Generic HTTP SQLi (Web Application) - Active Check
🗓️ 03 Nov 2005 00:00:00Reported by Copyright (C) 2002 John LampeType
openvas🔗 plugins.openvas.org👁 23 Views
| Source | Link |
|---|---|
| securitydocs | www.securitydocs.com/library/2651 |
| securiteam | www.securiteam.com/securityreviews/5DP0N1P76E.html |
| en | www.en.wikipedia.org/wiki/SQL_injection |
# SPDX-FileCopyrightText: 2002 John Lampe
# Some text descriptions might be excerpted from (a) referenced
# source(s), and are Copyright (C) by the respective right holder(s).
#
# SPDX-License-Identifier: GPL-2.0-only
if(description)
{
script_oid("1.3.6.1.4.1.25623.1.0.11139");
script_version("2023-07-21T05:05:22+0000");
script_tag(name:"last_modification", value:"2023-07-21 05:05:22 +0000 (Fri, 21 Jul 2023)");
script_tag(name:"creation_date", value:"2005-11-03 14:08:04 +0100 (Thu, 03 Nov 2005)");
script_tag(name:"cvss_base", value:"7.5");
script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:P/I:P/A:P");
script_name("Generic HTTP SQLi (Web Application) - Active Check");
script_category(ACT_MIXED_ATTACK);
script_copyright("Copyright (C) 2002 John Lampe");
script_family("Web application abuses");
script_dependencies("find_service.nasl", "no404.nasl", "webmirror.nasl", "DDI_Directory_Scanner.nasl", "global_settings.nasl");
script_require_ports("Services/www", 80);
script_exclude_keys("Settings/disable_cgi_scanning", "global_settings/disable_generic_webapp_scanning");
script_xref(name:"URL", value:"http://en.wikipedia.org/wiki/SQL_injection");
script_xref(name:"URL", value:"http://www.securiteam.com/securityreviews/5DP0N1P76E.html");
script_xref(name:"URL", value:"http://www.securitydocs.com/library/2651");
script_tag(name:"summary", value:"This script attempts to use SQL injection (SQLi) techniques on
CGI / web application scripts.");
script_tag(name:"vuldetect", value:"Sends various crafted HTTP requests and checks the
responses.");
script_tag(name:"insight", value:"NOTE: Please enable 'Enable generic web application scanning'
within the preferences of the VT 'Global variable settings' (OID: 1.3.6.1.4.1.25623.1.0.12288) if
you want to run this script.");
script_tag(name:"impact", value:"An attacker may exploit this flaw to bypass authentication or to
take the control of the remote database.");
script_tag(name:"solution", value:"Modify the relevant CGIs so that they properly escape
arguments.");
script_tag(name:"solution_type", value:"Workaround");
script_tag(name:"qod_type", value:"remote_analysis");
script_timeout(600);
exit(0);
}
include("http_func.inc");
include("http_keepalive.inc");
include("port_service_func.inc");
# TODO: Create a separate "reporting" VT which reports found items
# by this VT if it reached a timeout or exit(0) was used due to the failed requests.
# nb: We also don't want to run if optimize_test is set to "no"
if( http_is_cgi_scan_disabled() ||
get_kb_item( "global_settings/disable_generic_webapp_scanning" ) )
exit( 0 );
single_quote = raw_string(0x27);
poison[0] = single_quote + "UNION" + single_quote;
poison[1] = single_quote;
poison[2] = single_quote + "%22";
poison[3] = "9%2c+9%2c+9";
poison[4] = single_quote + "bad_bad_value";
poison[5] = "bad_bad_value" + single_quote;
poison[6] = single_quote + "+OR+" + single_quote;
poison[7] = single_quote + "WHERE";
poison[8] = "%3B"; # semicolon
poison[9] = single_quote + "OR";
# methods below from http://www.securiteam.com/securityreviews/5DP0N1P76E.html
poison[10] = single_quote + " or 1=1--";
poison[11] = " or 1=1--";
poison[12] = single_quote + " or " + single_quote + "a" + single_quote + "=" + single_quote + "a";
poison[13] = single_quote + ") or (" + single_quote + "a" + single_quote + "=" + single_quote + "a";
# blind sql injection methods that we will pass
# if they are putting the user-supplied variable within single quotes, then we trick them with this
blinder[0] = single_quote + "+AND+" + single_quote + "a" + single_quote + ">" + single_quote + "b";
# otherwise, this will work most of the time
blinder[1] = "+AND+1=1";
posreply[0] = "Can't find record in";
posreply[1] = "Column count doesn't match value count at row";
posreply[2] = "error " + single_quote;
posreply[3] = "Incorrect column name";
posreply[4] = "Incorrect column specifier for column";
posreply[5] = "Invalid parameter type";
posreply[6] = "Microsoft OLE DB Provider for ODBC Drivers error";
posreply[7] = "ODBC Microsoft Access Driver";
posreply[8] = "ODBC SQL Server Driver";
posreply[9] = "supplied argument is not a valid MySQL result";
posreply[10] = "mysql_query()";
posreply[11] = "Unknown table";
posreply[12] = "You have an error in your SQL syntax";
posreply[13] = "Error Occurred While Processing Request";
posreply[14] = "Syntax error converting the varchar value";
posreply[15] = "not a valid MySQL result resource";
posreply[16] = "unexpected end of SQL command";
posreply[17] = "mySQL error with query";
posreply[18] = "ORA-00936: missing expression";
posreply[19] = "ORA-00933: SQL command not properly ended";
posreply[20] = "Unclosed quotation mark before the character string";
posreply[21] = "Incorrect syntax near";
posreply[22] = "PostgreSQL query failed:";
posreply[23] = "not a valid PostgreSQL result";
posreply[24] = "An illegal character has been found in the statement";
posreply[25] = "[IBM][CLI Driver][DB2/6000]";
posreply[26] = "Unable to connect to PostgreSQL server:";
posreply[27] = "Can't connect to local";
posreply[28] = "ADODB.Recordset";
posreply[29] = "Microsoft SQL Native Client error";
posreply[30] = "Query failed: ERROR: syntax error at or near";
port = http_get_port( default:80 );
host = http_host_name( dont_add_port:TRUE );
unsafe_urls = "";
blind_urls = "";
mywarningcount = 0;
blindwarningcount = 0;
cgis = http_get_kb_cgis( port:port, host:host );
if( ! cgis ) exit( 0 );
foreach cgi( cgis ) {
# populate two arrays param[] and data[]
everythingrray = split( cgi, sep:" ", keep:FALSE );
if( everythingrray[0] =~ ".*/$") {
isdir = TRUE;
} else {
isdir = FALSE;
}
#counter for current failed requests
failedReqs = 0;
#counter for max failed requests
#The VT will exit if this is reached
#TBD: Make this configurable?
maxFailedReqs = 5;
if( ! isdir ) {
vrequest = string( everythingrray[0], "?" );
bogus_vrequest = string( everythingrray[0], "?", rand() );
pseudocount = 0;
foreach rrayval( everythingrray ) {
if( pseudocount >= 2 ) {
if( "]" >< rrayval ) {
pseudocount--;
tmpf = ereg_replace( pattern:"\[|\]", string:rrayval, replace:"" );
data[pseudocount] = tmpf;
vrequest = string( vrequest, "=", tmpf );
} else {
param[pseudocount] = rrayval;
if( pseudocount == 2 ) {
vrequest = string( vrequest, rrayval );
} else {
vrequest = string( vrequest, "&", rrayval );
}
}
} else {
param[pseudocount] = rrayval;
}
pseudocount++;
}
}
for( z = 2; param[z]; z++ ) {
blind = '';
url = vrequest;
req = http_get( item:url, port:port );
res = http_keepalive_send_recv( port:port, data:req, bodyonly:FALSE );
if( ( isnull( res ) ) || ( ! egrep( string:res, pattern:"^HTTP/1\.[01] (200|302)" ) ) ) {
failedReqs++;
if( failedReqs >= maxFailedReqs ) {
exit( 0 );
}
continue;
}
if( "Content-Length: 0" >< res ) continue; # there is no body to compare later. dell omsa fp workaround
res_saved = strstr( res, string( "\r\n\r\n" ) );
req = http_get( item:bogus_vrequest, port:port );
bres = http_keepalive_send_recv( port:port, data:req );
if( egrep( string:bres, pattern:"^HTTP/1\.[01] 200" ) ) {
continue;
}
for( i = 0; posreply[i]; i++ ) {
if( posreply[i] >< res ) {
exit( 0 );
}
}
for( poo = 0; poison[poo]; poo++ ) {
doblind = 0;
qa = '';
url = string( param[0], "?" );
blind = string( param[0], "?" );
for( i = 2; param[i]; i++ ) {
if( i == z ) {
if( blinder[poo] ) {
doblind++;
qa = string( blind, param[i], "=", data[i], "'" );
blind = string( blind, param[i], "=", data[i], blinder[poo] );
}
if (data[i]) {
url = string( url, param[i], "=", poison[poo] );
} else {
url = string( url, param[i], "=", poison[poo] );
}
} else {
if( blinder[poo] ) {
qa = string( qa, param[i], "=", data[i] );
blind = string( blind, param[i], "=", data[i] );
}
if( data[i] ) {
url = string( url, param[i], "=", data[i] );
} else {
url = string( url, param[i], "=" );
}
}
if( param[i + 1] ) {
url = string( url, "&" );
blind = string( blind, "&" );
qa = string( qa, "&" );
}
}
req = http_get( item:url, port:port );
inbuff = http_keepalive_send_recv( port:port, data:req );
if( isnull( inbuff ) ) {
failedReqs++;
if( failedReqs >= maxFailedReqs ) {
exit( 0 );
}
continue;
}
if( "Content-Length: 0" >< inbuff ) continue;
for( mu = 0; posreply[mu]; mu++ ) {
if( posreply[mu] >< inbuff ) {
unsafe_urls = string( unsafe_urls, http_report_vuln_url( port:port, url:url, url_only:TRUE ), ":", posreply[mu], "\n" );
mywarningcount++;
}
}
if( doblind > 0 ) {
req_blind = http_get( item:blind, port:port );
inbuff = http_keepalive_send_recv( port:port, data:req_blind );
if( isnull( inbuff ) ) {
failedReqs++;
if( failedReqs >= maxFailedReqs ) {
exit( 0 );
}
continue;
}
if( "Content-Length: 0" >< inbuff ) continue;
buff_body = strstr( inbuff, string( "\r\n\r\n" ) );
if( buff_body == res_saved ) {
req_qa = http_get( item:qa, port:port );
inbuff = http_keepalive_send_recv( port:port, data:req_qa );
qa_body = strstr( inbuff, string( "\r\n\r\n" ) );
if( "Content-Length: 0" >< inbuff ) continue;
if( qa_body != res_saved ) {
blind_urls = string( blind_urls, http_report_vuln_url( port:port, url:blind, url_only:TRUE ), "\n" );
blindwarningcount++;
}
}
}
if( safe_checks() == 0 ) {
# create a POST req
tmppost = split( url, sep:"?", keep:FALSE );
mypostdata = tmppost[1];
postreq = http_post( item:param[0], port:port, data:mypostdata );
# Test the POST req
inbuff = http_keepalive_send_recv( port:port, data:postreq );
if( isnull( inbuff ) ) {
failedReqs++;
if( failedReqs >= maxFailedReqs ) {
exit( 0 );
}
continue;
}
if( "Content-Length: 0" >< inbuff ) continue;
for( mu = 0; posreply[mu]; mu++ ) {
if( posreply[mu] >< inbuff ) {
unsafe_urls = string( unsafe_urls, http_report_vuln_url( port:port, url:url, url_only:TRUE ), ":", posreply[mu], "\n" );
mywarningcount++;
}
}
if( doblind > 0 ) {
# create a blind POST req
tmppost = split( blind, sep:"?", keep:FALSE );
mypostdata = tmppost[1];
postreq = http_post( item:param[0], port:port, data:mypostdata );
inbuff = http_keepalive_send_recv( port:port, data:postreq );
if( isnull( inbuff ) ) {
failedReqs++;
if( failedReqs >= maxFailedReqs ) {
exit( 0 );
}
continue;
}
if( "Content-Length: 0" >< inbuff ) continue;
buff_body = strstr( inbuff, string( "\r\n\r\n" ) );
if( buff_body == res_saved ) {
qapost = split( blind, sep:"?", keep:FALSE );
qapostdata = tmppost[1];
qareq = http_post( item:param[0], port:port, data:qapostdata );
qabuff = http_keepalive_send_recv( port:port, data:qareq );
qa_body = strstr( qabuff, string( "\r\n\r\n" ) );
if( qa_body != res_saved ) {
blind_urls = string( blind_urls, http_report_vuln_url( port:port, url:blind, url_only:TRUE ), "\n" );
blindwarningcount++;
}
}
}
}
# end the non-safe check
}
}
}
report = "";
if( mywarningcount > 0 ) {
VULN = TRUE;
report += string( "The following URLs seem to be vulnerable to various SQL injection techniques : <url>:<matching pattern>\n\n", unsafe_urls, "\n\n" );
}
if( blindwarningcount > 0 ) {
VULN = TRUE;
report += string( "The following URLs seem to be vulnerable to BLIND SQL injection techniques : \n\n", blind_urls, "\n\n" );
}
if( VULN ) {
security_message( port:port, data:report );
exit( 0 );
}
exit( 99 );
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation
21 Jul 2023 00:00Current
8.3High risk
Vulners AI Score8.3