3

I was going through DECIPHERING MSGSTORE.DB.CRYPT5, THE NEW DATABASE WHATSAPP & Steal WhatsApp update.

The author of the first link published a decryptor which sets the iv for the aes_192_cbc to

iv = bytearray([0x1E,0x39,0xF3,0x69,0xE9,0xD,0xB3,0x3A,0xA7,0x3B,0x44,0x2B,0xBB,0xB6,0xB0,0xB9])

Here is the full decryptor:

#!/usr/bin/python              
"""
48bits presents:
8===============================================D~~~
WhatsApp msgstore crypt5 decryptor by grbnz0 and nullsub
8===============================================D~~~

"""

import sys
import hashlib
import StringIO
from M2Crypto import EVP

key = bytearray([141, 75, 21, 92, 201, 255, 129, 229, 203, 246, 250, 120, 25, 54, 106, 62, 198, 33, 166, 86, 65, 108, 215, 147])
iv = bytearray([0x1E,0x39,0xF3,0x69,0xE9,0xD,0xB3,0x3A,0xA7,0x3B,0x44,0x2B,0xBB,0xB6,0xB0,0xB9])

def decrypt(db,acc):
  fh = file(db,'rb')
  edb = fh.read()
  fh.close()
  m = hashlib.md5()
  m.update(acc)
  md5 = bytearray(m.digest())
  for i in xrange(24): key[i] ^= md5[i&0xF]
  cipher = EVP.Cipher('aes_192_cbc', key=key, iv=iv, op=0)
  sys.stdout.write(cipher.update(edb))
  sys.stdout.write(cipher.final())

if __name__ == '__main__':
  if len(sys.argv) != 3:
    print 'usage %s <db> <accountname> > decrypted.db' % sys.argv[0]
  else:
    decrypt(sys.argv[1],sys.argv[2])

The only piece I miss is where did the IV came from ? I don't see it on the ida snapshot:

enter image description here

migrated from security.stackexchange.com Apr 25 '14 at 17:19

This question came from our site for information security professionals.

2

It doesn't seem to be on the IDA snapshot. You probably identified the right part of the program flow to set the initial key array. and assumed that the left part should have something to do with the iv, but that's not true. iv is 16 bytes, the left part of the IDA disassembly defines 24 bytes, which is the same length as key. Also, the very top of the image shows there's an if condition that branches either to setting up the key or setting up the left part, so these branches exclude each other.

After the key initialization on the right part, the MD5 calculation is performed, then there's the call to dword ptr eax+2AH where eax is set up to [ebp+0], and ebp itself being the top item on the stack. The parameters are put on the stack - ebp on top, then edx=esp+40, then edx=esp+60. esp+60 is setup earlier to be the location of the result of the call that preludes MD5_Init, and obviously the string being MD5'ed (MD5_Update(x, esp+60, strlen(esp+60)). This pattern - ebp being a pointer to data and functions, with the first parameter of the functions being ebp - hints at ebp being a pointer to a C++ class.

Overall, the right part sets up the key, calls a class method, does the MD5 stuff, and calls another class method. Comparing that to the python script, it seems like the first class method performs the python "read from file", the second the XOR-ing. The CVP.cipher call comes later, not shown on the IDA snapshot, so you can't see how iv is set up.

The left part of the IDA snapshot is something else, maybe code for decrypting old versions of the database. The top of the IDA snapshot says "perform the right part if something is equal to 5"; this could be a version number, with lower versions branching to the left; however, the IDA disassemble doesn't show the conditions for the left side branch, so this is guesswork.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.