Actually track this in SVN

git-svn-id: file:///home/svn/framework3/trunk@10135 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
HD Moore 2010-08-25 14:21:53 +00:00
parent 7ea537c7ea
commit db1adc0e76
10 changed files with 376 additions and 0 deletions

View File

@ -0,0 +1,7 @@
@set BASE=%~dp0
@cd %BASE%
@echo [*] Starting the audit...
@cscript /nologo audit.js
pause

View File

@ -0,0 +1,5 @@
@set BASE=%~dp0
@cd %BASE%
@cscript /nologo analyze.js
pause

Binary file not shown.

View File

@ -0,0 +1,14 @@
Execute 01_StartAudit.bat as an administrative user. This will attempt to launch the
handler for all known file types. When this process is complete, access the open
ProcMon window and use the Save option from the File menu. Save the output to this
directory as a file named Logfile.CSV and make sure you choose the CSV file type.
Once Logfile.CSV has been created, execute 02_Analyze.bat as an administrative user.
This will attempt to validate each result and generate a list of proof-of-concepts
within the Exploit subdirectory. For the best results, manually review the ProcMon
logs to ensure that various corner cases and other related vulnerabilities are not
missed.
Have fun!
-HD <hdm[at]metasploit.com>

View File

@ -0,0 +1,194 @@
/* DLLHijackAuditKit (C) 2010 Rapid7 LLC */
var oFso = new ActiveXObject("Scripting.FileSystemObject");
var oShl = new ActiveXObject("WScript.Shell");
var oCWD = oShl.CurrentDirectory + "";
function print_status(msg) {
try {
WScript.StdOut.WriteLine("[*] "+ msg);
} catch(e) {}
}
function process_list() {
var res = new Array();
var wbemFlagReturnImmediately = 0x10;
var wbemFlagForwardOnly = 0x20;
var oWMI = GetObject("winmgmts:\\\\localhost\\root\\CIMV2");
var cPID = oWMI.ExecQuery("SELECT * FROM Win32_Process", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
var enumItems = new Enumerator(cPID);
for (; !enumItems.atEnd(); enumItems.moveNext()) {
var p = enumItems.item();
if (p.ExecutablePath && p.ExecutablePath.toLowerCase().indexOf("taskmgr") != -1) continue;
res.push(p.ProcessId);
}
return res;
}
function replace_payloads(dir, src) {
var base = oFso.GetFolder(dir);
var files = new Enumerator(base.files);
for (; !files.atEnd(); files.moveNext()) {
var entry = files.item().Name.toString().toLowerCase();
if ( entry.indexOf("exploit.") == -1) {
if (entry.toString().indexOf(".exe") != -1) {
try { oFso.CopyFile(src + "\\runcalc.exe", dir + "\\" + entry); } catch(e) { }
} else {
try { oFso.CopyFile(src + "\\runcalc.dll", dir + "\\" + entry); } catch(e) { }
}
}
}
var subs = new Enumerator(base.SubFolders);
for (; !subs.atEnd(); subs.moveNext()) {
var entry = (subs.item() + "").toLowerCase();
replace_payloads(entry, src);
}
}
/* Process Logfile.CSV
a) Make a list of applications and their associated DLLs
b) Create a test case for each extension and each DLL
c) Run each test case and look for "exploited.txt"
d) Copy confirmed test cases to a new directory
*/
var procs = process_list();
print_status("Protecting " + procs.length + " processes");
var apps = new Array();
var fCSV = oFso.OpenTextFile("Logfile.CSV");
var line = fCSV.ReadLine();
var iPath = 4;
var iProc = 1;
var bits = line.split(",");
// Determine which fields are what index
for (var i=0; i < bits.length; i++) {
if (bits[i].toLowerCase().indexOf("process name") != -1) {
iProc = i;
}
if (bits[i].toLowerCase().indexOf("path") != -1) {
iPath = i;
}
}
// Parse the CSV into a map of each application's loads
while( ! fCSV.AtEndOfStream ) {
line = fCSV.ReadLine();
bits = line.replace(/"/g, '').split(",")
var vApp = bits[iProc].toLowerCase();
var vPath = bits[iPath].toLowerCase();
var vExt = vPath.replace(/.*DLLAudit\\ext\\/ig, '').split("\\")[0].toLowerCase();
var vTgt = vPath.replace(/.*DLLAudit\\ext\\/ig, '').split("\\");
vTgt.shift();
var vDll = vTgt.join("\\").toLowerCase();
if (! apps[vApp]) apps[vApp] = new Array();
if (! apps[vApp][vExt]) apps[vApp][vExt] = new Array();
apps[vApp][vExt][vDll] = true;
}
print_status("Generating and validating test cases...");
try { oFso.CreateFolder(oCWD + "\\TestCases"); } catch(e) { }
try { oFso.CreateFolder(oCWD + "\\Exploits"); } catch(e) { }
for (var tApp in apps) {
print_status(" Application: " + tApp);
var aBase = oCWD + "\\TestCases\\" + tApp;
try { oFso.CreateFolder(aBase); } catch(e) { }
for (var tExt in apps[tApp]) {
var eBase = aBase + "\\" + tExt;
var aExploited = new Array();
try { oFso.CreateFolder(eBase); } catch(e) { }
for (var tDll in apps[tApp][tExt]) {
var tBits = tDll.split("\\");
var tName = tBits.pop();
var dBase = eBase + "\\" + tName;
try { oFso.CreateFolder(dBase); } catch(e) { }
if (aExploited[tName]) continue;
// tDll may be a subdirectory + DLL
tPath = dBase;
for (var y = 0; y < tBits.length; y++) {
tPath = tPath + "\\" + tBits[y];
try { oFso.CreateFolder(tPath); } catch(e) { }
}
tPath = tPath + "\\" + tName;
try {
if (tName.toLowerCase().indexOf(".exe") != -1) {
oFso.CopyFile(oCWD + "\\runtest.exe", tPath);
} else {
oFso.CopyFile(oCWD + "\\runtest.dll", tPath);
}
} catch(e) { }
// Create the actual test case file
try {
var a = oFso.CreateTextFile(dBase + "\\exploit." + tExt);
a.WriteLine("HOWDY!");
a.Close();
} catch(e) { }
try {
// Run the test case
oShl.CurrentDirectory = dBase;
oShl.Run("cmd.exe /c start exploit." + tExt, 0);
} catch(e) { }
WScript.Sleep(500);
var nprocs = process_list();
var cnt = 0;
while(nprocs.length == procs.length && cnt < 2) {
cnt++;
WScript.Sleep(500);
nprocs = process_list();
}
WScript.Sleep(500);
var killer = "taskkill /F ";
for (var i=0; i < nprocs.length; i++) {
var found = false;
for (var x=0; x < procs.length; x++) {
if (nprocs[i] == procs[x]) {
found = true;
break;
}
}
if (found) continue;
killer = killer + "/PID " + nprocs[i] + " ";
}
oShl.Run(killer, 0, true);
// Check for the file existence
if (oFso.FileExists(dBase + "\\exploited.txt")) {
print_status("Successfully exploited " + tApp + " with ." + tExt + " using " + tName);
aExploited[tName] = true;
var xBase = oCWD + "\\Exploits\\" + tApp + "_" + tExt + "_" + tName;
try { oFso.CreateFolder(xBase); } catch(e) { }
try { oFso.CopyFolder(dBase + "\\*.*", xBase + "\\", true); } catch(e) { }
try { oFso.CopyFile(dBase + "\\*.*", xBase + "\\", true); } catch(e) { }
try { oFso.DeleteFile(xBase + "\\exploited.txt"); } catch(e) { }
replace_payloads(xBase, oCWD);
}
}
}
}

View File

@ -0,0 +1,156 @@
/* DLLHijackAuditKit (C) 2010 Rapid7 LLC */
function print_status(msg) {
try {
WScript.StdOut.WriteLine("[*] "+ msg);
} catch(e) {}
}
function process_list() {
var res = new Array();
var wbemFlagReturnImmediately = 0x10;
var wbemFlagForwardOnly = 0x20;
var oWMI = GetObject("winmgmts:\\\\localhost\\root\\CIMV2");
var cPID = oWMI.ExecQuery("SELECT * FROM Win32_Process", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
var enumItems = new Enumerator(cPID);
for (; !enumItems.atEnd(); enumItems.moveNext()) {
var p = enumItems.item();
if (p.ExecutablePath && p.ExecutablePath.toLowerCase().indexOf("taskmgr") != -1) continue;
res.push(p.ProcessId);
}
return res;
}
var pause_interval = 100000;
var oFso = new ActiveXObject("Scripting.FileSystemObject");
var oShl = new ActiveXObject("WScript.Shell");
var oLoc = new ActiveXObject("WbemScripting.SWbemLocator");
var oSvc = oLoc.ConnectServer(null, "root\\default");
var oReg = oSvc.Get("StdRegProv");
var oCWD = oShl.CurrentDirectory + "";
var oMethod = oReg.Methods_.Item("EnumKey");
var oInParam = oMethod.InParameters.SpawnInstance_();
oInParam.hDefKey = 0x80000002;
oInParam.sSubKeyName = "Software\\Classes";
var oOutParam = oReg.ExecMethod_(oMethod.Name, oInParam);
var aNames = oOutParam.sNames.toArray();
try { oFso.CreateFolder("DLLAudit"); } catch(e) { }
try { oFso.CreateFolder("DLLAudit\\ext"); } catch(e) { }
if (! oFso.FileExists("procmon.exe")) {
print_status("Downloading procmon.exe from \\\\live.sysinternals.com ...")
try { oFso.CopyFile("\\\\live.sysinternals.com\\Tools\\procmon.exe", "procmon.exe"); } catch(e) {}
}
if (! oFso.FileExists("procmon.exe")) {
print_status("Failed to download procmon.exe, copy here manually.");
WScript.Quit();
}
print_status("Starting the process monitor...");
oShl.Run("procmon.exe /AcceptEULA /Quiet /LoadConfig DLLAudit.pmc", 10);
WScript.Sleep(5000);
var total = 0;
print_status("Creating test cases for each file extension...");
for (var i = 0; i < aNames.length; i++) {
if (aNames[i].substr(0,1) != ".") continue;
var ext = aNames[i].substr(1,32).toLowerCase();
if (ext == "com") continue;
if (ext == "pif") continue;
if (ext == "exe") continue;
if (ext == "bat") continue;
if (ext == "scr") continue;
if (ext == "dos") continue;
if (ext == "386") continue;
if (ext == "cpl") continue;
if (ext == "sys") continue;
if (ext == "dll") continue;
if (ext == "drv") continue;
if (ext == "rb") continue;
if (ext == "py") continue;
if (ext == "pl") continue;
if (ext == "crds") continue;
if (ext == "crd") continue;
if (ext == "pml") continue;
if (ext == "pmc") continue;
try { oFso.CreateFolder("DLLAudit\\ext\\" + ext); } catch(e) { }
try {
var a = oFso.CreateTextFile("DLLAudit\\ext\\" + ext + "\\exploit." + ext);
a.WriteLine("HOWDY!");
a.Close();
} catch(e) { }
total++;
}
print_status("Created " + total + " test cases");
var procs = process_list();
print_status("Protecting " + procs.length + " processes");
var tries = 0;
var base = oFso.GetFolder("DLLAudit\\ext");
var subs = new Enumerator(base.SubFolders);
for (; !subs.atEnd(); subs.moveNext()) {
var path = subs.item() + "";
var bits = path.split("\\");
var ext = bits[bits.length - 1];
print_status("Auditing extension: " + ext);
oShl.CurrentDirectory = path + "\\";
oShl.Run("cmd.exe /c start exploit." + ext, 0);
WScript.Sleep(500);
var nprocs = process_list();
var cnt = 0;
while(nprocs.length == procs.length && cnt < 1) {
cnt++;
WScript.Sleep(500);
nprocs = process_list();
}
// If an application spawned, give it another second
// This helps with ProcMon memory usage as well
if (nprocs.length > procs.length) {
WScript.Sleep(1000);
}
var killer = "taskkill /F ";
for (var i=0; i < nprocs.length; i++) {
var found = false;
for (var x=0; x < procs.length; x++) {
if (nprocs[i] == procs[x]) {
found = true;
break;
}
}
if (found) continue;
killer = killer + "/PID " + nprocs[i] + " ";
}
oShl.Run(killer, 0, true);
tries++;
if (tries % pause_interval == 0) {
print_status("Completed " + tries + " extensions, hit enter to continue.")
WScript.Stdin.ReadLine();
print_status("Continuing...")
}
}
print_status("Data collection phase complete, export Logfile.CSV from ProcMon.")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.