Supporting dynamic Malware Analysis with WinHttp library debug logs (tracing)

December 15, 2016 in Malware Analysis

Dynamic Malware Analysis is a tricky business. If you don’t use a dedicated sandbox, or an API monitor, it’s often hard to say what’s going on under the hood. Relying on differential analysis may not be enough and having multiple ways to get more information out of the session is always welcome. Process Monitor, DebugView, Performance/EWT logging, etc. are really handy as a support for black-box analysis, and so it is (or may be) enabling of the NtGlobalFlag. In this post I will describe one more hidden flag that can help to trace what’s going on when malware runs.

It turns out that WinHttp library has a built in debugging/tracing mechanism that enables it to log a lot of interesting details and send it either to a file, or directly to a debugger (or both). Lo and behold – it actually has a built-in API monitoring for us! It would be handy if this feature could become an integral part of popular debuggers (or a OllyDbg/Xdbg plug-in).

To enable the logging, you can either add the tracing options directly to Registry under the following key:

  • HKLM\SOFTWARE\Microsoft\Windows\
    CurrentVersion\Internet Settings\WinHttp\Tracing

f.ex. by using a reg file:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp\Tracing]
"Enabled"=dword:00000001
"LogFilePrefix"="winhttp"
"ToFileOrDebugger"=dword:00000000
"ShowBytes"=dword:00000001
"ShowApiTrace"=dword:00000001
"MaxFileSize"=dword:01312d00

or use a winhttptracecfg tool which is a part of Windows Server 2003 Resource Kit Tools.

The tool is handy, and we can run it like this:

  • winhttptracecfg -l winhttp -e 1 -d 0 -s 1 -t 1 -m 20000000

Running the tool gives us the following output:

The meaning of the options is as follows:

  • -e : 1: enable tracing; 0: disable tracing
  • -l : [trace-file-prefix], i.e., “C:\Temp\Test3”; or simply: “Test3”
  • -d : 0: output to file; 1: output to debugger; 2: output to both
  • -s : 0: show HTTP headers only; 1: ANSI output; 2: Hex output  (note, this doesn’t seem to work on newer versions of Windows)
  • -t : 1: enable top-level API traces; 0: disable top-level API traces
  • -m : Maximum size the trace file can grow to

and in our case:

  • -e 1 –> TracingEnabled: 1  –> enable tracing
  • -d 0 –> ToFileOrDebugger: 0 –> save to file only
  • -s 1 –> ShowBytes: 1 –> show ANSI output (test on Windows XP)
  • -t 1 –> ShowApiTrace: 1  –> enables API monitoring
  • -m 20000000 –> MaxFileSize: 20000000 –> file should be large enough
  • -l winhttp –> FileNamePrefix: winhttp –> prefix used for a file name

Let’s run a test.

One tool that uses WinHttp library is Autoruns. When you launch it with the tracing enabled you should see a log file immediately or almost immediately created f.ex.:

  • winhttp-autoruns.exe-4020.22.11.42.035-12.15.2016.LOG

where ‘winhttp’ is a prefix we provided in the tracing options, followed by the process name ‘autoruns.exe’, then 4020 which is a PID of the process, then time and date.

The example content looks as below, note that:

  • API calls and their parameters are clearly visible
  • Return values are provided
  • Lots of internal state-related debug info is also provided

(If you don’t see the .log file, check the file / process with VirusTotal)

