Certulitis – one tool that keeps on giving

Update

EC who is one of the most technical guys I know pinged me because he figured out the meaning of that 0x00FB switch, The idea behind it is Windows archeology at its best and it goes as follows:

The code page your windows terminal uses is 437. Endash (‘–’) is an ASCII character 150 (0x96). When this character is inputted on terminal using code page 437 it will be mapped to ‘û’ which is code 0xFB.

How to use it with certutil?

You can run:

certutil ALT+150<command of your choice>

Old Post

Certutil is a really naughty tool. It accepts lots of various command line arguments that I believe are not widely known – and this post (and maybe some follow-up posts) is hoping to change that.

One of the first things I caught when I started analysing its command line arguments was the mysterious, case-insensitive command line argument comparison with the ‘uSAGE’ string. It turns out that certutil offers two different usage information depending on a command line option. If you just use ‘?’ then it’s the ‘official’ version. If it’s ‘uSAGE’ then it’s the unofficial one. Of course, once I found out I ran into Google and Twitter to find out if it is IN THE KNOWN.

Yes, it was. @0gtweet did it my favourite way – the hard way :-), @dunarth did it the right way, and @chris_ayres did it the earliest way (AFAICT).

Okay, with this out of the way, we look at the actual command line arguments.

Wait. What about the command line switches? Similarly to PowerShell, certutil accepts command line arguments using a number of different characters:

  • / (Unicode 0x002F)
  • – (Unicode 0x002D)
  • (Unicode 0x2013)
  • (Unicode 0x2212)
  • ? (Unicode 0x00FB)

I still can’t figure out why the last Unicode character on that list is being accepted. The Unicode character 0x00FB is ‘û’. If you know, please let me know and I will update the post.

Another discovery is brought to us by two unusual environment variables:

  • certsrv_rawhex – shows stuff in raw hex (e.g. certs)
  • CertSrv_Chain – enables debugging information being available for cert chain
  • CERTSRV_LOGMAX – maximum length of the certutil.log file
  • CERTSRV_DEBUG – enables certutil debug mode
  • CERTSRV_LOGFILE – name of the log file

The ‘certutil.log’ file is a log file that is created if DbgIsSSActive function imported from ‘certcli.dll’ which forwards it to ‘certca.dll’ returns true. I am kidding, it’s a convoluted way to say that certain conditions need to be met for the ‘certutil.log’ to be created, They can be either set via Registry (HKLM\Software\Microsoft\Cryptography\AutoEnrollment\Debug=XXX OR HKLM\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\Debug=XXX), or via environment variables listed below.

In fact, setting

set CERTSRV_LOGFILE=c:\test\foo.log
set CERTSRV_DEBUG=0xFFFFFFFF

will enable full logging to your main console and to the file c:\test\foo.log.

Pick up your favorite certutil command and give it a go. You will like the output as it helps to troubleshoot your manual testing 🙂

Finally, while certutil is primarily a command line application, it does create a windows called ‘CertUtil Application’ of class ‘CertUtil’, and apart from it, provides a UI for some of its commands (e..g -URL).

Sleeping DLL beauties

How do we sleep?

We do one of these:

  • kernel32/kernelbase ! Sleep
  • kernel32/kernelbase ! SleepEx
  • ntdll ! ZwDelayExecution

but… not only.

Windows 10 offers more libs with more sleeping goodness:

  • staterepository.core.dll ! sqlite3_win32_sleep
  • winsqlite3.dll ! sqlite3_win32_sleep
  • number of tools e.g. Visual Studio offer access to e_sqlite3.dll ! sqlite3_win32_sleep, Python to sqlite3.dll ! sqlite3_win32_sleep

These are actually identical SQLite functions exported by various libraries.

And then you may have LibreSSL on your system (c:\windows\system32\libcrypto.dll), so you can use:

  • libcrypto.dll, sleep

All of them can be used as a lame anti-sandbox/anti-analysis alternative to traditional delay functions listed at the top of the post. And as a random, but lasting very long delay replacing a never ending loop in batch files, or if lucky, maybe even ping 127.0.0.1.

How?

By executing these APIs via rundll32:

  • start /wait rundll32 kernel32.dll, Sleep
  • start /wait rundll32 kernelbase.dll, Sleep
  • start /wait rundll32 kernel32.dll, SleepEx
  • start /wait rundll32 kernelbase.dll, SleepEx
  • start /wait rundll32 staterepository.core.dll, sqlite3_win32_sleep
  • start /wait rundll32 winsqlite3.dll, sqlite3_win32_sleep
  • start /wait rundll32 sqlite3.dll, sqlite3_win32_sleep
  • start /wait rundll32 e_sqlite3.dll, sqlite3_win32_sleep
  • start /wait rundll32 libcrypto.dll, sleep

In these cases the argument to functions will be pretty high numbers (taken from stack and kinda random), but it’s not about logic, is it? 😉