Logman, the Windows volverine

Update

Coincidentally, @HECFBlog @nicoleibrahim released a tool ETL Parser that helps to at last extract raw buffers and as a result it produces a CSV file with data that can be analyzed row by row. This is the closest so far that I have seen for a tool to be able to help analyze the output of api trace log. Have a look at the screenshot:

Old Post

Almost everyone is excited about .etl files that are produced as a result of Event Tracing for Windows.

Almost, because not me.

This feature is so rich in … features. Except it’s only for MS internal consumption. At least, it seems to be the case in some very really interesting… well… cases…

It all started when I looked at the logman tool command line arguments; one that immediately caught my attention was this one:

logman create api

Aha… A basic API Monitor!

But not only that. It allows to run API Monitoring across different systems!!!

Oh… this could be a nice covert channel to transfer data between systems. Write one piece that constantly calls a monitored API and feeds it with the data to transfer, and then – on the other end – collect this data on the other system using logman tool. You could definitely implement it in a duplex set-up too.

Simple.

So I thought.

First, I immediately tested the ‘create api’ bit it and it worked like a charm:

logman create api foo -f bincirc -exe c:\windows\notepad.exe -o c:\test\notepad.etl

logman start foo

Now you have to simply run Notepad.exe (c:\windows\notepad.exe) and the .etl log will be created&updated as long as notepad.exe runs; the example content of the binary .etl file is as follows:

You can clearly see the APIs being recorded when Notepad is running:

  • RegisterClassW with the Unicode class ‘OleMainThreadWndClass’
  • GetAppCompatFlags2
  • IsProcessDPIAware
  • GdiReleaseDC
  • etc.

The only problem remaining:
– how to convert this binary blob into something more readable?

After googling around, I discovered that the tool basically embraces the api tracng functionality offered by the IApiTracingDataCollector interface. When you read into the docs of this interface you will soon realize that logman’s command line argument ‘-f’ that is supposed to determine the file type for the output file can be only… binary. So any attempts to specify TSV, or CSV will fail 🙁

Okay.

Since I couldn’t bite it from this end, I started looking at Windows Performance Analyzer (WPA) and other tracing and trace conversion tools.

No matter which one I used, I could only get a basic flow of the events, but w/o these interesting gore details of each API call:

It’s all nice and eye candy, but the problem is already visible:
– if you don’t know how to parse, you simply don’t.

As a last resort I tried ‘tracerpt’:

tracerpt <log> -o <output> -of CSV

.. and it provided a similar enigmatic output:

Some more googling around and now I know I need to get a .PDB file for the api trace provider, or some other schema files that will allow WPA to parse it properly…

Sigh…

The provider’s GUID is 7535aef9-4a3b-482b-91eb-25db0299995d.

It is nowhere to be found.

Eventually I gave up & I asked on Twitter.

Unfortunately, Alex Ionescu, and Zac Brown are both pessimistic 🙁 Still, I am grateful to them for chipping in and providing the useful feedback – if they can’t do it, I guess we explored all the ‘normal’ possibilities.

But then I am thinking… so… if it is an internal schema, then there is only one way out.

Brute-Force attack.

I may cover it in the next post.

From the blue team’s perspective, if you want to detect logman’s activity, in particular api tracing, you may be interested in this process tree:

The example command line arguments from my VM test run are as follows:

  • C:\Windows\system32\svchost.exe -k netsvcs
    • taskeng.exe {A7B77AA7-00E9-45C4-92C5-31C3868DB30D} S-1-5-18:NT AUTHORITY\System:Service:
      • C:\Windows\system32\rundll32.exe C:\Windows\system32\pla.dll,PlaHost “foo” “0x934_0x91c_0x2a045dff88a”

One thing is also worth mentioning – many logman command line option talk about running some task when some event happens; at first I thought it may be a new persistence mechanism, until I realized the tasks names required by these commands are task names registered using a Task Scheduler. So… yet another fail on the documentation, as it is very cryptic and talks about these various traces in a very superficial way 🙁

Enter Sandbox – part 17: The clique of clickers

Every sandbox needs to click stuff. Let it be ‘Next’, ‘Finish’, or ‘OK’ button – when the sample runs and the GUI shows up these buttons must be simply pressed somehow to ensure the execution continues.

Writing a clicker tool that handles it smoothly is not a trivial task.

First, it has to click only windows that are created by new processes – this can be kinda easily achieved by PID filtering f.ex. based on a process snapshot obtained prior to launching the sample, but don’t be fooled – the OS message boxes, or running services or programs may sometimes require additional clicking that are ‘out of band’ (e.g. hard error messages from csrss.exe process). There may also be some issues if sandbox tools don’t handle errors silently (e.g. exceptions in .NET tools).

Next, the actual clicking…

Oh boy… this is a tricky one…

Do we send a keyboard event, or mouse event?

Do we even know where the actual button we must click… is?

For installers that rely on Windows GUI system to draw its components – it’s quite easy. Every sych GUI control is a separate window which we can enumerate, find, inspect its class name, text and, send a message to, if we need to. Unfortunately, the generic solution is much harder to write, because:

  • Borland/Delphi/Embarcadero etc. use VCL and its own components (and programmers often created their own libraries with dedicated owner-drawn controls – this was really popular in late 90s and early naughties)
  • .NET uses its own components (Read about Windows Presentation Foundation (WPF))
  • Office uses its own GUI components (forms, etc.) – read about UI automation below and about Office UI Fabric
  • Java uses its own components; many testing frameworks rely on access to the source code (from what I learnt so far), so it’s hard to do a blackbox test
  • Adobe Flash and Silverlight are also custom drawn, same as Google Chrome, Mozilla Firefox and many other software packages may and often do use their own GUI libraries
  • Some (especially old-school) applications use their own components that are proprietary and only known to the software company that produced them, so it’s hard to write a generic clicker for them (Lotus Notes anyone?)
  • Then there are CLI tools that require manual input; these are impossible to handle in a generic way (interestingly, many executables submitted to VT are student projects and require manual input to produce some results; while not malicious, they pose a significant challenge to sandboxes)
  • The GUI elements can be localized
  • The localization itself is one issue, the other is the fact that localized software, especially the old one, often relies on the old ANSI code pages and ANSI APIs, so you have to guess what code page is being used by the sample’s GUI
  • The GUI elements can be ordered, or not (this may determine which button is ‘default‘ – in the absence of the standard buttons like ‘OK’, of ‘Finish’ this may be important)
  • The GUI elements can be bitmaps so no way to determine what to click… other than via known bitmap hashes, OCR/ICR, or a matrix clicking where you walk through the surface of the window and click every few pixels, moving both horizontally and vertically through the whole window area; it’s prone to errors and may force the app to exit early
  • The GUI elements can be drawn using a HTML code, so you may need to either access it via existing means (eg. via WM_HTML_GETOBJECT) or use Accessibility options (read below about that)
  • Many installers are interactive
    • The Installers often include EULA that has to be accepted (various keys used to accept, depending on language)
    • You may also need to choose options for installation e.g. installed UI languages, destination path, etc.
  • Many installers download other components from the net or drop generic component installers during the installation, so the clicker needs to work across multiple processes w/o disturbing parent while the child process is still being ‘processed’ (e.g. can’t send ‘Next’ to the parent process until the child process exited successfully; for examples, see anything that relies on winpcap)
  • There could be decoy GUI elements (e.g. transparent elements added to fool auto clickers, ad hoc passwords, captchas, etc.)

