Monday, October 11, 2010

Accessing (or not) GetOwnerModuleFromTcpEntry from Powershell

Normally on XP SP2, Vista, Win7 'netstat -ano' or 'netstat -anob' gives us the connected sockets, the PID of listening applications. With the '-b' option, netstat makes an attempt at finding the owner of the socket probably through the 'GetOwnerModuleFromTcpEntry function [which] retrieves data about the module that issued the context bind for a specific IPv4 TCP endpoint in a MIB table row.'  found in iphlpapi.dll (IP Helper). Finding this same information with Powershell I have found to be more than difficult. It is easy enough to find the listening and connected sockets with [System.NET.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties(). 



List-Connections.ps1 will produce a listing comparable to netstat. However, I can't find the MIB table entry from the process to the socket (or the converse) in either 'ps' or 'gwmi win32_process'. My workaround is to use netstat from cmd.exe where gwmi_netstat_ano.cmd is:


for /f "tokens=1-6" %%a in ('netstat -ano ^| findstr TCP') do @echo %%e > ano.list.txt
for /f "tokens=1-6" %%a in ('netstat -ano ^| findstr UDP') do @echo %%d >> ano.list.txt


or where gwmi_tcpvcon_ano.cmd is:


@del /q ano.list.txt
@path C:\tools\SysinternalsSuite\;%path%
for /f "delims=, tokens=1-5" %%a in ('tcpvcon -acn ^| findstr TCP') do @echo %%c >> ano.list.txt
for /f "delims=, tokens=1-5" %%a in ('tcpvcon -acn ^| findstr UDP') do @echo %%c >> ano.list.txt



This powershell script runs the commands in 'gwmi_netstat_ano.cmd' and processes the 'netstat -ano' output with 'gwmi win32_process':


Microsoft.PowerShell.Management\Start-Process $pwd\gwmi_netstat_ano.cmd -argument /Q  -nonewwindow
$ano_list = gc ano.list.txt | sort | get-unique
$ano_proc = foreach ($ano in $ano_list) {gwmi win32_process | Select Name,ProcessId,HandleCount,ThreadCount,WriteOperationCount,ReadOperationCount,CommandLine | ? {$_.ProcessID -eq "$ano"}}
write $ano_proc | sort -property ProcessID | ft -auto
# or alternatively
foreach ($id in $ano_list) {get-wmiObject win32_process -filter "ProcessID=$id" | Select Name,ProcessID,Commandline}


PS C:\ps1: .\gwmi_netstat_ano.ps1


C:\ps1: for /F "tokens=1-6" %a in ('netstat -ano | findstr TCP') do @echo %e > ano.list.txt
C:\ps1: for /F "tokens=1-6" %a in ('netstat -ano | findstr UDP') do @echo %d >> ano.list.txt


Name        ProcessId HandleCount ThreadCount WriteOperationCount ReadOperationCount CommandLine
----        --------- ----------- ----------- ------------------- ------------------ -----------
System              4        5381         151               62649               2192
svchost.exe      1164         368          11                1902               2335 C:\Windows\system32\svchost.exe -k LocalService
svchost.exe      1304         700          27                 398               2119 C:\Windows\system32\svchost.exe -k NetworkService
svchost.exe      3168        1234          49               12312              42668 C:\Windows\system32\svchost.exe -k netsvcs
opera.exe        3684         849          39              112787              65814 "C:\Program Files (x86)\Opera\opera.exe"
ftp.exe          3796         128           1                   4                  5 ftp  rmfdevelopment.com


Name        ProcessID Commandline
----        --------- -----------
svchost.exe      1164 C:\Windows\system32\svchost.exe -k LocalService
svchost.exe      1304 C:\Windows\system32\svchost.exe -k NetworkService
svchost.exe      3168 C:\Windows\system32\svchost.exe -k netsvcs
opera.exe        3684 "C:\Program Files (x86)\Opera\opera.exe"
ftp.exe          3796 ftp  rmfdevelopment.com
System              4


( A script like Get-Svchost.ps1 can help open up the incantations of svchost.exe.) I find the cmd.exe workaround I use here unfortunate as a security professional, because it means I am unable to use Powershell to get the MIB table entry from GetOwnerModuleFromTcpEntry, information which is critical to understanding malware. Sure, I can parse this information from netstat, but this blows up any chance of scripting detection  anywhere near real-time. Perhaps someone has an answer...

No comments:

Post a Comment