CodeGate 2009's Challenge 18 - Diffie-Hellman parameter tampering case study

1 Introduction

Last week I joined team CLGT to take part in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CodeGate 2009 organized by BeistLab. There's 21 challenges. This post is about challenge 18 which, IMHO, is one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most interesting. You can download full report from CLGT here.

There was only two teams could nail #18, and, unfortunately, we were not one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. We were very close, just minutes away, from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 final solution, but could not manage to solve it before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contest ended. Anyway, we're writing this writeup because we like it.

This is a cryptography challenge. The objective is to decrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 communication between a server and a client, which play a protocol involving RSA digital signature algorithm [1], Diffie-Hellman Key Protocol Agreement [2], and AES block cipher [3].

Section 2 describes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol and its setting in detail. Section 3 discusses some vulnerabilities of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol. Section 4 describes how we nail it. Section 5 discusses some ways to fix it. Section 6 concludes.

2 The Protocol

As we said in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 introduction, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re's a client and server (in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 challenge, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are port 9328 and 9000, respectively) who talk to each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r using a protocol. The interesting part is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y don't talk directly, but through a middle man who is, you guessed it, us.

The first thing we want to do is to understand cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol, so in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 beginning, we just pipe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data back and forth between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. As far as we know, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol includes four steps that consisting of seven numbers and two messages:

2.1 Step 1 – client sends his RSA public-key (e & n) to server

The client starts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol by sending two numbers to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. At first, to be honest, we thought cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first ten bytes number, which is a prime, is p in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DH protocol. After a very long try-and-error process, we concluded that this prime is in fact e in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client's RSA public-key. If it is e, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second number, which is 38 bytes, should be n. We confirmed this cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory in step 3.

The client starts cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol by sending two numbers to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. At first, to be honest, we thought cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first ten bytes number, which is a prime, is p in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DH protocol. After a very long try-and-error process, we concluded that this prime is in fact e in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client's RSA public-key. If it is e, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second number, which is 38 bytes, should be n. We confirmed this cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory in step 3.

These two numbers are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only static numbers of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol, which makes sense since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are client's RSA public-key. All ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r numbers are somewhat random at first sight.

2.2 Step 2 – server sends DH's g, p, and A = g^x (mod p) to client

After receiving two numbers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client in step 1, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server sends back three numbers. This step is where we were stuck. We knew that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se 3 numbers are DH's parameters but didn't know which was which. The very reason is none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m was a prime! At first we thought cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were encrypted by client's RSA public-key, so we tried to decrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, but still no prime appeared. Then somebody in #codegate suggested us looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of each number. And until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n, after wasting hours trying ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ories, we recognized cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 obvious.

The second number was always greater than two ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r numbers. As g and A are both less than p, so we guessed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second number must be p. Of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two remained numbers, to know which was g and which was A, we tried to change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, and analyzed what we saw in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next step. Base on our analysis, which makes sense when you see what happened in step 3, we concluded that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first number is g, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 third number is A respectively.

To recap, in this step, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server sends DH's g, p, and A in that order to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client.

2.3 Step 3 – client sends B = g^y (mod p) and B's RSA signature to server

After receiving three numbers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server in step 2, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client sends back two numbers. At first, we didn't know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 role of each number. Once again after a very long try-and-error process, we saw cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are related to each ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. The second number is RSA signature of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first number which is signed by using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client's public-key seen in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first step.

So what is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first number? As you know, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are four public parameters in DH key agreement protocol, and we already saw three numbers in step 2, so this number should be B = g^y (mod p).

In summary, in this step, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client sends DH's B and B's RSA signature to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server.

2.4 Step 4 – server and client starts exchanging AES encrypted data

After receiving two numbers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client in step 3, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server checks cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RSA signature and returns a “SIGNATURE MISMATCH” message and terminates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol if it sees, you know, a modified B. Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sever and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client starts exchanging data by sending one 16 bytes message back and forth.

The data is of course encrypted using a 128-bit block cipher which we guess is AES. What is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key? As you know, after completing step 3, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DH protocol is done. In ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r words, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client and server can both derive a shared secret which is A^y = B^x = g ^(xy) (mod p). They use this shared secret as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key to encrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir data using AES.

In summary, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol consists of 4 steps which use RSA to verify data, DH to derive a key, and AES to encrypt messages.

3 Protocol Vulnerabilities

As you may already see, this protocol has several weaknesses. Below we show two major vulnerabilities which helps us cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 middle man to decrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages exchanged between client and server.

3.1 Weak RSA public-key's n

The n part of client's RSA public-key is just 38 bytes = 304 bit which took us only seconds to factor it into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 product of two primes:

26997494888422756793800618646853986321 = 5150852573609963923 * 5241364318354314827

As you know, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security of RSA is totally broken when n is factorizable like this, since we can easily compute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client private-key:

e = 3598711421, d = 15264128287770523976569188681594873497

Even if n is large enough, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re's still anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r attack vector by replacing n with smaller numbers. Remember we are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 trusted man in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 middle!

3.2 Man-In-The-Middle Attacks against DH protocol

There's a lot of attacks against DH but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most powerful one is man-in-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-middle attack [5]. It has been known for years that an active attacker like us, capable of removing and adding messages, can easily break cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core DH protocol. By intercepting A = g^x and B = g^y and replacing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m with g^x' and g^y' respectively, we can fool client and server into thinking that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y share a secret key. In fact, server will think that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 secret key is g^xy' and client will believe that it is g^x'y which are both known by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attacker [4] . As a result, if we replace A with 1, and B with 1, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret will equal to 1.

By exploiting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se two vulnerabilities, we can set cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret to whatever value we want, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore, decrypt subsequent messages.

4 How We Nail This Challenge

As we said in section 3, we nail this challenge by deploying a man-in-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-middle attack against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DH protocol.

In step 2 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol, when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server sends its DH's g, p and A parameters to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client, we intercept and replace cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 third number with 1, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 modified numbers to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client.

In step 3 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol, when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 client sends its DH's B parameter to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server, we intercept and replace it with 1. We can easily compute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RSA signature which is 1. Then we send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 modified number and its signature to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server. Now we know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret which, as stated section 3, equals to 1.

This shared secret is used as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key to encrypt subsequent messages using AES. But how? This is where we were stuck and lost 400 points :(. Since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret is only one byte but AES requires a 16 bytes, we thought that we must do some calculation on it before actually use it to decrypt data.

At first, we tried to SHA1 cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret, and used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first 16 bytes output as AES key. This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key derivation method recommended in DH Key Agreement Protocol's RFC [2]. But Alex told us not to do that. So we tried ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r methods, but, however, due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lack of experience and time, we didn't get it until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contest was over. It was just 5 minutes :(. The solution is simply to zero padding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 shared secret, to make it become something like '\x01' + '\x00' * 15, and uses that as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 key to decrypt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages. Run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attached Python script, and you'll see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages in cleartext.

5 How To Fix The Protocol

The first obvious way to fix cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol is...to forget it. Don't ever use it in production. Don't try to re-invent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wheel, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re's existed secure protocols for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same purpose, for example TLS/SSL. But if we are forced to use this protocol, how should we modify it so that it becomes more secure?

The first thing we want to do is to ensure that RSA public-key's n number is large enough. After receiving n and e, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server must test to see if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y meet cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requirements of RSA cryptography standard [1]. The server must terminate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y don't. This will prevent somebody forging cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signature in step 3.

For suggestion on how to use DH protocol securely, see [5].

6 Conclusion

At some point in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CodeGate2009, Alex sighed and said that “new school is weak at crypto”, and we agree. We definitely need to learn more. But, at least, by going this far, and writing such a detail report, we deserve some points, don't we?

7 Acknowledgement

Alex thank you so much for giving this gift to us. It was very nice of you to answer us many questions about this challenge. We're looking forward to seeing more cryptography challenges from you and BeistLab. Thanks somebody at #codegate for suggesting us to look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of each number in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 step 2 of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol.

8 Reference

[1] RSA Cryptography Standard

ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf

[2] Diffie-Hellman Key Agreement Method

http://www.ietf.org/rfc/rfc2631.txt

[3] Advanced Encryption Standard (AES)

http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf

[4] Handbook of Applied Cryptography

http://www.cacr.math.uwaterloo.ca/hac/

[5] Security Issues in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Diffie-Hellman Key Agreement Protocol

http://crypto.cs.mcgill.ca/~stiglic/Papers/dhfull.pdf

Comments

This comment has been removed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 author.
Hi Thai, len trang http://hacking.beist.org/ thay nhom cua Thai hang 9, khong biet nhom co du duoc final round ko? Mong nhom co duoc ket qua tot nhat co cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365.
Anonymous said…
Em thấy cái này thiếu các bước cơ bản của một giao thức bảo mật như xác thực, và integrity.

Client gửi PU(n,e) cho server giả sử từ đầu.
Server gửi cho client có mã hóa thông tin gồm xác thực với MAC không?
Em thấy có rất nhiều giao thức dựa trên Diffie Hellman như EKE, SPEKE.
Anonymous said…
This comment has been removed by a blog administrator.
Anonymous said…
我的站點介紹:情趣用品,情趣用品,情趣用品,情趣用品情趣用品,
情趣用品,
情趣用品,
情趣用品,
情趣用品,
情趣用品 來看看 賣克

室內設計這是我找過最好的一家唷!

室內設計這家很好!

保健食品代工,素食膠囊,順傑

你需要買雨傘,這裡有一把優良的雨傘讓你的,制服不會被淋濕唷!制服
Unknown said…
awesome!
Nathan said…
You are an interesting guy!

A Lê Hồng Phong alumni, 1979