What can significantly help to code a good clicker is the use of mixed technologies and in general – be ready for lots of tuning:

  • Recognize installer / sample file type and apply appropriate playbook
    • This is very important, because sometimes you can use unattended options, if available
    • You can also try to decompile the installer to extract files w/o GUI
  • In a generic way:
    • If possible, enumerate windows and their children, and recognize standard controls
    • Ensure you you use proper windows APIs e.g. RealChildWindowFromPoint vs. ChildWindowFromPoint/ChildWindowFromPointEx
    • Recognize standard shortcuts/accelerators
    • Recognize default buttons (depends on the sequence of resources compiled into the binary)
    • Recognize ‘Next’, ‘Finish’, OK class of buttons, etc.
    • Recognize button classes in general (substrings: ‘button’, ‘btn’, etc.)
    • Recognize Window texts e.g. ‘Accept EULA’ type of buttons (checkboxes, or radiobuttons)
    • Recognize localized versions of the above
    • Recognize automation possibilities
      • The problem of automatic clicking is actually not reserved to sandboxes only
      • QA testing of any sort relies on it a lot: regression tests for coding and localization projects etc. involves lots of clicking and a huge progress has been made over the years to make it work smoothly, and fast
      • Luckily, many software packages support GUI controls’ automation via IAccessible interface
      • Have a read about Automated UI testing and Microsoft UI Automation
    • Have a look at other large projects where the localized strings for standard buttons are already localized e.g. LibreOffice
    • During windows enumeration search for both Unicode, and ANSI versions of these strings while enumerating windows
    • If no success, consider injecting instrumentation code that is ‘native’ to the installer’s platform
    • If no success, consider OCR/ICRing elements of the screen, or use the Babylon technique of hooking API/redrawing text and catching text printed using Text APIs
    • For Delphi, it’s a mundane task of understanding all versions of their VCLs (I have code some PoC code and it was painful, but I was able to read some labels from Delphi programs)
    • As a last resort, redirect trouble samples to a team doing manual malware analysis so the clicker can be tuned

And just to give you a localization sample… this is a list of ‘Agree’ buttons in various languages extracted from one of the Open Source projects:

  • Afrikaans Regso
  • Albanian Pranoj
  • Arabic موافق
  • Armenian Համաձայն եմ
  • Basque Onartu
  • Belarusian Згодзен
  • Bosnian Prihvatam
  • Breton A-du emaon
  • Bulgarian Съгласен
  • Catalan Hi estic d’acord
  • Cibemba Nasumina
  • Croatian Prihvaćam
  • Czech Souhlasím
  • Danish Acceptér
  • Dutch Akkoord
  • Efik Ami Mmenyịme
  • English I Agree
  • Esperanto Akceptite
  • Estonian Nõustun
  • Farsi موافقم
  • Finnish Hyväksyn
  • French J’accepte
  • Galician Aceito
  • Georgian ვეთანხმები
  • German Annehmen
  • Greek Συμφωνώ
  • Hebrew אני מסכים
  • Hindi सहमत
  • Hungarian Elfogadom
  • Icelandic Ég Samþykki
  • Igbo M Kwere
  • Indonesian Saya Setuju
  • Irish Glacaim Leis
  • Italian Accetto
  • Khmer I យល់​ព្រម​
  • Korean 동의함
  • Kurdish Ez Dipejirînim
  • Latvian Es piekrītu
  • Lithuanian Sutinku
  • Luxembourgish Unhuelen
  • Macedonian Да
  • Malagasy Ekeko
  • Mongolian Зєвшєєрлєє
  • Norwegian Godta
  • Pashto زه منم
  • Polish Zgadzam się
  • Portuguese Brasilian Eu Concordo
  • Romanian De acord
  • Russian Принимаю
  • Serbian Прихватам
  • Sesotho Kea Lumela
  • Shona Ndinobvuma
  • Simplified Chinese 我接受
  • Slovak Súhlasím
  • Slovenian Se strinjam
  • Spanish Acepto
  • Swahili Nakubali
  • Swedish Jag Godkänner
  • Tamil A நான் ஒப்புக்கொள்ளுகிறேன்
  • Thai ตกลง
  • Turkish Kabul Ediyorum
  • Twi Migye Tom
  • Ukrainian Приймаю
  • Uyghur قوشۇلىمەن
  • Uzbek Qabul qilaman
  • Valencian Accepte
  • Vietnamese Tôi đồng ý
  • Welsh Cytuno
  • Yoruba Mo Gbà
  • Zulu Ngiyavuma