HackerScan.js
Description
This script parses all the IIS-related log files (IIS log files, HTTPError log files, UrlScan log files) looking for "suspicious'" URL's that might have been sent to compromise the server. The "HackerScan.txt" file contains a sample of the patterns to search for in URL's. You can add your own patterns to the text file if you want to look for more specific patterns.
Requirements
You must install and use the Log Parser.
Supported Platforms
Windows Server 2003 |
Yes |
Windows XP |
No |
Windows 2000 |
No |
Script Code
//Create the main Log Parser Query object
var g_LogParser=new ActiveXObject("MSUtil.LogQuery");
//Initialize the global counter of hacker attempts
var g_nAttempts=0;
//Check the HTTP Error log files first
DoHTTPERRScan();
//Check the URLScan log files now
DoUrlscanScan();
//Load the HackerScan.txt file
WScript.Echo("Loading the HackerScan file...");
var objFS=new ActiveXObject
("Scripting.FileSystemObject");
try
{
var objFile=objFS.OpenTextFile("HackerScan.txt",1);
var g_szUrlHackConditions=objFile.ReadAll();
objFile.Close();
WScript.Echo("...succesfully loaded.");
//Check if Centralized Binary Logging is enabled
var bCentralizedBinaryLogging=false;
var objW3SVC=GetObject("IIS://localhost/W3SVC");
try
{
bCentralizedBinaryLogging=objW3SVC.
CentralBinaryLoggingEnabled;
}
catch(e)
{
//Most probably this is not IIS6.0
}
if(!bCentralizedBinaryLogging)
{
//Navigate through all the IIS sites, and query their log files
try
{
for( var objIISSites=new Enumerator(objW3SVC);
!objIISSites.atEnd();
objIISSites.moveNext())
{
var objIIS=objIISSites.item();
if (objIIS.Class == "IIsWebServer")
{
//Scan this site
DoSiteScan(objIIS.Name);
}
}
}
catch(e)
{
WScript.Echo("Cannot enumerate
the IIS sites
on this machine: " + e.description);
}
}
else
{
//Scan the IIS Centralized Binary log files
DoCentralizedBinaryScan();
}
}
catch(e)
{
WScript.Echo("Unexpected error: " +
e.description);
WScript.Quit(-1);
}
//Print final report
WScript.Echo(g_nAttempts + "
suspicious attempts found.");
//Exit
WScript.Quit(0);
//---------------------------------------------------------------
function DoHTTPERRScan()
{
//Create the query text
var szQuery="SELECT src-ip AS ClientIP,
cs-url AS UriStem,
NULL AS UriQuery, sc-status AS StatusCode,
COUNT(*) AS
Total FROM HTTPERR WHERE s-reason='Url'
GROUP BY ClientIP,
UriStem, UriQuery, StatusCode";
try
{
WScript.Echo("Scanning HTTPError log files...");
var recordSet=g_LogParser.Execute(szQuery);
var nAttempts=0;
for(;!recordSet.atEnd();recordSet.moveNext())
{
var record=recordSet.getRecord();
Output(record);
nAttempts+=record.getValue(4);
}
WScript.Echo("...HTTPError log files scanned. "
+ nAttempts +
" suspicious requests found.");
recordSet.close();
}
catch(e)
{
if(e.number!=-2147024894) //File not found
WScript.Echo("Unexpected error while scanning the
HTTPError log files: " + e.description +
" (" + e.number + ")");
else
WScript.Echo("There are no HTTPError
log files to scan
on this machine.");
}
}
function DoUrlscanScan()
{
//Create the query text
var szQuery="SELECT ClientIP, Url AS UriStem, NULL
AS UriQuery, NULL AS StatusCode, COUNT(*) AS Total
FROM URLSCAN WHERE Comment LIKE 'URL%' GROUP BY
ClientIP, UriStem, UriQuery, StatusCode";
try
{
WScript.Echo("Scanning URLScan log files...");
var recordSet=g_LogParser.Execute(szQuery);
var nAttempts=0;
for(;!recordSet.atEnd();recordSet.moveNext())
{
var record=recordSet.getRecord();
Output(record);
nAttempts+=record.getValue(4);
}
WScript.Echo("...URLScan log files scanned. "
+ nAttempts + " suspicious requests found.");
recordSet.close();
}
catch(e)
{
if(e.number!=-2147024894) //File not found
WScript.Echo("Unexpected error while scanning the
URLScan log files: " + e.description + " (" + e.number + ")");
else
WScript.Echo("There are no URLScan log files to scan
on this machine.");
}
}
function DoCentralizedBinaryScan()
{
//Create the query text
var szQuery="SELECT ClientIpAddress AS ClientIP,
UriStem, UriQuery, ProtocolStatus, COUNT(*) AS
Total FROM %windir%\\system32\\logfiles\\W3SVC\\ra*.ibl WHERE "
+ g_szUrlHackConditions + " GROUP BY ClientIP, UriStem, UriQuery,
ProtocolStatus";
try
{
WScript.Echo("Scanning Centralized Binary log files...");
var recordSet=g_LogParser.Execute(szQuery);
var nAttempts=0;
for(;!recordSet.atEnd();recordSet.moveNext())
{
var record=recordSet.getRecord();
Output(record);
nAttempts+=record.getValue(4);
}
WScript.Echo("...Centralized Binary log files scanned. "
+ nAttempts + " suspicious requests found.");
recordSet.close();
}
catch(e)
{
if(e.number!=-2147024894) //File not found
WScript.Echo("Unexpected error while scanning the
Centralized Binary log files: " +
e.description + " (" + e.number + ")");
else
WScript.Echo("There are no Centralized Binary log files
to scan on this machine.");
}
}
function DoSiteScan(szSiteID)
{
//Get the site object
var objSite=GetObject("IIS://localhost/W3SVC/" + szSiteID);
//Get the current log format of this site
var szLogPluginCLSId=objSite.LogPluginCLSId;
//Create the SELECT clause text
var szSelectClause="SELECT ";
switch(szLogPluginCLSId.toUpperCase())
{
case "{FF160663-DE82-11CF-BC0A-00AA006111E0}": {
//W3C Format
szSelectClause+="c-ip AS ClientIP, cs-uri-stem
AS UriStem, cs-uri-query AS UriQuery,
sc-status AS StatusCode";
break;
}
case "{FF16065F-DE82-11CF-BC0A-00AA006111E0}": {
//NCSA Format
WScript.Echo("NCSA log format is not
supported - aborting scan for site " + szSiteID);
return;
}
case "{FF160657-DE82-11CF-BC0A-00AA006111E0}": {
//IIS Format
szSelectClause+="UserIP AS ClientIP, Target
AS UriStem, Parameters AS UriQuery, StatusCode";
break;
}
case "{FF16065B-DE82-11CF-BC0A-00AA006111E0}": {
//ODBC Format
szSelectClause+="ClientHost AS ClientIP,
Target AS UriStem, Parameters AS UriQuery,
ServiceStatus AS StatusCode";
break;
}
default: {
WScript.Echo("Unknown log format " + szLogPluginCLSId);
return;
}
}
//Create the whole query text
var szQuery=szSelectClause + ", COUNT(*) AS Total
FROM <" + szSiteID + "> WHERE " +
g_szUrlHackConditions + " GROUP BY ClientIP,
UriStem, UriQuery, StatusCode";
try
{
WScript.Echo("Scanning IIS Site " + szSiteID + " log files ...");
var recordSet=g_LogParser.Execute(szQuery);
var nAttempts=0;
for(;!recordSet.atEnd();recordSet.moveNext())
{
var record=recordSet.getRecord();
Output(record);
nAttempts+=record.getValue(4);
}
WScript.Echo("...IIS Site " + szSiteID + " log files scanned. "
+ nAttempts + " suspicious requests found.");
recordSet.close();
}
catch(e)
{
if(e.number!=-2147024894) //File not found
WScript.Echo("Unexpected error while scanning the IIS Site "
+ szSiteID + " log files: " + e.description + " (" + e.number + ")");
else
WScript.Echo("There are no IIS Site " + szSiteID + " log files
to scan on this machine.");
}
}
function Output(record)
{
WScript.Echo(" !!! Client " + record.getValue(0) + ":");
WScript.Echo(" " + record.getValue(1) +
(record.isNull(2)?"":("?" + record.getValue(2))));
var nAttempts=record.getValue(4);
WScript.Echo(" Requested " + record.getValue(4) + " time"
+ (nAttempts>1?"s":"") + (record.isNull(3)?(""):(", rejected
with " + record.getValue(3))));
g_nAttempts+=nAttempts;
}
For any feedback regarding the content of this sample script, please write to Microsoft TechNet.
Text File "HackerScan.txt"
UriStem LIKE '%cmd.exe%' OR
UriStem LIKE '%\%%' OR
UriStem LIKE '%...%' OR
UriStem LIKE '%:%' OR
UriStem LIKE '%$%' OR
UriStem LIKE '%&%' OR
UriStem LIKE '%\%00%' OR
UriQuery LIKE '%\%3c%' OR
UriQuery LIKE '%\%3e%' OR
UriQuery LIKE '%\"%' OR
UriQuery LIKE '%\'%' OR
UriQuery LIKE '%#%' OR
UriQuery LIKE '%\%00%'
Disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.