Quantcast
Channel: Sogeti ESEC Lab
Viewing all 229 articles
Browse latest View live

The undocumented password validation algorithm of Adobe Reader X

$
0
0

Someone recently sent me an email about troubles when opening in Origami encrypted PDF documents produced by Acrobat Pro X. At first I thought it was a bug, but while looking in the data of the document I noticed two unusual things: the specified PDF version was Extension Level 8 and the revision level of the cryptographic handler was 6. However at this time, the latest published specification by Adobe is the Extension Level 5, and it makes no mention about a revision 6 of the security handler.

After some quick researchs, it appears that the specifications for this PDF version have not been released by Adobe, but are yet implemented in Adobe Reader X. This undocumented version makes use of a new password validation algorithm when opening encrypted documents.

Apparently the Extension Level 8 is an intermediate PDF version to prepare for the future arrival of the new ISO specifications (32000-2, aka PDF 2.0). Those are still in development, and the current drafts seem to be only available for the members of the ISO committee. As I could not find any publicly available documentation about the new password validation scheme, I decided to directly take a look inside Adobe Reader X.

Before detailing the algorithm, just a short history about Adobe encryption schemes used in PDF.

The first implementations of PDF used about 50 rounds of MD5 to validate the user password, then used RC4 or AES-128 to encrypt the document contents. With the arrival of Adobe Reader 9 and the PDF Extension Level 3, Adobe switched to a single round of SHA-256 combined with AES-256. While SHA-256 is considered as cryptographically more secure than MD5, this scheme was less resistant against a bruteforce attack. Adobe tried to remove this weakness by replacing the single SHA-256 pass with a custom key stretching algorithm to validate the user password. AES-256 is still the cipher being used for the encryption part.

The new algorithm is based on SHA-256, SHA-384, SHA-512 and AES-128-CBC. It takes a user password encoded in UTF-8 up to 127 bytes, combined with an 8 or 56 bytes salt, and produces a 256-bit hash. I am personally not aware of any known algorithm similar to this one, so I assume this is Adobe's personal design.

Here is the algorithm in pseudocode:

revision6_hash(password,salt,vector=''){block_size=32;input=SHA-256(password+salt+vector);key=input[0..15];iv=input[0..15];i=0;while(i<64||i<x[block_size-1]+32){block=input[0..block_size-1];aes=AES-128-CBC.init(key,iv);for(j=0;j<64;j++);{x="";if(len(password)>0)x=x+aes.update(password);x=x+aes.update(block);if(len(vector)>0)x=x+aes.update(vector);if(j==0)switch(sum_of_first_16_bytes_of_x%3){case0:block_size=32;digest=SHA-256;case1:block_size=48;digest=SHA-384;case2:block_size=64;digest=SHA-512;}digest.update(x);}h=digest.final();input=h;key=h[0..15];iv=h[16..31];i++;}returnh[0..31];}

The parameter salt is the 8-bytes (user or owner) key validation salt.The parameter vector is actually only present when hashing the owner password (it then contains the 48-bytes /U key).

I upgraded Origami to version 1,1 and included this algorithm. Beware that documents encrypted with this method cannot be opened in Adobe Reader 9 or earlier. By the way, other undocumented PDF features might also potentially be present in Adobe Reader X.

You can use the helper script pdfencrypt if you want to test it (--hardened switch). For example, using this method with a null password:

$ pdfencrypt -c aes -s 256 --hardened clear.pdf -o protected.pdf

The previous implementation (single SHA-256 pass) is not available anymore in the latest version of Acrobat Pro X, so Adobe manifestly wants to get rid of it.

Update: I missed a few lines in the assembly, so the previous algorithm was only matching Adobe's implementation when using null passwords. This is fixed now.


Hack.lu CTF 2011 Write-up : Romulan Business Network

$
0
0

Once again, we participated in the Capture-The-Flag event organized by the FluxFingers team at Hack.lu. Just like last year's CTF, the challenges were fun and original, and we finished up first after 48 hours of rude competition. The challenge here consisted in a little PDF crackme to solve. I will explain how I got through it using Origami and a standalone JavaScript VM like V8.

When opening the PDF in Adobe Reader, we are prompted to enter a password:

hacklu_ctf_romulan.png

The document is clearly making use of JavaScript to interact with the user, so let's start by dumping the scripts with pdfextract:

$ pdfextract --js Gwl4U5fqQZlJxEpPlgFL0hRNQrG4mmhg.pdf
$ ls Gwl4U5fqQZlJxEpPlgFL0hRNQrG4mmhg.dump/
script_69980994953860.js  script_69980994958360.js

This is the first script we get:

function___________________a(arg1){ozjcYQp=false;ozjcYQp="TS779Q81xBa2g7kP2qABK00";if(ozjcYQp){HeGJR4=YcQpjo+cYQpjo+zjocYQp;}}varozFjcYQp=this;varokzFfjcYQp=info;varYcQpjo=ozFjcYQp.okzFfjcYQp.author;varcYQpjo=ozFjcYQp.okzFfjcYQp.title;varzjocYQp=ozFjcYQp.okzFfjcYQp.subject;

And this is the second script extracted:

function__________________a(arg1){HeGJR4="Qb0pBIZ4NplD4H0pdqRU9HYqUtRbOzUy";}functionheyho(arg1){varoepnj43=toString;varoepni43=arguments;if(SWDfzP){try{a0O7ZyO=[18,55,16,102,49,29,53,72,16,17,54,65,79,97,11,49,23,22,41,59,98,104,60,19,124,17,83,52,49,61,110,34,22,25,66,10,37,106,114,67,9,66,53,30,27,23,70,50,38,94,70,52,93,100,41,23,45,49,49,78,60,42,8,90,34,80,1,76,11,30,63,80,61,47,93,93,50,59,58,62,26,45,82,64,112,26,83,5,18,26,20,99,74,3,119,44,68,21,10,39,54,20,41,27,80,0,73,20,79,109,65,83,47,0,107,53,39,60,18,14,69,11,85,41,53,54,103,56,25,26,69,65,54,38,42,17,28,26,98,73,6,7,21,42,40,70,80,113,18,44,24,89,48,32,98,78,60,42,8,90,34,80,1,76,4,2,119,80,108,101,90,81,47,115,117,42,16,47,6,9,44,51,66,22,87,85,52,83,24,39,27,77,10,57,18,35,122,12,62,12,23,4,9,89,1,36,79,65,125,27];varWyOSbq=a0O7ZyO.length;YQpoczFfjk=HeGJR4.toString().length;for(i=0,j=0;i<WyOSbq;i++,j++){a0O7ZyOChar=a0O7ZyO[i];keyChar=HeGJR4.toString().charCodeAt(j);a0O7ZyO[i]=String.fromCharCode(a0O7ZyOChar^keyChar);if(j==YQpoczFfjk-1)j=-1;}eval(a0O7ZyO.join(""));SWDfzP=false;}catch(e){}}if(!app){oczFfjkYQp=0x72;}if(app){oczFfjkYQp+=1;}else{try{a0O7ZyO=[104,60,19,124,17,83,52,49,61,110,34,22,25,66,10,37,106,114,67,9,66,53,30,27,23,70,50,24,55,16,10,49,29,89,72,47,93,93,50,59,58,62,26,45,82,64,112,74,3,119,44,68,21,10,39,54,20,41,16,17,54,65,79,94,11,49,23,99,41,59,98,38,94,70,52,93,100,41,23,45,49,49,78,60,42,8,90,34,80,1,76,11,30,63,80,61,27,80,0,73,20,79,109,26,83,5,18,26,20,99,65,83,47,0,107,53,39,60,18,14,69,11,85,41,53,54,99,80,113,18,44,24,89,48,32,98,78,38,24,17,28,26,98,44,26,17,54,70,60,42,48,90,34,21,42,40,103,56,25,26,69,65,80,1,76,24,24,119,80,90,81,47,108,101,15,117,42,16,47,6,9,44,51,66,22,87,85,52,83,24,39,27,77,10,57,18,35,122,12,62,12,23,4,9,89,1,36,79,65,125,27];varWyOSbq=a0O7ZyO.length;YQpoczFfjk=HeGJR4.toString().length;for(i=0,j=0;i<WyOSbq;i++,j++){a0O7ZyOChar=a0O7ZyO[i];keyChar=HeGJR4.toString().charCodeAt(j);a0O7ZyO[i]=String.fromCharCode(a0O7ZyOChar^keyChar);if(j==YQpoczFfjk-1)j=-1;}eval(a0O7ZyO.join(""));SWDfzP=false;}catch(e){}}if(oczFfjkYQp==0x152){___________________a(1);}else{__________________a(2);}varfuu=oepni43.callee().oepnj43().replace(/W/g,"").toUpperCase();}varSWDfzP=true;varHeGJR4="zZLnggvOZ4CFlfMbS3bn";varJ9nYrE='function TS779QqABK81xBa2g7kP0() {return 1; }';eval(J9nYrE);varXwA5WE=0;vardLKOnD='';varBmW8cd='';varmHkMFd=0;while(XwA5WE<2000){mHkMFd=XwA5WE+1;dLKOnD='function TS779QqABK81xBa2g7kP';dLKOnD+=mHkMFd;dLKOnD+='() { return TS779QqABK81xBa2g7kP';dLKOnD+=XwA5WE;dLKOnD+='();}';HeGJR4+=XwA5WE;BmW8cd+=dLKOnD;XwA5WE++;}eval(BmW8cd);eval(TS779QqABK81xBa2g7kP2000());varoczFfjkYQp=0x01;heyho(1);

As we can see, those two scripts are obfuscated, so we'll need a JavaScript VM to debug them. I will here use the V8 JavaScript engine for that purpose, but you can use others as well (SpiderMonkey, Rhino...). I plan to integrate a V8 sandbox into a next future release of Origami. For now, you will have to use the JS engine separately and define a minimal Acrobat namespace if required by the script.

$ cd Gwl4U5fqQZlJxEpPlgFL0hRNQrG4mmhg.dump
$ cat *.js > payload.js
$ d8 payload.js
payload.js:18: ReferenceError: info is not defined
var okzFfjcYQp=info;
^
ReferenceError: info is not defined
    at payload.js:18:1

The first lines of the script reference some strings contained in the document's metadata (through the this.info object). Let's create that object with the proper values. We first dump the metadata object with pdfmetadata.

$ pdfmetadata Gwl4U5fqQZlJxEpPlgFL0hRNQrG4mmhg.pdf
[*] Document information dictionary:
Producer            : MiKTeX pdfTeX-1.40.12
Subject             : I5xlmqMpKN14VZNWuCulWR2fy4X6jS3j
Keywords            : 47ljm6agvj2xYyKVnEVwBfin2KQvzzto
CreationDate        : BjcEwttYWwOcPn1bZPwXPqbt1jUq6X4e
Creator             : TeX
Author              : dVbFZxLu7en8hJhhFfCTIOek76hBPONC
Title               : xj5oWJOch2E0ir5BI05QuClyYTCnHBmz
Trapped             : False
ModDate             : D:20110901121355+02'00'
PTEX.Fullbanner     : This is MiKTeX-pdfTeX 2.9.4225 (1.40.12)

Then we put at the beginning of the script:

varinfo={author:"dVbFZxLu7en8hJhhFfCTIOek76hBPONC",title:"xj5oWJOch2E0ir5BI05QuClyYTCnHBmz",subject:"I5xlmqMpKN14VZNWuCulWR2fy4X6jS3j"};

We will not even try to understand the code. Instead of trying to deobfuscate the contents of the script, we will go fast and get straight to the point : we know the dialog box prompting for the key is invoked using the JavaScript method app.response. Consequently we will directly hook it by defining the method:

varapp={response:function(str){print(str);print(arguments.callee.caller.toString());}};

This definition will print out the prompt message, and also the code of the method responsible for calling it.

$d8payload.jsEnterthekeyforvalidationfunctioneval(){[nativecode]}

We managed to get to the call to app.response so the emulation seems to be working fine. Now we need to know what was the argument passed to the eval method, so we simply hook it by redefining it. As there are a lot of junk calls to eval in the script, we filter out the results:

_eval=eval;eval=function(str){if(typeof(str)=='string'&&str.match(/app\.response/))print(str);_eval(str);};

Now we get :

$d8payload.jsvarkey='tXy'+cYQpjo+'YxK';varanswer=app.response('Enter the key for validation','Hack.LU PDF Challenge','');if(answer==key){app.alert('you have got it! the key is: '+key);}else{app.alert('nope try again');}

The defined key variable is the solution to the crackme. We actually do not need to know what is the cYQpjo variable: we can dump the key since it is accessible from the scope of app.response in that case.

In the end, we just define:

varapp={response:function(){print(key);}};

And we get:

$ d8 payload.js
tXyxj5oWJOch2E0ir5BI05QuClyYTCnHBmzYxK

Done!

Hack.lu CTF 2011 Write-up : FluxScience

$
0
0

This was probably one of the most entertaining challenges of this CTF.A file data.flux is provided. The goal is to analyze a Windows binary to be ableto decrypt this file.

A few informations are given:

Thanks to a former employee of FluxScience (one of our competitors), wemanaged to get hands on some important files which might help us revealingcompany secrets. Attached you will find the files. The employee who providedthem got fired. You might be lucky and find his account still working:FLUX-38B273DD75860083-0B3DD6B02EC5B9B1-4AFFBAC2EB8B4D17 He might not havethe necessary permission to decrypt the personal data data.flux. he stolethem from his boss, _GLaDOS_. Would you mind helping us by finding theircompany secret?

The sections of the binary seem to contains hints:

.go      00401000 0040A000 R . X . L para 0001 public CODE 32 0000     0000
.find    0040A140 0040D000 R . . . L para 0002 public DATA 32 0000     0000
.the     0040D000 00410000 R W . . L para 0003 public DATA 32 0000     0000
.rsrc    00410000 00411000 R . . . L para 0005 public DATA 32 0000     0000
Intel(R) 00411000 00413000 R W X . L para 0004 public CODE 32 0000     0000

Removing code obfuscation

The code is slightly obfuscated. Jumps and calls are emulated using a simplestack-based virtual machine. All the jumps/calls have this form:

Intel(R):004115FD E8 45 FD FF FF                 call    vm_start
Intel(R):004115FD                ; ---------------------------------------------------------------------------
Intel(R):00411602 02                             db    2
Intel(R):00411603 52                             db  52h ; R
Intel(R):00411604 10                             db  10h
Intel(R):00411605 40                             db  40h ; @
Intel(R):00411606 00                             db    0
Intel(R):00411607 03                             db    3
Intel(R):00411608 04                             db    4
Intel(R):00411609 04                             db    4
Intel(R):0041160A 00                             db    0
Intel(R):0041160B                ; ---------------------------------------------------------------------------
Intel(R):0041160B E9 3A 00 00 00                 jmp     loc_41164A

vm_start reads the data located just below the call, here 02 52 10 40 00 03 0404 00. The virtual machine has only 10 opcodes (thanks to alex for the list):

  • 0: O_JMP jump to the value on the top of the stack
  • 1: O_CALL call the value on the top of the stack
  • 2: O_LOAD load a 32 bit value
  • 3: O_FLAG test a EFLAG value
  • 4: O_IMUL multiplies the two values on the top of the stack
  • 5: O_ADD same with an addition
  • 6: O_SUB same with a subtraction
  • 7: O_NEG negate value (pushes 1 if zero, else 0)
  • 8: O_AND logical and between two values on the top of the stack
  • 9: O_OR same with logical or

In the example, the VM code can be disassembled this way:

02 52 10 40 00 load 0x00401052 # jump destination
03 04          test ZF
04             imul
00             jump

VM pushes the jump address. It then tests if the Z flag is set, which willreturn or value of 0 or 1. It multiplies this value with the jump address, andjumps to this address if it is not 0. Hence this code is similar to:jz 401052h.

The same method is used to emulate the other kind of jumps. The emulated opcodesare "call", "jmp", "jz", "jnz", "jb", "jl" and "jle". A IDA script has beenwritten to de-obfuscate the whole binary:

