Skip to content

Instantly share code, notes, and snippets.

@spake
Last active October 23, 2015 08:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spake/0472b9fd462cf35c6cb2 to your computer and use it in GitHub Desktop.
Save spake/0472b9fd462cf35c6cb2 to your computer and use it in GitHub Desktop.
Trend Micro CTF 2015: Crypto 400

We get a single file, document.xbm, which looks like an XBM image (a strange old file format that encodes images inside C strings). In our case, we have three arrays of bytes: bits, metadata1, and metadata2.

#define ________________width 1024
#define ________________height 540

static unsigned char ________________bits[] =
{
  0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00, 0x00,
  ...
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

unsigned char metadata1[] =
{
  0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E,
  ...
  0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0D, 0x0A
};

unsigned char metadata2[] =
{
  0x30, 0x82, 0x05, 0xEC, 0x30, 0x82, 0x04, 0xD4, 0xA0, 0x03,
  ...
  0x35, 0xE6, 0x7B, 0x52, 0x33, 0xA4, 0xBB, 0x67, 0x49, 0x6B
};

(It's easy to miss the metadata ones, since bits is some 55,000 lines long!)

I didn't actually try to open this in an XBM viewer, but I assume you get garbage. Instead, I decoded each of the three arrays' hex values and wrote them to files to better analyse them (isolating each array's bytes in a text editor and piping through sed 's/0x//g' | tr -d ' ,' | xxd -r -p).

We end up with:

» file bits
bits: CDF V2 Document, No summary info
» file metadata1
metadata1: ASCII text, with CRLF line terminators
» file metadata2
metadata2: data

Googling CDF V2 points us in the direction of Microsoft Office; specifically, this site tells us that first few bytes D0 CF 11 E0 A1 B1 1A E1 indicate it's either an Office 97-2003 document, or password-protected DOCX/XLSX/PPTX. Sure enough, renaming bits to bits.docx and trying to open it in Word for Mac 2011 prompts for a password to open the file.

metadata1 is actually a certificate: renaming it to metadata1.pem and opening it (with something like Quick Look on OS X, or just double-clicking on Windows) gives us some Microsoft-looking info, e.g. NT Principal Name: Administrator@trendmicro.local.

metadata2 looks like binary data, but using strings we get some curious results:

» strings metadata2
local1
trendmicro1
trendmicro-AD-CA0
...
Administrator@trendmicro.local0
...

This is looking a lot like the certificate in metadata1; is it the same one? We can convert it to something more friendly by base64-encoding it:

» echo '-----BEGIN CERTIFICATE-----' >metadata2.pem
» cat metadata2 | base64 -b 64 >>metadata2.pem
» echo '-----END CERTIFICATE-----' >>metadata2.pem

Inspecting the two certs reveals that while a lot of the Trend Micro-related names are the same, their public keys (and serial numbers, signatures, etc.) are different.

Alright, so we have these certificates, what do they have to do with the password-protected document?

Well, a lot of mad Googling eventually revealed that Microsoft made a way for administrators to open password-protected Office documents without the password in this article:

Previously, if the original creator of a file password either forgot the password or left the organization, the file was rendered unrecoverable. By using Office 2013 and an escrow key, which is generated from your company or organization’s private key certificate store, an IT admin can “unlock” the file for a user and then either leave the file without password protection, or assign a new password to the file. You, the IT admin, are the keeper of the escrow key which is generated from your company or organization’s private key certificate store. ... When a user later creates a password-protected Office 2013 Word, Excel, or PowerPoint file, this public key is included in the file header. Later, an IT pro can use the Office DocRecrypt tool to remove the password that is attached to the file ...

Looking at the end of bits.docx, we see some interesting XML:

X509Certificate="MIIF7DCCBNSgAwIB...kowU4qTXme1IzpLtnSWs="

This looks exactly the same as metadata2.pem! At this stage, DocRecrypt is looking very useful: we can remove the password from bits.docx using metadata2.pem! The above article tells us (under Set up the IT admin computer that has the key and DocRecrypt tool) that all we need is the private key/certificate pair!

But wait, don't we only have the public key of the metadata2.pem?

At this stage, I wondered what metadata1.pem was there for. Could the two certificates have been generated together, and could their moduli even share a prime? We can find this out by calculating the greatest common divisor (gcd) of their moduli: this will return the common prime if there is one, or 1 if they are coprime.

First, extract the certificates' public keys:

» openssl x509 -inform pem -in metadata1.pem -pubkey -noout >metadata1.pub
» openssl x509 -inform pem -in metadata2.pem -pubkey -noout >metadata2.pub

And do some Python-fu (thank god for pycrypto):

from Crypto.PublicKey import RSA
import gmpy

pubkey1 = RSA.importKey(open('metadata1.pub').read())
pubkey2 = RSA.importKey(open('metadata2.pub').read())

n1, n2 = pubkey1.n, pubkey2.n

print gmpy.gcd(n1, n2)

which gives us

157746045840640895812964578773586707100705919159625098240496503863073211370186483727847116602878913341676744929198720901288070585370639160366898124554401605620694963419366758153733330098773272970134599633189378720014988750464701361157408042199349121238466211527219183217335113256629803174746270659749965682417

So they do have a common prime, and so we can factor metadata2.pem's modulus and get its private key!!

# get primes from n2
p = long(gmpy.gcd(n1, n2))
q = long(n2 / p)

e = pubkey2.e # gonna be 65537

# calculate d from primes
d = long(gmpy.invert(e, (p-1)*(q-1)))

key = RSA.construct((n2,e,d,p,q))

with open('metadata2.key','w') as f:
    f.write(key.exportKey())

Then, we combine the public and private parts of the certificate into a Windows-friendly file format:

» openssl pkcs12 -in metadata2.pem -inkey metadata2.key -export -out metadata2.pfx
Enter Export Password:
Verifying - Enter Export Password:

Finally, as per the article's instructions, import metadata2.pfx into our Personal certificate store (using the Windows certificate manager, certmgr.msc) so DocRecrypt can use it:

Z:\ctf\trend\crypto\crypto400>DOCRECRYPT -i bits.docx -o decrypted.docx
Input File:bits.docx Output File:decrypted.docx SUCCESS

Whoooop! Now, after decrypting, it appears that the file is actually a PPTX file (it's a ZIP file containing a lot of references to ppt and slides); extracting the ZIP and grepping for TMCTF reveals the flag (or, for the less lazy, renaming to decrypted.pptx, opening in PowerPoint, and finding the flag hidden under the Trend Micro logo on the second slide):

TMCTF{OFFICE_ESCROW_KEY_SSL_GCD}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment