private void procListUpdater_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
//Make sure we're in Debug Mode so we have access to all processes.
Process.EnterDebugMode();
//Change our process priority to Below Normal so we don't eat all the CPU time.
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
BackgroundWorker worker = sender as BackgroundWorker;
List<Process> procs = new List<Process>();
Process[] all = Process.GetProcesses();
for (int i = 0; i < all.Length; i++)
{
double pct = (double) i / (double) all.Length;
pct = pct * 100;
Process p = all[i];
//Report our progress as a percentage of the process list completed.
worker.ReportProgress((int)pct,"");
//It's important to refresh processes before each check. A full scan is time consuming, and process state can often change in between.
p.Refresh();
try
{
//Check to make sure our process is still there
if (!p.HasExited)
{
//Filter out ourselves as well as the Windows Defender module. Windows Defender will almost always have the signature we're looking for provided AntiPwny is running
if (!p.MainModule.FileName.ToLower().Contains("msmpeng"))
{
//Use a different scan for Java. We still need to look for meterpreter in java as well, because it can be migrated. This will look specifically for Java Meterpreter
if (p.ProcessName == "java")
{
if (Utilities.scanJava(p))
{
procs.Add(p);
}
}
//Scan our process for Meterpreter
if (Utilities.scanProcess(p))
{
procs.Add(p);
}
}
}
}
catch (Exception f) { Console.WriteLine("Error opening " + p.ProcessName); Console.WriteLine(f.Message); }
}
//Build our TCP table so we have all connections
MIB_TCPROW_OWNER_PID[] table;
int inet = 2;
int buffSize = 0;
uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, inet, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
IntPtr buffTable = Marshal.AllocHGlobal(buffSize);
try
{
ret = GetExtendedTcpTable(buffTable, ref buffSize, true, inet, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
if (ret != 0)
{
return;
}
// get the number of entries in the table
MIB_TCPTABLE_OWNER_PID tab = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(buffTable, typeof(MIB_TCPTABLE_OWNER_PID));
IntPtr rowPtr = (IntPtr)((long)buffTable + Marshal.SizeOf(tab.dwNumEntries));
table = new MIB_TCPROW_OWNER_PID[tab.dwNumEntries];
for (int i = 0; i < tab.dwNumEntries; i++)
{
MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID));
table[i] = tcpRow;
rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(tcpRow)); // next entry
}
}
finally
{
// Free the Memory
Marshal.FreeHGlobal(buffTable);
}
worker.ReportProgress(100, "Scanning Connections");
//Map connections to PIDs for easier lookup
Dictionary<int, List<ProcessListObject>> map = new Dictionary<int, List<ProcessListObject>>();
foreach (MIB_TCPROW_OWNER_PID row in table){
List<ProcessListObject> list;
map.TryGetValue(row.owningPid, out list);
if (list != null)
{
ProcessListObject temp = new ProcessListObject();
temp.ProcessName = new IPAddress(BitConverter.GetBytes(row.localAddr)).ToString() +" (" + BitConverter.ToUInt16(
new byte[2] { row.localPort2, row.localPort1 }, 0) + ")";
temp.ProcessID = "->";
temp.ProcessPath = new IPAddress(BitConverter.GetBytes(row.remoteAddr)).ToString() + " (" + BitConverter.ToUInt16(
new byte[2] { row.localPort2, row.localPort1 }, 0) + ")";
list.Add(temp);
temp.InternalID = row.owningPid;
map.Remove(row.owningPid);
map.Add(row.owningPid, list);
}
else
{
list = new List<ProcessListObject>();
ProcessListObject temp = new ProcessListObject();
temp.ProcessName = new IPAddress(BitConverter.GetBytes(row.localAddr)).ToString() + " (" + BitConverter.ToUInt16(
new byte[2] { row.localPort2, row.localPort1 }, 0) + ")";
temp.ProcessID = "->";
temp.ProcessPath = new IPAddress(BitConverter.GetBytes(row.remoteAddr)).ToString() + " (" + BitConverter.ToUInt16(
new byte[2] { row.localPort2, row.localPort1 }, 0) + ")";
list.Add(temp);
temp.InternalID = row.owningPid;
map.Add(row.owningPid, list);
}
}
List<ProcessListObject> objects = new List<ProcessListObject>();
List<ProcessListObject> reference;
//Loop back through the processes we detected with Meterpreter and correlate connections going outbound for display
foreach (Process p in procs)
{
p.Refresh();
if (!p.HasExited)
{
if (PreventionMode)
{
builder.Clear();
builder.Append(p.ProcessName);
builder.Append(" Killed");
w.write(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(), builder.ToString(), "Meterpreter");
p.Kill();
}
else
{
ProcessListObject temp = new ProcessListObject();
temp.ProcessID = p.Id.ToString();
temp.ProcessName = p.ProcessName;
temp.ProcessPath = p.MainModule.FileName;
temp.InternalID = p.Id;
temp.Detected = "Meterpreter";
map.TryGetValue(p.Id, out reference);
if (reference != null)
{
foreach (ProcessListObject t in reference)
{
t.Parent = temp;
}
temp.Connections = reference;
}
else
{
temp.Connections = null;
}
objects.Add(temp);
}
}
}
worker.ReportProgress(100, "Scanning cmd.exe");
//Looking for reverse shells. They usually manifest as cmd.exe with a parent process running that has the actual reverse connection
foreach (Process p in Process.GetProcessesByName("cmd"))
{
Process par = Utilities.ParentProcessUtilities.GetParentProcess(p.Id);
if (par != null)
map.TryGetValue(par.Id, out reference);
else
map.TryGetValue(p.Id, out reference);
if (reference != null)
{
if (PreventionMode)
{
p.Kill();
w.write(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString(), "Killed cmd.exe", "Reverse Shell");
}
else
{
ProcessListObject temp = new ProcessListObject();
temp.ProcessID = p.Id.ToString();
temp.ProcessName = p.ProcessName;
temp.ProcessPath = p.MainModule.FileName;
temp.InternalID = p.Id;
temp.Detected = "Reverse Shell";
foreach (ProcessListObject t in reference)
{
t.Parent = temp;
}
temp.Connections = reference;
objects.Add(temp);
}
}
}
worker.ReportProgress(100, "Scanning wscript");
//Look through wscript and cscript, which are almost always used for meterpreter. If we find the command line arguments
//contain both temp and .vbs, we can be fairly certain this is a persistence script being called.
foreach (Process p in Process.GetProcessesByName("wscript"))
{
string s = Utilities.GetCmdArguments(p);
if (s.ToLower().Contains("temp") && s.ToLower().Contains(".vbs"))
{
ProcessListObject temp = new ProcessListObject();
temp.ProcessID = p.Id.ToString();
temp.ProcessName = p.ProcessName;
temp.ProcessPath = p.MainModule.FileName;
temp.InternalID = p.Id;
temp.Detected = "Persistence WScript";
temp.Connections = null;
objects.Add(temp);
}
}
foreach (Process p in Process.GetProcessesByName("cscript"))
{
string s = Utilities.GetCmdArguments(p);
if (s.ToLower().Contains("temp") && s.ToLower().Contains(".vbs"))
{
ProcessListObject temp = new ProcessListObject();
temp.ProcessID = p.Id.ToString();
temp.ProcessName = p.ProcessName;
temp.ProcessPath = p.MainModule.FileName;
temp.InternalID = p.Id;
temp.Detected = "Persistence CScript";
temp.Connections = null;
objects.Add(temp);
}
}
Process.LeaveDebugMode();
//Exit Debug Mode
worker.ReportProgress(100, "Waiting :60 Till Next Scan");
//Report our finished status
e.Result = objects;
}