#!/usr/bin/env pythonimportidaapiO_JMP=0O_CALL=1O_LOAD=2O_FLAG=3O_IMUL=4O_ADD=5O_SUB=6O_NEG=7O_AND=8O_OR=9VM_START_EA=0x411347flags_list={0:'OF',2:'CF',4:'ZF',8:'SF',10:'PF'}classJumpDecoder(object):def__init__(self,ea):self.ea=eaself.read=5self.instr=Noneself.dest=Noneself.vm_bytes=""self.analyze()defanalyze(self):while1:opcode=idaapi.get_full_byte(self.ea+self.read)self.read+=1ifopcodein[O_FLAG,O_IMUL,O_ADD,O_SUB,O_NEG,O_AND,O_OR]:self.vm_bytes+=chr(opcode)ifopcode==O_FLAG:# O_FLAG has one operandself.vm_bytes+=chr(idaapi.get_full_byte(self.ea+self.read))self.read+=1elifopcodein[O_JMP,O_CALL]:self.instr=opcodebreakelifopcode==O_LOAD:# jmp destinationself.dest=idaapi.get_full_long(self.ea+self.read)self.read+=4else:print"unknown opcode!"breakdefdeobfuscate(self):jmp_equivalent={'':"jmp",'\x03\x04\x04':"jz",'\x03\x02\x04':"jb",'\x03\x04\x07\x04':"jnz",'\x03\x00\x03\x08\x06\x07\x07\x04':"jl",'\x03\x00\x03\x08\x06\x07\x07\x03\x04\x09\x04':"jle"}ifself.destisnotNoneandself.instrisnotNone:ifself.instr==O_CALL:opcode="call"else:ifjmp_equivalent.has_key(self.vm_bytes):opcode=jmp_equivalent[self.vm_bytes]else:print"%08X: undefined"%self.ea# never reach hereelse:print"error occurred"returnprint"%08X: %s%08Xh"%(self.ea,opcode,self.dest)foriinrange(self.read):idaapi.assemble(self.ea+i,0,self.ea+i,1,"nop")idaapi.assemble(self.ea,0,self.ea,1,"%s%d"%(opcode,self.dest))idaapi.do_unknown_range(self.ea,self.read,idaapi.DOUNK_EXPAND)idaapi.create_insn(self.ea)idaapi.do_unknown(self.ea+self.read,idaapi.DOUNK_EXPAND)idaapi.create_insn(self.ea+self.read)jmp_ea=GetOperandValue(self.ea+self.read,0)# get jump destinationidaapi.do_unknown(jmp_ea,idaapi.DOUNK_EXPAND)idaapi.create_insn(jmp_ea)idaapi.do_unknown(self.dest,idaapi.DOUNK_EXPAND)idaapi.create_insn(self.dest)defmain():while1:found=FalseforeainCodeRefsTo(VM_START_EA,1):found=Trued=JumpDecoder(ea)d.deobfuscate()iffound==False:breakidaapi.analyze_area(0,0xffffffff)passif__name__=='__main__':main()

The IDA database is fully patched, making the code more readable. I preferred towork on a clean executable. For this, I produced a DIF file with IDA thatspecifies all the patches that have been made to the database, and I injectedthem in the binary. Finally, a working, clean executable is obtained.

Overview of the algorithm

The account number is composed of 3 blocks (block1, block2, block3) of 64 bits.Each block is encrypted using XTEA. The encryption key is derived from CPUinformation. Computation is done in sub_401060, which produces a 128 bit key.Let's name it tea_key1.

A second key tea_key2 is composed of the last 64 bit block of the accountnumber, and the last 64 bits of the CPU key.

The decryption of the account number is done this way:

tea_key1=block3+cpu_key[8:]tea_key2=cpu_keyblock1=xtea_decrypt(tea_key1,block1,32)block1=xtea_decrypt(tea_key2,block1,33)block2=xtea_decrypt(tea_key2,block2,34)block3=xtea_decrypt(tea_key2,block3,35)

XTEA functions are a bit modified: the third argument is the number of rounds,here variable.

Three checks are made on the resulting blocks:

  • block2 value, once decrypted, must be "_GLaDOS_".
  • Last 32 bits of block3 must match a modified Adler32 hash of the first 32 bits of block3
  • First 32 bits of block3, xored with the last 32 bits of the CPU key, must match the modified Adler32 hash of the 128 bits of block1 + block2.

Basically, the provided test account will not be correctly decrypted, as the CPUkey will not be the same as _GLaDOS_'s CPU. So this will not help us for themoment.

I decided to write an account generator that will pass these checks. Thepseudocode is quite obvious:

tea_key2=cpu_keyblock1="UNKNOWN!"block2="_GLaDOS_"h1=adler32(block1+block2)^cpu_key[-4:]h2=adler32(h1)block3=h1+h2block2=xtea_encrypt(tea_key2,block2,34)block3=xtea_encrypt(tea_key2,block3,35)tea_key1=block3+cpu_key[8:]block1=xtea_encrypt(tea_key2,block1,33)block1=xtea_encrypt(tea_key1,block1,32)

The generated serial passes the three checks. It is then easier to follow therest of the algorithm.

The charset of block1 is checked: it must match [A-Za-z_]. It is compared to thesession username, retrieved with GetUserNameA, and must be 8 chars long. Thispart has to be patched.

Tricky things start now. A new XTEA key is derived from the decrypted buffer andthe CPU key. This key is used to decrypt the whole data.flux file. A check isdone on the decrypted file:

  • first dword must match the modified Adler32 hash of the account name.
  • second dword must be 0xdeadbeef.

This is bad, data.flux is not correctly decrypted, and we cannot bruteforce a128 bit key. Good bye...

The decryption key for data.flux is composed of:

  • block3, decrypted with the CPU key
  • the first 32 bits of the username xored with their last 32 bits. For example, "UNKNOWN!" gives 0x4e4b4e55 ^ 0x214e574f = 0x6f05191a.
  • the first 32 bits of "_GLaDOS_" xored with their last 32 bits.

As we do not know the CPU key present of _GLaDOS_ computer, we cannot compute theXTEA key used to decrypt data.flux. And we are screwed.

Retrieving the CPU key

How is computed the CPU key? It consists in 128 bits, i.e 4 dwords. Thepseudo-code to generate it is:

a,b,c,d=cpuid(0x80000002)cpu_key[0]=acpu_key[1]=bcpu_key[3]=c^da,b,c,d=cpuid(0x80000003)cpu_key[3]^=a^b^c^da,b,c,d=cpuid(0x80000004)cpu_key[3]^=a^b^c^dcpu_key[2]=key[3]^0x78756C66# xulf

cpuid returns the processor brand string, for values of 0x80000002, 0x80000003and 0x80000004. On my computer I get:

"Intel(R) Core(TM)2 Duo CPU     E8400  @ 3.00GHz"

cpu_key[0] and cpu_key[1] depend only on the value of cpuid(0x80000002). Hence cpu_key[0] + cpu_key[1] = "Intel(R)" here.

HINT! HINT!: "Intel(R)" is the name of the last section of the binary, so itseems we are on the good way!

The two last dwords have to be computed. As cpu_key[2] = key[3] ^ 0x78756C66, abruteforce on 32 bits will give the result. The plaintext for block2 needs to be"_GLaDOS_", so we can try all the possible XTEA keys for the test account numberto retrieve the CPU key:

/* XTEA decryption, ripped from http://en.wikipedia.org/wiki/XTEA */voiddecipher(unsignedintnum_rounds,unsignedlong*v,unsignedlong*k){unsignedlongv0=v[0],v1=v[1],i;/* delta has a custom value */unsignedlongdelta=0x61c88646,sum=delta*num_rounds;for(i=0;i<num_rounds;i++){v1-=((v0<<4^v0>>5)+v0)^(sum+k[sum>>11&3]);sum-=delta;v0-=((v1<<4^v1>>5)+v1)^(sum+k[sum&3]);}v[0]=v0;v[1]=v1;}intbrute_cpuid(){/* encrypted block2, in the test account number */unsignedcharencrypted[]={0xb0,0xd6,0x3d,0x0b,0xb1,0xb9,0xc5,0x2e};unsignedlongblock[2];unsignedchartea_key[16]={'I','n','t','e','l','(','R',')'};unsignedlongseed1,seed2;unsignedlongi,j;intfound=0;for(i=0;i<0xffffffff;i++){seed1=i;seed2=i^'xulf';memcpy(tea_key+8,&seed1,4);memcpy(tea_key+12,&seed2,4);memcpy(block,encrypted,8);decipher(34,block,(unsignedlong*)tea_key);if(memcmp(block,"_GLaDOS_",8)==0){found=1;break;}}if(found){printf("seed = 0x%x\n",i);for(j=0;j<16;j++)printf("%02x",tea_key[j]);printf("\n");}return0;}

The bruteforce is quite fast. Finally we obtain:

seed = 0x13715e62
496e74656c285229625e71130432046b

Computing _GLaDOS_ account number

Now, let's try the test account number again, this time replacing the CPU keywith the correct one. The account is correctly decrypted. The decrypted bufferis:

00000000  57 68 65 61 74 6C 65 79 5F 47 4C 61 44 4F 53 5F  Wheatley_GLaDOS_
00000010  D8 37 E8 58 31 01 B7 03                          .7.X1...

So Wheatley is the stealer! But, again, the account number does not decryptproperly data.flux. Why? Remember that the file belonged to _GLaDOS_, and not toWheatley. A new account number has to be forged, this time with the username"_GLaDOS_". The account generator described above can be reused: only the CPUkey needs to be changed.

The full source code for the account number generation is:

#!/usr/bin/env pythonimportstruct# ripped from http://code.activestate.com/recipes/496737-python-xtea-encryption/defxtea_encrypt(key,block,n=32):v0,v1=struct.unpack("<2L",block)k=struct.unpack("<4L",key)sum,delta,mask=0,0x61c88646,0xffffffffforroundinrange(n):v0=(v0+(((v1<<4^v1>>5)+v1)^(sum+k[sum&3])))&masksum=(sum+delta)&maskv1=(v1+(((v0<<4^v0>>5)+v0)^(sum+k[sum>>11&3])))&maskreturnstruct.pack("<2L",v0,v1)defadler32(input):a,b=1,2# be careful: b=2forcininput:ifc&0x80:c|=0xffffff00a=(a+c)%0xfff1b=(a+b)%0xfff1returna+(b<<16)defkeygen(username):cpu_key=bytes.fromhex("496e74656c285229625e71130432046b")# glados cpu keytea_key2=cpu_keyblock1=usernameblock2=b"_GLaDOS_"xor_value,=struct.unpack('<L',cpu_key[-4:])h1=adler32(block1+block2)h1^=xor_valueh2=adler32(struct.pack('<L',h1))block2=xtea_encrypt(tea_key2,block2,34)block3=struct.pack('<2L',h1,h2)block3=xtea_encrypt(tea_key2,block3,35)tea_key1=block3+cpu_key[8:]block1=xtea_encrypt(tea_key2,block1,33)block1=xtea_encrypt(tea_key1,block1,32)serial="FLUX"forblockin[block1,block2,block3]:a,b=struct.unpack('<2L',block)serial+="-{0:08X}{1:08X}".format(a,b)returnserialprint(keygen(b"_GLaDOS_"))

The account number for _GLaDOS_ is:FLUX-04644DBE65073E9E-0B3DD6B02EC5B9B1-F01864F663B0B371 . It correctly decryptsdata.flux and the challenge is over. Almost over...

Final round

The output file is named flux.dat. Once the decryption is finished, the programdisplays a message box:

The decrypted buffer is partly corrupted. Good luck anyway.

Here is the content of the file:

00000000  50 0B 03 04 14 00 01 00 00 00 00 00 00 00 82 23  P.............‚#
00000010  73 0F 00 00 00 00 30 00 00 00 12 00 00 00 63 6F  s.....0.......co
00000020  6D 70 61 6E 79 2D 73 65 63 72 65 74 2E 74 78 74  mpany-secret.txt
00000030  2B BF 46 F7 C4 D5 A9 F6 BE E9 C6 DD F5 6F 8A 3A  +¿F÷ÄÕ©ö¾éÆÝõoŠ:
00000040  A4 7B 8C C3 B1 2C 13 87 8B C5 6E 89 1C A6 6D 4F  ¤{ŒÃ±,.‡‹Ån‰.¦mO
00000050  12 89 56 16 4F F4 5D 82 88 EF A7 FB 99 DE 59 61  .‰V.Oô]‚ˆï§û™ÞYa
00000060  79 6D 24 3B 11 34 C4 73 95 CB A2 68 50 40 01 02  ym$;.4Äs•Ë¢hP@..
00000070  14 00 14 00 01 00 00 00 00 00 00 00 82 23 73 0F  ............‚#s.
00000080  3C 00 00 00 00 00 00 00 12 00 00 00 00 00 00 00  <...............
00000090  00 00 20 00 00 00 00 00 00 00 63 6F 6D 70 61 6E  .. .......compan
000000A0  79 2D 73 65 63 72 65 74 2E 74 78 74 00 4B 05 06  y-secret.txt.K..
000000B0  00 00 00 00 01 00 01 00 40 00 00 00 6C 00 00 00  ........@...l...
000000C0  00 00                                            ..

It is quite obvious that it is a zip file, which has been partly destroyed. Thearchive contains a single file, company-secret.txt.

The two first magic bytes should be 50 4B ("PK") insted of 50 0B. The sameproblem is found at offsets 6D (40 insted of 4B) and AC (00 instead of 50).

The compressed stream goes from offset 0x30 to 0x6c. Its size should be locatedin the compressed size field of the file header, at offset 0x12, which iscurrently 0x00000000.

Finally, the "uncompressed size" field of the central directory at offset 0x84has a zero value, while it must match the uncompressed size value of the fileheader at offset 0x16 (0x00000030).

Once these changes have been made, flux.dat is:

00000000  50 4B 03 04 14 00 01 00 00 00 00 00 00 00 82 23  PK............‚#
00000010  73 0F 3C 00 00 00 30 00 00 00 12 00 00 00 63 6F  s.<...0.......co
00000020  6D 70 61 6E 79 2D 73 65 63 72 65 74 2E 74 78 74  mpany-secret.txt
00000030  2B BF 46 F7 C4 D5 A9 F6 BE E9 C6 DD F5 6F 8A 3A  +¿F÷ÄÕ©ö¾éÆÝõoŠ:
00000040  A4 7B 8C C3 B1 2C 13 87 8B C5 6E 89 1C A6 6D 4F  ¤{ŒÃ±,.‡‹Ån‰.¦mO
00000050  12 89 56 16 4F F4 5D 82 88 EF A7 FB 99 DE 59 61  .‰V.Oô]‚ˆï§û™ÞYa
00000060  79 6D 24 3B 11 34 C4 73 95 CB A2 68 50 4B 01 02  ym$;.4Äs•Ë¢hPK..
00000070  14 00 14 00 01 00 00 00 00 00 00 00 82 23 73 0F  ............‚#s.
00000080  3C 00 00 00 30 00 00 00 12 00 00 00 00 00 00 00  <...0...........
00000090  00 00 20 00 00 00 00 00 00 00 63 6F 6D 70 61 6E  .. .......compan
000000A0  79 2D 73 65 63 72 65 74 2E 74 78 74 50 4B 05 06  y-secret.txtPK..
000000B0  00 00 00 00 01 00 01 00 40 00 00 00 6C 00 00 00  ........@...l...
000000C0  00 00                                            ..

Open it, extract company-secret.txt and... it is password protected. Rememberthere where two hints in the section names. Only one has been used. So .go .find.the .rsrc! I made a raw dump of the section, and search for strings.

$ strings moonstone.panel.exe.section-3.dmp displays only the manifest. Nothinginteresting there. Let's try unicode strings:

$ strings -el moonstone.panel.exe.section-3.dmp
FluxScience Moonstone Vault Panel
MS Shell Dlg
Enter credentials below.
Let's make lemonade!

"lemonade" and "lemonade!" seemed to be good candidates, but it fails.Actually the password is "FluxScience". The content of the decrypted file is:

The solution is the MD5 hash of GLaDOS' login.

Flag is md5("FLUX-04644DBE65073E9E-0B3DD6B02EC5B9B1-F01864F663B0B371")--> b6c91946501f2b0e00cc0a0189dc7c2c

Thanks to the whole fluxfingers team for this really great CTF.

Hack.lu CTF 2011 Write-up : Scotty's last signal

$
0
0

Another writeup for the excellent Hack.lu 2011 Capture The Flag contest. This one was very unusual, based on a patched NES rom of Super Mario Bros 1.

Scotty's last signal

You might have heard about Montgomery Scott, the legendary chief
engineer of the U.S.S. Enterprise. What you probably did not know is
his passion for Video Games - especially really old classics. We
recently lost contact with his transport shuttle and we think you
should examine this old game file we recently recieved because he
might have just put a message into there. This would make sense if
he could not send a fully blown Space-Unicode message signal to
avoid attracting any Borg ships in the sector... (Borg usually are
very bad at video games)
 His passion for Beaming and Warping might be of interest for
your analysis.

The linked file is a NES rom image, based on the Mario 1 all-time classic game from Nintendo.

The first two levels have been heavily edited, adding numerous foes and traps.

The game features a secret passage in world 1-2, but the way to reach the warp zone seems to have vanished. So the first idea that comes to mind is that we have to finish the game the long way, and when done we should be rewarded with the secret passphrase.

However when we finish the game, the end is the classic one.

On a second try, and using the hint given in the challenge introduction, we see that the elevator to get to the warp zone is simply delayed, and that we can indeed reach this area with the right timing. There, the secret passphrase is displayed on the wall.

Here is the short version showing the challenge solution :

Please note that for more hex-oriented people, other solutions exists: [blog.bedford.org]

The video was done using fceux/tasedit

Download the rom https://ctf.hack.lu/files/mario

iOS 5 data protection updates

$
0
0

iOS 5 was released this week, and introduced some changes to the data protection features we described at HITB Amsterdam. This post highlights the updates made since iOS 4.

LwVM partition scheme

The GPT partition table used on iOS 4 was replaced by Apple's proprietary Lightweight Volume Manager (LwVM), previously only used on Apple TVs. This scheme was reversed earlier this year by Bluerise of the openiBoot project. This new partition table needs to be taken into account when computing the data partition logical block address (LBA), required to correctly decrypt raw disk images.

File encryption changes

With the release of Mac OS X Lion, the HFS content protection code (used in iOS) is now part of the open-source XNU kernel tree (code and headers).However in iOS 5, the CP_CURRENT_MAJOR_VERS version number is now 4, and the cp_xattr structure has additional padding between the key_size and persistent_key fields. More importantly, a change was introduced in the Initialization Vectors computation for data forks encryption. To compute the IV for a block in a file data fork, the input to the IV generator is now the block offset in the file fork (instead of the block LBA on iOS 4), and the resulting IV is then encrypted (AES128) with the "IV-key" to give the actual IV. The "IV-key" is unique per-file and computed using the following formula:

IV-key=SHA1(filekey)[:16]

Also, directories can now have their protection class set (through the F_SETPROTECTIONCLASS fcntl), and by default new files will inherit their parent folder protection class.

New protection classes

Two new protection classes for files were added in iOS 5:

  • NSFileProtectionCompleteUntilFirstUserAuthentication (class C, CLAS=3)
  • NSFileProtectionCompleteUnlessOpen (class B, CLAS=2)

The first class has the same semantics as the AfterFirstUnlock keychain accessibility setting that was available on iOS 4. Files that use it can only be accessed after the device has been unlocked at least once.The NSFileProtectionCompleteUnlessOpen class is more complex and allows the following:

  • keep protected files open even if the device becomes locked: simply keeps the file key in memory and does not block operations on the file descriptors
  • create protected files even if the device is locked (and some class keys are not accessible)

For this class, the persistent file key is secured using Elliptic curve Diffie Hellman over D. J. Bernstein's Curve25519. The following steps describe the creation of a file using this protection class:

  • file key randomly generated (used to encrypted file contents)
  • file public/private keypair (Curve25519) generated
  • shared secret computed using file private key and system keybag public key (PBKY)
  • shared secret is hashed (SHA1) to get wrapping key
  • file key is stored wrapped in the cprotect extended attribute, along with file public key
  • file private key is dismissed (erased from RAM), shared secret (and thus file key) can only be recomputed using the file public key and the system keybag private key (class key protected by passcode). The file key stays in memory as long as the file is open to allow access even if the device is currently locked.

It looks like this new class would be useful for securing pictures, which can now be taken at the lockscreen, but apparently only the Mail application uses this class to secure e-mails downloaded in the background.

Keychain

The keychain database has been modified significantly in iOS 5. Now, all item attributes are encrypted (account, service, etc.) instead of just the data field (kSecValueData). All the attributes are regrouped in a dictionary, serialized as a binary plist and stored encrypted in the data column. The operating mode of the AES cipher was also changed from CBC to GCM (Galois counter mode) with integrity protection. The database columns for attributes that were previously in clear-text are still there, but now only hold SHA1 hashes of the attributes values (to allow queries without having to decrypt the whole table).We updated the Keychain Viewer tool, which now supports iOS 3, 4 and 5.

Keybag

Keybags generated on iOS 5 now have the version attribute set to version 3. The only notable changes are the addition of the PBKY tag [STRIKEOUT:in the header] for asymmetric keys (holds the Curve25519 public key for the NSFileProtectionCompleteUnlessOpen class), and the KTYP tag for each class key: KTYP=0 means regular AES wrap key, KTYP=1 means Curve25519 [STRIKEOUT:private] key. Only class key number 2 (NSFileProtectionCompleteUnlessOpen) has KTYP=1.The passcode derivation algorithm was not modified since iOS 4.3.

Escrow records

Escrow records are property-list files that contains passcodes for escrow keybags (stored off-device, for instance in iTunes or on an MDM server). Those files are now protected with the new UntilFirstUserAuthentication protection class (the /var/root/Library/Lockdown/escrow_records/ folder has its protection class set to 3). This effectively blocks the "escrow keybag attack" that was possible on iOS 4, as an attacker cannot read those files without knowing the device's passcode, and thus cannot bypass the passcode using an escrow keybag.

Forensics tools update

We just updated our open-source forensics tools to support iOS 5. A few months ago we also added an adaptation for iOS of the HFS journal carving recovery technique presented by Aaron Burghardt and Adam J. Feldman in 2008. This technique can only recover a limited set of files (or even nothing at all), but the simple Python implementation of HFS+ provided (read-only) can be useful for experimenting with the file-system internals.

Retours sur le 28C3

$
0
0

Voilà un résumé des conférences auxquelles j'ai assisté. Les planches seront rendues disponibles au fur et à mesure. Les conférences sont réparties sur 3 salles en simultané, il a donc fallu faire des choix. Globalement, c'est une des meilleures conférences auxquelles j'ai pu assister, je ne peux donc que la recommander. Leur système de streaming vidéo en direct et la mise à disposition des vidéos juste quelques jours après l'évenement sont remarquables.

802.11 Packets in Packets (PIP)

Travis Goodspeed nous présente un nouveau type d'attaque exploitant le fonctionnement des couches physiques sans fil qui :

  • doivent gérer les phénomènes d'interférence : une onde dans les airs peut être brouillée (non détectable par le récepteur) lorsque plusieurs ondes se superposent
  • considèrent les données reçues comme "valides" dès lors qu'elles sont "cohérentes", c'est a dire qu'elles "ressemblent" à des données valides

En pratique, l'interférence crée plus souvent une série d'octets invalides consécutifs que des bits isolés invalides. Si le début du paquet est corrompu dans la couche 1, la machine à état (qui cherche le motif de synchronisation) cherchera à se synchroniser plus tard, éventuellement sur les données des couches supérieures, contrôlées par l'attaquant. Les données en couche 7 peuvent ainsi etre interprétées comme un paquet en couche 1 (d'où le terme Packet in Packet).

Ce type d'attaque est "standard compliant" car il n'y a aucun moyen de détecter si les données sont intègres. De plus, même si la vulnérabilité est au niveau de la couche 1, l'attaquant n'a pas besoin d'émetteur radio, l'attaquant peut etre physiquement distant (par Internet).

Notons tout de même que l'impact est limité :

  • fonctionne uniquement sur un accès Wifi non chiffré (WPA et WEP ne sont pas vulnérables)
  • fonctionne avec la technologie ZigBee (pour l'exemple, mais n'a pas de réelle application compte tenu des périphériques impliqués)

En tout cas, c'est une excellente présentation.

Data Mining, the Israeli Population Cencus

Yuval Adam nous présente son analyse des bases de données qui ont fuité en 1998, 2001, 2002, 2004 et 2006, permettant d'avoir les informations suivantes sur tous les citoyens israéliens entre 1948 et 2006 :

  • nom, prénom
  • date de naissance
  • statut marital
  • parents
  • adresse, n° de téléphone

D'autres informations peuvent être déduites en comparant les données des différentes années :

  • nouvel enregistrement : personne née ou immigrante (suivant la date de naissance)
  • mise à jour d'un enregistrement : changement de nom, n° de téléphone, adresse ou personne décédée
  • suppression d'un enregistrement : ??? L'auteur avoue ne pas avoir de réponse...Ceci sera laissé à l'interprétation du lecteur...

Les questions soulevées ensuite montrent la pertinence de sa présentation, et que l'interprétation des données récupérées n'est pas toujours facile... (base de données consistante, non modifiée ou sinon dans quelle intention ?, etc.)

Defending Mobile Phones

Karsten Nohl nous présente la suite (et fin dit-il) de 3 ans de travaux sur le sujet.

Il utilise pour cela les projets bien connus :

  • OpenBTS pour avoir une "fausse" antenne GSM
  • OsmocomBB pour installer un firmware customisé sur un téléphone à des fins de test

Trois types d'attaques sont développés:

  • imitation : sniffer ce qu'il faut pour être en mesure de se faire passer pour un téléphone cible
  • interception : sniffer une conversation et ce qu'il faut pour être en mesure de la déchiffrer
  • tracking : sniffer ce qu'il faut pour être en mesure de géolocaliser un téléphone cible

Voir GSM map pour les résultats obtenus, pour l'Europe seulement à l'heure actuelle.

Datamining for Hackers - Encrypted Traffic Mining (TM)

Stefan Burschka, très bon orateur, utilise une approche intéressante basée sur la physique et les maths pour tenter de récupérer des informations d'un flux chiffré, sans effectuer d'attaque sur le chiffrement à proprement parler. L'attaquant sniffe les paquets, puis les analyse et en déduit des caractéristiques sur le contenu.

Il prend l'exemple du flux de Skype (opaque) et développe sa présentation autour.

En prenant le slide 11 de sa présentation, correspondant à un graphe de tailles des paquets IP :

  • au début de la conversation, une charge plus importante de données transite, dû à un apprentissage afin d'optimiser la conversation
  • le flux est de type audio : il y a des pauses de discussions, mais en fait dans skype, il y a toujours du trafic, même lorsque personne ne parle
  • la taille minimale des paquets est 3 et correspond à un ping interne
  • la taille des paquets transitant dans un sens est plus grande que l'autre sens : le 1er interlocuteur parle plus que le 2nd

Il existe une fonction de transfert entre l'audio et le paquet IP.

Est-il possible de savoir si c'est un homme ou une femme qui parle ? Comment cela se voit sur un paquet ?

Est-il possible, considérant une phrase donnée dite par quelqu'un de reconnaitre la même phrase dite par quelqu'un d'autre ?

Deux personnes qui disent la même phrase ne feront pas varier la taille du signal ni la présence de signal / silence. Pour cela, l'auteur se base sur des modèles mathématiques (notamment le filtre Kalman). Ainsi, si on connait la phrase, on crée un modèle et on détectera cette phrase répétée dans 83% des cas sous certaines conditions...

Les moyens pour éviter cela serait d'ajouter du padding de taille aléatoire a tous les paquets.

Introducing OsmoCom GMR

Sylvain Munaut présente pour la 1ère fois le projet OsmoCom GMR dont le but est le développement d'une pile pour téléphone satellite (équivalent d'OsmoComBB pour le GSM). Il a commencé en juillet 2011 et actuellement il est capable de sniffer quelques trames de gestion (non chiffrées).

Il lui reste à :

  • comprendre l'algorithme de chiffrement A5/1 utilisé (différent de l'A5/1 du GSM)
  • comprendre le codec audio AMBE utilisé (propriétaire)
  • gérer la transmission
  • et plein d'autres choses...

Très prometteur.

Cellular protocols for mobile Internet

Harald Welte nous présente tous les acronymes utilisés dans les technologies GSM/GPRS/UMTS. Rentrer dans le sujet n'est pas simple, car de nombreux documents se référencent les uns les autres dans les standards 3GPP. Le but de cette présentation est justement de montrer cette diversité afin de ne pas se trouver bloqué lorsque l'on rentre sur le sujet.

L'auteur précise qu'il a laissé volontairement de côté la complexité de la couche 1 pour s'intéresser au reste. On retiendra les schémas contenant les piles réseaux des différentes couches utilisées pour le "control plan" (gestion du trafic) ou le "user plan" (les données à proprement parler) pour chacune des technologies GSM, GPRS, UMTS...

Reverse Engineering USB devices

Drew Fisher présente ici la méthode "classique" pour développer un driver pour un device USB. Que ce soit à l'aide d'un sniffeur USB matériel ou en utilisant les fonctionnalités de Windows/Linux ou d'un émulateur, l'auteur sniffe les communications du protocole propriétaire circulant au dessus de l'USB et détermine les champs du protocole qui sont souvent présents :

  • nombre magique : champ qui est répété régulièrement
  • champ "taille" : champ qui est suivi d'un nombre d'octets correspondant à sa valeur
  • numéro de séquence : champ qui est incrémenté
  • timestamp : champ qui est envoyé par un endpoint et qui "bizarrement" coïncide en différentiel avec l'évolution du temps

Il souligne que des outils de reverse engineering permettant de détecter ou d'aider l'homme dans cette tâche seraient utiles...

Au final, soit on arrive à comprendre le protocole en entier, soit on rejoue les bits non compris afin que cela "marche" !Enfin, il recommande d'utiliser la librairie libUSB pour accéder à l'USB depuis l'espace utilisateur pour prototyper le driver, ce qui évite de devoir le recharger après chaque recompilation.

Scada & PLC vulnerabilities

Tiffany Rad présente les résultats de 2 mois de recherche (dit-elle !) lui permettant à partir d'un accès au réseau de prisons de modifier le comportement du PLC afin :

  • de lui faire ouvrir les portes de prisons
  • et de faire en sorte qu'aucune alarme ne soit remontée

Le scénario envisagé est une clé USB branchée sur un ordinateur du réseau, déclenchant l'infection. La 1ère réaction des prisons fut de dire que ce n'était pas un problème car leur réseau n'est pas relié à Internet, même si en pratique il s'est avéré qu'une grande quantité l'était bel et bien...

Le coût pour réaliser une telle attaque est de $500 pour le matériel + $2000 pour le logiciel (également présent sur Internet...) et finalement le plus difficile fut la recherche de la bonne version du logiciel (parmi environ 80 versions différentes...)

Une excellente conférence !

Some feedback from the 28C3 conference

$
0
0

Here is a summary of the talks I attended during CCC. The talks were given in 3 simultaneous tracks, so some choices had to be made. All in all, this is one of the best conferences I attended and I can only recommend it. The slides will be made available little by little. The live video streaming and the video downloads, ready only a few days later, are excellent resources to watch.

802.11 Packets in Packets (PIP)

