check for runnning programs that are not signed

Started by pamsniffer, February 28, 2015, 01:05:33 PM

Previous topic - Next topic

pamsniffer

Hi,

I want to make a winbatch script that is checking for running programs that are not signed.
maybe someone can help me.

pam

td

Interesting problem.  I am not aware of any simple way to check all running programs for a digital signature.  You can use the WinVerifyTrust API function exported from Wintrust.dll via a DllCall to check the signature of the image file associated with each running process.  Of course, this entails getting the image file for each running process via the process extender or the dotNet "System.Diagnostics.Process" class.

MSFT's signtool command line tool can be used to verify the signature of an executable image.  The following article describes how to do this with the tool

https://msdn.microsoft.com/en-us/library/windows/desktop/aa388171%28v=vs.85%29.aspx

You would need to download the tool if you don't have it already and you would still need to get a list of all the running executable images.

There may be a pure FCL (dotNet) way to do this but that would require a little more research to establish its existence.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Here's a mashup that more or less gets the image file names of running unsigned executables.  It needs a considerable amount of work including error handling and needs to be run as an elevated admin.

Code (winbatch) Select

; Handy constants
INVALID_HANDLE_VALUE=-1
WTD_UI_NONE=2
WTD_REVOKE_NONE=0
WTD_CHOICE_FILE=1
WTD_SAFER_FLAG=256
WTD_STATEACTION_VERIFY=1
WTD_STATEACTION_CLOSE=2

; Structures.
;WINTRUST_FILE_INFO structure
strWinTrustFileInfo = "DWORD:cbStruct;LPWSTR:pcwszFilePath;HANDLE:hFile;DWORD_PTR:pGUID"
hFileData  = DllStructAlloc(strWinTrustFileInfo)
DllStructPoke(hFileData, "cbStruct", IntControl(98, hFileData, 1,0,0)) ; Set the struct size.

; WINTRUST_DATA structure
strWinTrustData =  "DWORD:cbStruct;DWORD_PTR:pPolicyCallbackData;DWORD_PTR:pSIPClientData;DWORD:dwUIChoice;"
strWinTrustData := "DWORD:fdwRevocationChecks;DWORD:dwUnionChoice;DWORD_PTR:pFile;DWORD:dwStateAction;"
strWinTrustData := "HANDLE:hWVTStateData;LPWSTR:pwszURLReference;DWORD:dwProvFlags;DWORD:dwUIContext"
hTrustData = DllStructAlloc(strWinTrustData)
DllStructPoke(hTrustData, "cbStruct", IntControl(98, hTrustData, 1,0,0)) ; Set the struct size.
DllStructPoke(hTrustData, "dwUIChoice",WTD_UI_NONE)
DllStructPoke(hTrustData, "fdwRevocationChecks", WTD_REVOKE_NONE)
DllStructPoke(hTrustData, "dwUnionChoice", WTD_CHOICE_FILE)
DllStructPoke(hTrustData, "pFile", IntControl(98, hFileData, 2,0,0)) ; Set the file data pointer.
DllStructPoke(hTrustData, "dwProvFlags", WTD_SAFER_FLAG)

; Use the Authenticode policy provider for verification by filling a GUID structure
; with the guid that represents it.
strGuild = "unsigned long:Data1;unsigned short:Data2;unsigned short:Data3;unsigned char:Data4[8]"
strActionVerify = "{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}" ; String version of GUID
hGuid = DllStructAlloc(strGuild)
if !DllCall("Shell32.dll", long:"703",lpstr:strActionVerify, long:IntControl(98,hGuid, 2,0,0))
   Message("Signed Image Error", "GUID conversion failed")
   exit
endif

#DefineSubroutine IsImageSigned( _strImageFile)

   ; Set the file name.
   DllStructPoke(hFileData, "pcwszFilePath",_strImageFile)

   ; Do the deed.
   return  !DllCall("WINTRUST.DLL", long:"WinVerifyTrust",long:INVALID_HANDLE_VALUE, lpstruct:hGuid, lpstruct:hTrustData)
#EndSubroutine


; Use our handy dandy FCL system assembly's process related classes.
ObjectClrOption("use","System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
objProcess = ObjectClrNew("System.Diagnostics.Process")
aProcesses = objProcess.GetProcesses(".")

hName     = BinaryAlloc(512)
hSize     = BinaryAlloc(4)
lUnsigned = ""
nMax      =  ArrInfo(aProcesses, 1) - 1
nChecked  = 0
for  i = 0 to  nMax

   objProc = aProcesses[i]

   ; Trap CLR exception error.
   nErrorMode = ErrorMode(@off)
   hProcHandle = objProc.Handle
   nError = LastError()
   ErrorMode(nErrorMode)
   if nError then continue ; Skip if we can't get a handle.

   ; Can't use the dotNet MainModule class on 64-bit systems so use the Win32 API instead.
   BinaryPoke4(hSize, 0, 512)
   DllCall('Kernel32.dll',long:'QueryFullProcessImageNameA',long:hProcHandle,long:0,lpbinary:hName, lpbinary:hSize)
   BinaryEODSet(hName, 512)
   strFileName = BinaryPeekStr(hName,0,512)
   objProc.Dispose()
   
   ; Add unsigned apps to a list.
   if !IsImageSigned(strFileName) then lUnsigned = ItemInsert(strFileName, -1, lUnsigned,@Cr)
   nChecked += 1
next

; Cleanup
BinaryFree(hSize)
BinaryFree(hName)
DllStructFree(hGuid)
DllStructFree(hFileData)
dllStructFree(hTrustData)

; Display results.
Message("Checked ":nChecked:" of ":nMax+1:" Process Images", lUnsigned)
exit


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade