PoC or GTFO, Volume 2
Page 41
Whether you choose XML in this style or to have every tag’s data between opening and closing tags, there are any number of ways to represent the data for each tag. For instance, once you know that the binary data for tag 0x9007 (TAG_DATABASE_ID) or tag 0x9010 (TAG_FIX_ID) is always a GUID, you might more conveniently represent it in the usual string form. Instead of showing the data for tag 0x5001 (TAG_TIME) as a raw qword, why not show that you know it’s a Windows FILETIME and present it as 16/09/2016 23:15:37.944? Or, on the grounds that it too must be generated automatically, you might decide not to show it at all!
Figure 13.18: Illegible XML from a ShimDB Dumping Tool
If I labour the presentation, it’s to make the point that what’s produced by any number of dumping tools inevitably varies according to purpose and taste. Let’s say a hundred researchers want a tool for the easy reading of SDB files. Yes, that’s doubtful, but 100 is a good round number. Then ninety will try to crib code from someone else—because, you know, who wants to reinvent the wheel—and what you get from the others will each be different, possibly very different, not just for its output but especially for what the source code shows of the file format. Worse, because nine out of ten programmers don’t bother much with commenting, even for a tool they may intend as showing off their coding skills, you may have to pick through the source code to extract the file format. That may be easier than reverse-engineering Microsoft’s binaries that work with the file, but not necessarily by much—and not necessarily leaving you with the same confidence that what you’ve learnt about the file format is correct and comprehensive. Writing a tool that dumps an undocumented file format may be more rewarding for you as a programmer but it is not nearly the same as documenting the file format.
Reversing XML to SDB
But is there really no definitive XML for representing SDB files? Of all the purposes that motivate anyone to work with SDB files closely enough to need to know the file format, one has special standing: Microsoft’s creation of SDB files from XML input. If we had Microsoft’s tool for that, then wouldn’t most researchers plumb for reversing its work to recover the XML source? After all, most reverse engineers and certainly the popular reverse-engineering tools don’t take binary code and unassemble it just to what you see in the debugger.
No, they disassemble it into assembly language that can be edited and re-assembled. Many go further and try to decompile it into C or C++ that can be edited and re-compiled, even if it doesn’t look remotely like anything you’d be pleased to have from a human programmer. In this context, the SDB to XML conversion to want is something you could feed to Microsoft’s Shim Database Compiler for compilation back to SDB. Anything else is pseudo-code. It may be fine in its way for understanding the content, and some may prefer it to a raw dump interpreted with reference to documentation of the file format, but however widely it gets accepted it is nonetheless pseudo-code.
The existence of something that someone at Microsoft refers to as a Shim Database Compiler has been known for at least a decade because Microsoft’s documentation of tag 0x6022 (TAG_-COMPILER_VERSION), apparently contemporaneous with Windows Vista, describes this tag’s data as the “Shim Database Compiler version.” And what, then, is the ShimDBC.exe from the even older TechNet article if it’s not this Shim Database Compiler?
But has anyone outside Microsoft ever seen this compiler? Dig out an installation disc for Windows XP from 2001, look in the Support Tools directory, install the ACT version 2.0 from its self-extracting executable, and perhaps install the Support Tools too in case that’s what the TechNet article means by “support utility.” For your troubles, which may include having to install Windows XP, you’ll get the article’s QFixApp.exe, and the Compatibility Administrator, as CompatAdmin.exe, and some other possibly useful or at least instructive tools such as GrabMI.exe, but you don’t get any file named ShimDBC.exe. I suspect that ShimDBC.exe never has existed in public as any sort of self-standing utility or even as its own file. Even if it did once upon a time, we should want a modern version that knows the modern tags such as 0x7025 (TAG_KSHIM) for defining driver shims.
For some good news, look into either QFixApp.exe or CompatAdmin.exe using whatever is your tool of choice for inspecting executables. Inside each, not as resources but intermingled with the code and data, are several instances of ShimDBC as text. We’ve had Microsoft’s Shim Database Compiler for 15 years since the release of Windows XP. All along, the code and data for the console program ShimDBC.exe, from its wmain function inwards, has been linked into the GUI programs QFixApp.exe and CompatAdmin.exe, of which only the latter survives to modern versions of the ACT. Each of the GUI programs has a WinMain function that’s first to execute after the C Run-Time (CRT) initialisation. Whenever either of the GUI programs wants to create an SDB file, it composes the Unicode text of a command line for the fake ShimDBC.exe and calls a routine that first parses this into the argc and argv that are expected for a wmain function and which then simply calls the wmain function. Where the TechNet article says QFixApp uses ShimDBC.exe, it is correct, but it doesn’t mean that QFixApp executes ShimDBC.exe as a separate program, more that QFixApp simulates such execution from the ShimDBC code and data that’s built in.
Unfortunately, CompatAdmin does not provide, even in secret, for passing a command line of our choice through WinMain to wmain. But, c’mon, we’re hackers. You’ll already be ahead of me: we can patch the file. Make a copy of CompatAdmin.exe as ShimDBC.exe, and use your favourite debugger or disassembler to find three things.
The program’s WinMain function;
the routine the program passes the fake command line to for parsing and for calling wmain; and,
the address of the Import Address Table entry for calling the GetCommandLineW function.
Ideally, you might simply assemble something like the following over the very start of WinMain.
call dword ptr [__imp__GetCommandLineW@0]
mov ecx,eax
call SimulateShimDBCExecution
ret 10h
In practice, you have to allow for relocations. Our indirect call to GetCommandLineW will need a fixup if the program doesn’t get loaded at its preferred address. Worse, if we overwrite any fixup sites in WinMain, then our code will get corrupted if fixups get applied. But these are small chores that are bread and butter for practised reverse engineers. For concreteness, I give the patch details for the 32-bit CompatAdmin.exe from the ACT version 6.1 for Windows 8.1 in Table 13.2.
For hardly any trouble, we get an executable that still contains all its GUI material (except for the seventeen bytes we’ve changed) but never executes it and instead runs the console-application code with the command line that we give when running the patched program. Microsoft surely has ShimDBC.exe as a self-standing console application, but what we get from patching CompatAdmin.exe must be close to the next best thing, certainly for so little effort. It’s still a GUI program, however, so to see what it writes to standard output we must explicitly give it a standard output. At a Command Prompt with administrative privilege, enter shimdbc -? >help.txt to get the built-in ShimDBC program’s mostly accurate description of its command-line syntax, including most of the recognised command-line options.
OFFSET
ORIGINAL
PATCHED
REMARKS
0x2FB54
8B FF
EB 08
Jump to ins. that will use existing fixup site.
0x2FB56
55
0x2FB57
8B EC
0x2FB59
81 EC 88 05 00 00
0x2FB5E
FF 15 D0 30 49 00
Use existing fixup site at offset 0x2FB60
0x2FB5F
A1 00 60 48 00
0x2FB64
33 C5
8B C8
0x2FB66
89 45 FC
E8 55 87 01 00
No fixup required for this direct call.
0x2FB69
8B 45 08
/> 0x2FB6B
C2 10 00
0x2FB6C
53
0x2FB6D
56
Table 13.2: Patch details for 32-bit CompatAdmin.exe from ACT 6.1 for Windows 8.1.
To produce the SDB file that is this article’s example, write the following as a Unicode text file named test.xml:
<?xml version="1.0" encoding="UTF–16" ?>
ID="{F9AB2228–3312–4A73–B6F9–936D70E112EF} ">
ID="{919CE4C8–D069–4521–A545–0132B06394ED} " LOGO="YES" />
and feed it to the compiler via the command line
shimdbc Driver test.xml test.sdb >test.txt
I may be alone in this, but if you’re going to tell me that I should know that you know the SDB file format when all you have to show is a tool that converts SDB to XML, then this would better be the XML that your tool produces from this article’s example of an SDB file. Otherwise, as far as I’m concerned for studying any SDB file, I’m better off with a raw dump in combination with actual documentation of the file format.
Do not let it go unnoticed, though, that the XML that works for Microsoft’s ShimDBC needs attributes that differ from the programmatic names that Microsoft has documented for the tags or the friendly names that can be obtained from the SdbTagTo-String function. For instance, the 0x6003 tag (TAG_MODULE) is compiled from an attribute named not MODULE but FILE. The 0x4017 tag (TAG_FLAGS) is synthesised from two attributes. Even harder to have guessed is that a LIBRARY tag is needed in the XML but does not show at all in the SDB file, i.e., as a tag 0x7002 (TAG_LIBRARY). So, to know what XML is acceptable to Microsoft’s compiler for creating an SDB file, you’ll have to reverse-engineer the compiler or do a lot of inspired guesswork.
Happy hunting!
13:10 Post Scriptum: A Schizophrenic Ghost
by Evan Sultanik and Philippe Teuwen
A while back, we asked ourselves,
What if PoC‖GTFO had completely different content depending on whether the file was rendered by a PDF viewer versus being sent to a printer?
A PostScript/PDF polyglot seemed inevitable. We had already done MBR, ISO, TrueCrypt, HTML, Ruby, ... Surely PostScript would be simple, right? As it turns out, it’s actually quite tricky.
$ gv pocorgtfo13.pdf
There were two new challenges in getting this polyglot to work:
The PDF format is a subset of the PostScript language, meaning that we needed to devise a way to get a PDF interpreter to ignore the PostScript code, and vice versa; and
It’s almost impossible to find a PostScript interpreter that doesn’t also support PDF. Ghostscript is nearly ubiquitous in its use as a backend library for desktop PostScript viewers (e.g., Ghostview), and it has PDF support, too. Furthermore, it doesn’t have any configuration parameters to force it to use a specific format, so we needed a way to force Ghostscript to always interpret the polyglot as if it were PostScript.
To overcome the first challenge, we used a similar technique to the Ruby polyglot from pocorgtfo11.pdf, in which the PDF header is embedded into a multi-line string (delimited by parenthesis in PostScript), so that it doesn’t get interpreted as PostScript commands. We halt the PostScript interpreter at the end of the PostScript content by using the handy stop command following the standard %%EOF “Document Structuring Conventions” (DSC) directive.
This works, in that it produces a file that is both a completely valid PDF as well as a completely valid PostScript program. The trouble is that Adobe seems to have blacklisted any PDF that starts with an opening parenthesis. We resolved this by wrapping the multi-line string containing the PDF header into a PostScript function we called /pdfheader.
The trick of starting the file with a PostScript function worked, and the PDF could be viewed in Adobe. That still leaves the second challenge, though: We needed a way to trick Ghostscript into being “schizophrenic” (cf. PoC‖GTFO 7:6), vi&., to insert a parser-specific inconsistency into the polyglot that would force Ghostscript into thinking it is PostScript.
Ghostscript’s logic for auto-detecting file types seems to be in the dsc_scan_type function inside /psi/dscparse.c. It is quite complex, since this single function must differentiate between seven different filetypes, including DSC/PostScript and PDF. It classifies a file as a PDF if it contains a line starting with “%PDF-”, and PostScript if it contains a line starting with “%!PS-Adobe”. Therefore, if we put anywhere before %PDF-1.5, then Ghostscript should be tricked into thinking it is PostScript! The only caveat is that Adobe blacklists any PDF that starts with “%!PS-Adobe”, so it can’t be at the beginning of the file, where it typically occurs in DSC files. But that’s okay, because Ghostscript only needs it to occur before the %PDF-1.5, regardless of where.
Index
0boot, 267
1-2-3 Sequence Me, 260, 385
4am, 222, 374
6502, 220, 344, 374, 607
65C816, 148
7 Zip, 57
AARD, 603
Abadi, Martín, 396
Academia, 13
ACM
CCS, 50
Adobe
Flash, 457
Reader, 128, 190, 352, 419, 457
Adventure, 143
AES, 439, 489
AFSK, 71
AGDQ, 144
AIM, 603
Aitel, Dave, 342
Albertini, Ange, 129, 415, 481
Allen, Tim, 602
AMBE Codec, 676
AMD64, 396
Anatomy, 139
Android, 35, 593
Antenna, 22
Antivirus, 57
Antonić, Voja, 84
APK, 593
AppleWin, 380
Apple ][, 220, 374
APRS, 71
Arciszewski, Scott, 43
Arduino, 200, 443
Aristotle, 13, 139
ARM, 401, 676
Cortex, 194, 311, 387
ASCII, 75, 467, 537, 579
ASLR, 536
Astrology, 16
Atari, 347, 604
Audio, 71, 676
Aumasson, Jean-Philippe, 43
AX.25, 71
Backdoor, 43, 306
Badenhop, Chris, 437
BadUSB, 659
Ballmer’s Peak, 696
Bangert, Julian, 483
Bank Street Writer III, 300, 381
Base91, 75
Baseband, 313
BASIC, 84, 302, 635
Battery, 343
Beer, 61, 217, 281
Ben, Byer, 423
Beneath Apple DOS, 308
Binary Brew Works, 61
BIOS, 147, 292, 355
Birr-Pixton, Joseph, 43
Black Hat, 30, 42, 438
Blazakis, Dion, 342
Blaze, Matt, 311
Bogk, Andreas, 587
Border Zone, 223
Bortreb, 146
BQ20Z80, 342
Brainfuck, 577
Bratus, Sergey, 71, 483
Bresenham’s Algorithm, 350
Brian, Life of, 439
Brinkman, John, 464
Brøderbund, 242
Brooks, John, 306
Brossard, Jonathan, 686
Brown Dog Affair, 139
Bruninga, Bob, 71
BSNES, 144, 190
Budiu, Mihai, 396
Bushing, 423
Calling Convention, 408
Cecil, Allan, 144
CFG, 396
Chaplin, Heather, 604
Chappell, Geoff, 740
Chimera, 415
Chinese, 313
ChipWhisperer, 663
CHIRP, 320
Chirp Modulation, 702
Chrome, 472
ClamAV, 57
Clang, 396
Clark, Sandy, 311
/> Clock Skew, 163
Cloud, 47
Codeplug, 319
Comma Chameleon, 453
Compiler, 483
Compression, 57, 289, 420, 467, 511
Confidence, 40
Control Flow Integrity, 396
CoolRISC, 342
Copy-Protection, 220, 311, 374
Copy ][+, 252
CORDIC Algorithm, 619
Corkami, 481
CR3, 553
CR4, 567
CRC, 26, 730
Criscione, Claudio, 481
Crowell, Jeffrey, 396
CRT, 350
Cryptography, 43, 82, 431, 439
CSV, 471
DAC, 349
Dalili, Soroush, 457
Daniels, Ronald J., 738
D’Antoine, Sophia, 47
Darkvoxels, 355
DARPA
CFT, 552
Davisson, Eric, 57, 355
DD4CR, 335, 676
Debugger, 435
Debugging, 194, 677
Anti, 263
Defcon, 43
Demay, Jonathan-Christofer, 437
DeviceGuard, 553
DFU, 311
Dig Dug, 385
Digital Operatives, 552
Disk ][, 226
Dissection, 139
DMR, 311, 676
DocIn, 313
Domas, Chris, 483, 577
Drapeau, Paul, 71
DSA, 43
Dukes, Brent, 71
DwangoAC, 144
E7 Protection, 257, 374
EBCDIC, 509
E.D.D., 252
EEPROM, 124, 442
Elektronika, 122
ELF, 396, 686
Elfsh, 400
EM4100
RFID, 672
Emulation, 148, 191, 401, 676
Erdös, Pál, 687
ERESI, 400
Erhlich, Paul, 433
Erlingsson, Úlfar, 396
ESP8266, 194
Ettus Research, 704
Evans, Chris, 455
EZ-Wave, 437
Fabela, Ron, 61
Facedancer, 664