Travis Goodspeed shows us a new class of attack. He exploits the way wireless physical layers work. These attacks are possible because:

  • wireless physical layers need to handle interference phenomenon: a wave in the air can interfere with others (so that the receiver cannot decode either correctly)
  • the receiver considers received data to be "valid" when they are "consistent", i.e. when they "look" like valid data

In practice, an interference creates more often invalid consecutive bytes than invalid isolated bits. If the (beginning of the) layer 1 of the packet is corrupted, the state machine (looking for the synchronization pattern) will look for the synchronization bit pattern later, which maps to the upper layers that are controlled by the attacker. Consequently, part of the data of the layer 7 can be interpreted as a layer-1 packet ("Packet In Packet").

This type of attack is "standard compliant" because there is no way to check the packet's integrity. Moreover, even if the vulnerability is at layer 1, the attacker may not need any radio transceiver, and can be physically distant (e.g. from the Internet).

Applications are quite limited:

  • it only works on an open WiFi spot (without encryption: WPA or WEP are not vulnerable)
  • it also works with the ZigBee technology (but there is no real-life application due to the peripherals involved)

All in all, it was an excellent talk.

Data Mining, the Israeli Population Cencus

Yuval Adam describes his analysis on the databases that leaked in 1998, 2001, 2002, 2004 and 2006, unveiling information on Israeli citizens from 1948 to 2006.

  • last name, first name
  • date of birth
  • marital status
  • parents
  • address, phone number

Other information can be inferred when comparing databases from one year to another:

  • new record: person who is born or immigrant (depending on his/her date of birth)
  • record updated: last name updated, phone number updated, address updated or deceased person
  • record deleted: ? The author confess not having any response to that...This is left to the interpretation of the reader...

His presentation shows that data interpretation is not always an easy task... (with such a leak, is the database legitimate, or was it tempered with ? if so, why ?)

Defending Mobile Phones

Karsten Nohl details his 3-year continuing work on the subject.

He uses the well-known projects:

  • OpenBTS to create a "fake" GSM antenna
  • OsmocomBB to flash a customized firmware on mobile phones

Three type of attacks are detailed:

  • impersonation: sniffing enough data in order to spoof the targeted phone
  • interception: sniffing a conversation and enough data to be able to decrypt it
  • tracking: sniffing enough data to geolocalize the targeted phone

See GSM map for results (European only for the moment).

Datamining for Hackers - Encrypted Traffic Mining (TM)

Stefan Burschka uses an interesting approach based on physics and mathematics in order to get information on a ciphered stream, without trying to decrypt it.The attacker sniffs packets, then analyzes them to deduce some characteristics of the content.

He takes Skype as an example because from the outside it is an opaque blob. He develops his presentation on this product.

Slide 11 of his presentation corresponds to a graph of IP-packet sizes:

  • there is an important load of data at the beginning, due to Skype self-learning functionality. It helps optimizing the following conversation
  • the stream type is audio so there are discussion breaks. However, in Skype, there is always some traffic, even when nobody talks
  • the minimal packet size is 3 and corresponds to an internal ping
  • the packet size in one way is more important than the other way. It means the 1st person talks more than the 2nd

A transfer function exists between the audio stream and IP packets.

Is there a way to infer if this is a man or woman that talks? How can we understand that from a packet?Considering a phrase from person A, is there a way to recognize this same phrase from person B?

Two persons saying the same phrase do modify neither the signal size nor the signal/silence presence. To do so, the author uses mathematical models (especially the Kalman filter). Consequently, if we can guess the phrase, we can create a model and we will be able to detect this sentence in 83% of cases under certain conditions...

In order to avoid that, a randomly generated padding should be added.

Stefan Burschka was a very good speaker.

Introducing OsmoCom GMR

Sylvain Munaut's talk deals with the new OsmoCom GMR project. The goal of this project is to develop a stack for satellite phones (as OsmoComBB is for the GSM). It started in July 2011 and it is currently possible to sniff some management frames (not ciphered).

What needs to be done next:

  • understand the A5/1 cipher algorithm (not the same as the GSM A5/1)
  • understand the AMBE audio codec (proprietary)
  • handle the transmission
  • etc.

Very promising.

Cellular protocols for mobile Internet

Harald Welte shows us the acronyms used in all GSM/GPRS/UMTS technologies. To get started with the subject is not an easy task, because of the many documents from the 3GPP standard that cross-reference each others. The goal of this presentation is precisely to show this diversity in order to help researchers get started with the subject.

The author specifies that he deliberately left aside the complexity of layer 1 in order to detail the other layers. We will remember the schemes containing the network stacks with all layers. They are detailed for the "control plan" (traffic management) as well as the "user plan" (data) for the GSM, GPRS and UMTS technologies...

Reverse Engineering USB devices

Drew Fisher demonstrates a classic method to develop a driver for a USB device. Using a hardware USB sniffer or the functionality of Windows/Linux, the author sniffs the proprietary communication protocol on top of the USB protocol. He determines the following fields:

  • magic number: field that is often repeated
  • length: field that is followed with a byte count corresponding to its value
  • sequence number: field that is incremented
  • timestamp: field that is sent by an endpoint and "weirdly" coincides with the time evolving

He underlines that reverse engineering tools allowing to detect or help humans to do this task would be useful...

In the end, we either understand the whole protocol or we are able to replay the bits that we did not understand in order to make it "work"!At last, he advises to use the libUSB library to access USB from userspace while prototyping the driver. It serves to not have to reload the driver every time you recompile your code.

Scada & PLC vulnerabilities

Tiffany Rad shows the results of a 2-month research period (!). Using an arbitrary access to the network of a prison, she is able to modify the behavior of a prison PLC in order to:

  • make it open the prison's doors
  • without any alarm being triggered

The scenario we consider is a USB stick plugged into a computer of the network, triggering the infection. The first reaction of prisons was to say that there is no problem since their network is not connected to the Internet. However, in practice, they discovered several cases where it was actually connected...

To get this attack working, one only need $500 for the hardware + $2000 for the software (also available on the Internet...) Finally the most difficult part was to get the right version of the software (among almost 80)

Very nice conference, I hope to get back there next year !

HTC unlock internals

$
0
0

Since the end of 2011, HTC allows unlocking its Smartphones' bootloaders. Before that, HTC controlled every updates and packages that were installed on their devices. Users can now unlock their device manually in order to install any installation image (commonly called "ROM" in Android jargon) on their Smartphone. This article describes the internal aspects behind this unlock procedure.

Main aspects

The unlock procedure takes place in 2 steps. For each step, the user has to put its mobile phone in bootloader mode (HBOOT) and to execute commands from the computer.

First step consists of asking a blob from the device.

# fastboot oem get_identifier_token

We get a blob that needs to be submitted to the HTC Dev website.

<<<< Identifier Token Start >>>>
6B08571CFA5165E6DD651B61E54C21CA
E831316228F61EAD276FA3B5C09D1FF0
427E42252BD24461130468DFAFEC344D
F13F5A83AA732CA9678B8AF453EDA69C
319A8C0BF1887C87DDC25B7D7FC16C41
0791099A245FDE2B54AF869E2D3F13F3
5B0F8982C5BA528445ABE98FC580EFAB
D735C19C752F679F2C4C5F98E4A1F063
D4D85FFA64FEC3C11CA5971188211502
B3098649EAE32FB28FC5A50DCF20B50F
536BBF0540842672D55E0DD8A2FFA353
3694DFEC8661C2E9CB6D4BD4E3299DE0
B7BC2EC9B63DE42D355C4C49308E9348
543A4FD687245D6284421593D44C3D33
46E6738AFB76248A373D1CC1027095C9
6754DC0CB0686C3FEB6FDA61E64FB308
<<<<< Identifier Token End >>>>>

In return, HTC will send us the "Unlock_code.bin" file by email. The second step consists of using this file to unlock the Smartphone.

# fastboot flash unlocktoken Unlock_code.bin

The phone will be unlocked only if the "Unlock_code.bin" file is valid.

Internals

Let us analyse the internal mechanisms. The following values are recovered during the first step.

  • IMEI: 123456789012345
  • Serial number: SH0CERT12345
  • Model ID: PC10*****
  • CID: 11111111
  • 4 DWORDs (unidentified)