22:11:42.035 ::>>>> WinHttp Version 6.0 Build 6.1.7601 >>>>Process autoruns.exe [4020 (0xfb4)] started at 22:11:42.035 12/15/2016
22:11:42.035 ::WinHttpOpen("Microsoft-CryptoAPI/6.1", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY (0), "", "", 0x0)
22:11:42.035 ::winhttp-dll added a reference to winhttp.dll (via LoadLibrary() call)
22:11:42.035 ::thread-pool created
22:11:42.035 ::thread pool initialized successfully
22:11:42.035 ::_SvcsStartup() succeeded; async-count = 1
22:11:42.035 ::WinHttpOpen() returning handle 0x38fcb98
22:11:42.035 ::WinHttpSetTimeouts(0x38fcb98, 0, 60000, 60000, 60000)
...
22:15:26.005 ::WinHttpOpen() returning handle 0x39ef730
22:15:26.005 ::WinHttpConnect(0x39ef730, "www.virustotal.com", 443, 0x0)
22:15:26.005 ::Indicate Status 0x39efad0, 0x0, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED (1024), 0x12edd4 [0x39efad0], 4
22:15:26.005 ::WinHttpConnect() returning handle 0x39efad0
22:15:27.066 ::WinHttpOpenRequest(0x39efad0, "POST", "/partners/sysinternals/file-reports?apikey=4e3202fdbe953d628f650229af5b3eb49cd46", "", "", 0x0, 0x00800000)
22:15:27.066 ::Indicate Status 0x395ebe8, 0x0, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED (1024), 0x2cefc84 [0x395ebe8], 4
22:15:27.066 ::WinHttpCreateUrl(0x2cefc20, 0x0, 0x0, 0x2cefc70)
22:15:27.066 ::    WinHttpCreateUrl(); URL = (null), URL Length = 0
22:15:27.066 ::    WinHttpCreateUrl: error 122 [ERROR_INSUFFICIENT_BUFFER]
22:15:27.066 ::WinHttpCreateUrl() returning FALSE
22:15:27.066 ::WinHttpCreateUrl(0x2cefc20, 0x0, 0x2af5b8, 0x2cefc70)
22:15:27.066 ::    WinHttpCreateUrl(); URL = https://www.virustotal.com/partners/sysinternals/file-reports?apikey=4e3202fdbe9, URL Length = 133
22:15:27.066 ::WinHttpCreateUrl() returning TRUE
22:15:27.066 ::WinHttpOpenRequest() returning handle 0x395ebe8
22:15:27.066 ::WinHttpGetProxyForUrl(0x39ef730, "https://www.virustotal.com", 0x2cefd9c, 0x2cefdb4)

On XP, the ShowBytes enables inclusions of the additional data dumps for headers f.ex.:

11:51:55.106 ::*0000001* :: sending data:
11:51:55.106 ::*0000001* :: 177 (0xb1) bytes
11:51:55.106 ::*0000001* :: <<<<-------- HTTP stream follows below ----------------------------------------------->>>>
11:51:55.106 ::*0000001* :: GET /wpad.dat HTTP/1.1
11:51:55.106 ::*0000001* :: Accept: */*
11:51:55.106 ::*0000001* :: User-Agent: Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; .NET5.0C; .NET5.0E)
11:51:55.106 ::*0000001* :: Host: 127.0.0.1
11:51:55.106 ::*0000001* :: Connection: Keep-Alive
11:51:55.122 ::*0000001* :: 
11:51:55.122 ::*0000001* :: 
11:51:55.122 ::*0000001* :: <<<<-------- End ----------------------------------------------->>>>
11:51:55.122 ::*0000001* :: WinHttpSendRequest() returning TRUE
11:51:55.122 ::*0000001* :: WinHttpReceiveResponse(0xaf2000, 0x0)
11:51:55.122 ::*0000001* :: received data:
11:51:55.122 ::*0000001* :: 67 (0x43) bytes
11:51:55.122 ::*0000001* :: <<<<-------- HTTP stream follows below ----------------------------------------------->>>>
11:51:55.122 ::*0000001* :: HTTP/1.1 200 OK
11:51:55.122 ::*0000001* :: Content-Length: 59745
11:51:55.122 ::*0000001* :: Content-Type: text/html
11:51:55.122 ::*0000001* :: 
11:51:55.122 ::*0000001* :: 
11:51:55.122 ::*0000001* :: <<<<-------- End ----------------------------------------------->>>>

Comments are closed.