📚 OpenRCE is preserved as a read-only archive. Launched at RECon Montreal in 2005. Registration and posting are disabled.








Flag: Tornado! Hurricane!

 Forums >>  Target Specific - General  >>  Finding Diffie Hellman P and G keys in a binary.

Topic created on: April 23, 2009 13:27 CDT by claymore1977 .

Greetings all.  I am new to the realm of Debugging, Disassembly, ASM code, and RCE in general.

I have a short turnaround project that needs to be done quickly and I'll be the first to admit I am in way over my head.  I am wondering if I could solicit some help from you all since this seems to be a good collection of expertise.

I have a Application that communicates to a server in the standard 1Server/ManyClients configuration.

I have disassembled this app with OllyDbg and IDA and have determined that it is linked against openSSL-0.9.6d.  I have downloaded the source for openSSL and am moderately familiar with it.  I also found references to Diffie-Hellman in the disassembly, so I believe its using DH for key generation and DES for the crypto.

The problem is that the server software has been lost and I need a way to start reverse engineering the network protocol.  I am at a loss as to how to find the p and g keys inside the binary.

I am thinking I have two basic options:
1)  Extract the DH keys from the binary (which I am having a lot of trouble learning to read assembly)
-or-
2) Try to inject some code into the binary so as to bypass the actual encrypt/decrypt routines, forcing the binary to send and recv unencrypted (aka original) data.

Can anyone help me with ideas?

  tagetora   April 23, 2009 15:59.22 CDT
Just a few thoughts :)

Are you sure p and g are hardcoded into the binary? Maybe the lost server had p and g or even they're generated at runtime.

Tips for reversing network protocols:

- Look for all references to socket operations: send, recv, sendto and recvfrom.

- Then look near the sockets for functions that seem to process data and place hooks at start & end of those functions. That way you can see which encryption and encodings are being used before sending the data.

- Try to code some dummy socket app that can act as fake server (I'm sure you already have one, but just in case)

And about the options... if it's not so hard to patch the binary and skip the encryption, do it. It will save you a lot of troubles while debugging.

Well, as you see it's not a magical recipe but, hope it helps ;D

  huku     April 23, 2009 19:55.44 CDT
More thoughts... :-)

- Even if you manage to hook the encrytpion/decryption routines, you will only solve 50% of your problem since the server part will still use encrypted data.

- Let's assume that the DH params are hardcoded in the binary, then it is highly possible that your application makes use of a code like the one below:


in = BIO_new(BIO_s_mem());  /* or BIO_s_file() if the params are stored in a file! */
...
BIO_set_mem_buf(in, address_of_hardcoded_DH_params, 0);
...
dh = d2i_DHparams_bio(in, NULL);  /* For ASN1 encoded DH params */
...
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);  /* For PEM encoded DH params */


This is "the OpenSSL way" of loading stored DH params. If this is the case, then just add a breakpoint after d2i_DHparams_bio() or PEM_read_bio_DHparams() and read the contents of dh. You can also hook these functions to make them save the params in a file.

- Another idea that might be helpful is to hook or break at DH_compute_key(). This will help you find the shared DH stuff (3rd argument) and the negotiated secret (1st argument) :-) Usually DH parameters are created runtime using DH_generate_parameters() and it is quite possible that your application doesn't have harcoded DH stuff. Even if this is the case, DH_compute_key() will give you all the hints that you need in order to decrypt the network traffic.

Cheers & good luck!

  claymore1977     April 24, 2009 12:55.41 CDT
Thanks for the reply!  Let me answer these in the order you posted:

I am relatively sure they are hardcoded since I have looked at some captured packet logs from a while back.
The very first client/server exchange is 100 bytes each way.  The first 4 bytes equate exactly to an integer value of 96.  To me, this is the Public Key exchange happening.
After that, its all gibberish.

My grasp on the DH key generation routine is that the Public Keys (both A and B) have to be based upon the same p and g values.  If those values are 'generated' at runtime, and the first 100 bytes exchanged are not the p and g values....then how can it work?  If the p and g values were server generated, then there should've been at least 2 unencrypted exchanges.

As for 'placing hooks' what do you mean... breakpoints in ollydbg?

I do have a simple proxy app and an echo app ready, just need those bloody p and g keys.

As for 50% of the problem... well maybe.  If the server software I code from scratch has the p and g keys in it, then its a matter of picking a random private value, calculating Public Key B and sending B to the client.  This way both client and server arrive at Secret Key (K).

I have been looking for any/all function calls from the openSSL code.  I will admit that I am having a seriously difficult time relating C source code to Assembly.  Got any hints for matching function signatures between the two?

As for using ollydbg and examining data in the registers... still learning.  Very difficult for me.

  itsme     April 25, 2009 00:22.59 CDT
dh key generation is not trivial, and time consuming, often a key known to be good is used, like those listed in http://www.ietf.org/rfc/rfc3526.txt .

maybe you can search for those in your binary?

  huku     April 26, 2009 10:45.31 CDT
> The very first client/server exchange is 100 bytes each way.  The first 4 bytes equate exactly to an integer value of 96.  To me, this is the Public Key exchange happening.

Ok I think this is not a coincidence :-) Maybe the 96 bytes are those that compose the BIGNUMs p and g. Take a look at the declaration of the bignum_st structure in the OpenSSL source and also notice that g is usually a very small prime e.g 2, 5, 7 etc, so, g is probably one byte :-)  

> As for \'placing hooks\' what do you mean... breakpoints in ollydbg?

Nope, hooks != breakpoints. The term 'hooking' means interception of control flow. For e.g you can hook function A so that function B is called instead. When B returns, control is passed to A. There are many techniques for this purpose, just google it :-)

> I have been looking for any/all function calls from the openSSL code.  I will admit that I am having a seriously difficult time relating C source code to Assembly.  Got any hints for matching function signatures between the two?

The OpenSSL code is quite complicated, so, take your time studying it.

Note: Registration is required to post to the forums.

There are 31,328 total registered users.


Recently Created Topics
[help] Unpacking VMP...
Mar/12
Reverse Engineering ...
Jul/06
let 'IDAPython' impo...
Sep/24
set 'IDAPython' as t...
Sep/24
GuessType return une...
Sep/20
About retrieving the...
Sep/07
How to find specific...
Aug/15
How to get data depe...
Jul/07
Identify RVA data in...
May/06
Question about memor...
Dec/12


Recent Forum Posts
Finding the procedur...
rolEYder
Question about debbu...
rolEYder
Identify RVA data in...
sohlow
let 'IDAPython' impo...
sohlow
How to find specific...
hackgreti
Problem with ollydbg
sh3dow
How can I write olly...
sh3dow
New LoadMAP plugin v...
mefisto...
Intel pin in loaded ...
djnemo
OOP_RE tool available?
Bl4ckm4n


Recent Blog Entries
halsten
Mar/14
Breaking IonCUBE VM

oleavr
Oct/24
Anatomy of a code tracer

hasherezade
Sep/24
IAT Patcher - new tool for ...

oleavr
Aug/27
CryptoShark: code tracer ba...

oleavr
Jun/25
Build a debugger in 5 minutes

More ...


Recent Blog Comments
nieo on:
Mar/22
IAT Patcher - new tool for ...

djnemo on:
Nov/17
Kernel debugger vs user mod...

acel on:
Nov/14
Kernel debugger vs user mod...

pedram on:
Dec/21
frida.github.io: scriptable...

capadleman on:
Jun/19
Using NtCreateThreadEx for ...

More ...


Imagery
SoySauce Blueprint
Jun 6, 2008

[+] expand

View Gallery (11) / Submit