These values are concatenated and padded to get 256 bytes (we will call that "PhoneIDs")

00000000  00 31 32 33 34 35 36 37  38 39 30 31 32 33 34 35  |.123456789012345|
00000010  30 53 48 30 43 45 52 54  31 32 33 34 35 50 43 31  |0SH0CERT12345PC1|
00000020  30 2a 2a 2a 2a 2a 31 31  31 31 31 31 31 31 45 01  |0*****11111111E.|
00000030  00 53 12 34 56 78 47 90  41 58 29 7f ad 4a 7f 60  |.S.4VxG.AX)..J.`|
00000040  e1 3c 12 83 5d c0 9c 74  30 a4 79 aa 41 68 58 cb  |.<..]..t0.y.AhX.|
…
000000f0  1b 21 48 0b f5 15 39 0a  a5 26 f2 09 78 c5 e6 b7  |.!H...9..&..x...|
00000100

Then, they are encrypted using the RSA-OAEP encryption scheme with HTCs' public key. The resulting "blob1" is what it figures between the tags <<<<< Identifier Token >>>>> and what should be sent to the HTC Dev website.

htc_unlock_get_identifier_token.png

The second step consists of validating the "Unlock_code.bin" file.

At first, it verifies the signature by using HTCs' public key.Secondly, it computes the hash value (using SHA2 algorithm) of a shortened version of the "PhoneIDs". This shortened version of the value "PhoneIDs" is the concatenation of IMEI, Serial number, Model ID, CID, and 4 DWORDs, but without the padding.

The resulting hash value is being compared with the hash value that results from the file's signature verification. If they match, the unlock procedure is granted by the mobile device.

htc_unlock_Unlock_code.png

Source code for these steps is available in github.

Conclusion

The HTC unlock procedure is quite simple. HTC is the only one to have the private key and can create the "Unlock_code.bin". So they can stop at any time the procedure if they want to. However, if you get an "Unlock_code.bin" for a given device, you will always be able to unlock it.

The unlock procedure will allow "fastboot flash" commands and reduce the security of your devices, since it will be possible to flash a custom recovery and mount your original data partition, so do it at your own risks.

For security reasons, the unlock procedure erases the data partition. Even if an attacker gets a device (protected with a passcode) and ask HTC to provide him this "Unlock_code.bin" file, he will not be able to access original data.


Some feedback from the HITB 2012 conference

$
0
0

Recently, HITB 2012 took place in Amsterdam (Okura Hotel) and some of us attended.

Impressed by the quality of the conference, we will try to summarize here all presentations that we attended.Also, Sogeti NL organized three challenges (Web application, WiFi and Social Engineering).

Windows RunTime

Sébastien RENAUD and Kévin SZKUDLAPSKI of Quarkslab presented a new feature in Windows 8 comparing it with Windows 7.

Indeed, Microsoft introduced a new interface: 'Metro'. Metro enables users to download applications in the Windows store. Each application is checked (API and DLL Characterics), and its signature is controlled. But the API list checking has its limits, if we retrieve the API address dynamically.

Metro provides a new way to secure users from malicious applications offering only one way to download applications (from Windows Store which will check these applications), and providing a certain level of isolation for each of them thanks to the new sandbox concept 'AppContainer'.

Killing a Bug Bounty Program

Curious about the title, we attempted this talk presented by Itzhak Avraham (Founder of zImperium) & Nir Goldshlager (Senior Researcher in zImperium).

Here were presented ways to find bug in Google services. As we know many Bug bounty programs exist to encourage security researchers to find bugs in softwares to help firms making more secure programs. Thereby, bugs finding sometimes looks like a race against the clock. What these two researchers did, is to track services and acquisitions of Google services to test it.

They shown that some mitigations techniques prevented from XSS, but there was still some possible ways using the Error message, or non-suspected functions that finaly weren't protected. Itzhak Avraham and Nir Goldshlager tried also to attack acquiered services by Google, and it got some interesting results. Indeed, acquiered services are sometimes not checked, or not enougth and sometimes also contains vulnerable & exploitable applications, to gain much more accesses.

Security threats in the world of digital satellite television

Adam Gowiak (from Security Exploitations) has presented ways to attack the digital satellite platforms. Digital satellite TV set-top-box devices are not so well known platforms to attack because of the dedicated hardware and software. Connected to the internet, they provide: IPTV, Video on Demand, remote DVR, Internet radio, and so on.

Among these vulnerabilities, it was possible to perform a remote attack against the network, satellite set-top-box and put a persistent malware code. In addition, a vulnerable set-top-box allows a malicious user to capture and share satellite TV signal as he wants to (without paying) after getting root access on the box.

Others attacks were presented like privilege elevation in Carbo set-top-box (in addition to Hermes), persistent backdoor installation, message spoofing on XML files, Hermes System Software Upgrade keys which are broadcasted in plain-text, replay attack against PUSH VOD, and so on.

As we could see, many security issues exists in set-top-box, mainly because of the bad implementations. But these infrastructures that are also exotic, and are not convenient at all because of some changes made, especially on the web browser configurations and so on. This talk gave a good overview of satellite TV set-top-boxes security, and attacks that could be performed in the same ways with boxes in other countries.

Corona Jailbreak for iOS 5.0.1

Finally, we could not miss the iPhone talks from the iOS jailbreak guys (Joshua Hill, Cyril, Nikias Bassen, David Wang to quote only a few).

They first explained all the security measures that Apple takes to protect the integrity and confidentiality of their devices. Then they detailed the techniques used to jailbreak the latest devices using Corona. This jailbreak was released before HITB but has finally been well-explained in this presentation.

The racoon (VPN binary) format string attack (still there in 2012!) allowed them to execute code, but they needed an additional kernel vulnerability (the HFS+ kernel exploit) in order to patch the kernel memory and disable all the security checks at runtime.

They use the already well-known bootrom vulnerability to inject the jailbreak. The injected files concern the racoom binary and allow to get code execution at each startup. ROP (Return Oriented Programming) is needed since everything that get executed needs to be signed.

The kernel vulnerability allows them to patch the kernel memory since everything is RWX.

They are able to bypass the ASLR at each startup using a launchd flag (DisableASLR) that will probably disappear.

Absinthe Jailbreak for iOS 5.0.1

There is no public bootrom or bootloader vulnerability for the last devices (iPad2/3 or iPhone 4S) so they are not able to decrypt the firmware files. Consequently, they can't decrypt the kernel and analyze it. Since no one can exploit a target without knowing it, they needed to get the kernel dump at runtime.

To inject the jailbreak, they use a vulnerability in the regular Backup mechanism (with iTunes) and the racoon binary. Note: It will be interesting to see if it is possible to do it remotely using the new iCloud services.

They also needed a way to bypass ASLR because they could not use yet the Disable ASLR flag. They used the regular crash report from Apple to get base addresses information and compute the right ROP payload to execute on the device. They did that from the computer jailbreak tool directly using the regular iTunes procedure and an otherwise unused NULL pointer vulnerability in MobileBackup.

It was really great having all the jailbreak teams in one place!

Sogeti Challenges

Sogeti Netherland organized three different challenges: Web application, WiFi, and Social Engineering.

We focused on the Social Engineering challenge. We had to fill a form: we got to find a lot of phone numbers to call and as much information as possible to help us getting further information. The funny thing was that we got only 'Nederlander' company to call.

After that, we got to call the company with the presence of Sogeti Staff, and ask them about the Operating System they use, OS version, if they use adobe reader, and corresponding version. There was also some URLs that we could make them visit (pdf, a page with flash, and so on) that could gave us much more points.

The real challenge was to keep the speaker on the phone, being as much understandable as possible (not as simple when you are talking to people not specialized in computer areas). What was really interesting is the fact that some (non-technical) people were really kind and helpful and gave us all kind of information (browser, operating system, e-mail client) and were ready to give us their respective versions but did not know where to look for that. Instead, they proposed to give us the IT support...

To sum things up, great conference and we hope to get there next year!

Viewing all 229 articles
Browse latest View live