# [Cryptohack] Static Client - Static Client2
## 1. Static Client

Nhìn vào ảnh thì mình có thể đoán được đây là dạng tấn công Meet-in-the-middle và Bob với ALice đang sử dụng giao thức trao đổi khóa Diffie Hellman:
* Alice và Bob thỏa thuận 1 số module P và g
* Alice chọn một số nguyên bí mật A, sau đó gửi cho Bob A = g^a^ (Mod P)
* Bob chọn một số nguyên bí mật B, sau đó gửi cho Alice B = g^b^ (Mod P)
* Alice tính toán key = B^a^ (mod p)
* Bob tính toán key = A^b^ (mod P)
* Giờ Alice và Bob đã có chung Key.
Chúng ta biết rằng sau khi mình gửi parameters (p,g,A) thì Bob sẽ gửi lại B = g^b^ (Mod P). Vậy nếu mình thay g = A, p giữ nguyên và A là số gì cũng được thì Bob sẽ gửi lại A^b^ (mod P) và đây chính là khóa mình cần tìm :))
Có được khóa thì mình chỉ cần giải mã theo đúng trình tự của AES.mode CBC là ra được flag :triangular_flag_on_post:
solve.py
```python=
import json
from pwn import *
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
def is_pkcs7_padded(message):
padding = message[-message[-1]:]
return all(padding[i] == len(padding) for i in range(0, len(padding)))
con=remote('socket.cryptohack.org',13373,level='debug')
con.recvuntil(b'Intercepted from Alice: ')
alice=json.loads(con.recvline())
p_hex,g_hex,A_hex=alice['p'],alice['g'],alice['A']
con.recvuntil(b'Intercepted from Bob: ')
B_hex=json.loads(con.recvline())['B']
con.recvuntil(b'Intercepted from Alice: ')
content=json.loads(con.recvline())
iv_hex,enc_flag_hex=content['iv'],content['encrypted']
to_bob={"p":p_hex,"g":A_hex,"A":'0x1'}
con.sendline(json.dumps(to_bob))
con.recvuntil(b'Bob says to you: ')
shared_secret=int(json.loads(con.recvline())['B'],16)
con.recvline()
def decrypt_flag(shared_secret: int, iv: str, ciphertext: str):
# Derive AES key from shared secret
sha1 = hashlib.sha1()
sha1.update(str(shared_secret).encode('ascii'))
key = sha1.digest()[:16]
# Decrypt flag
ciphertext = bytes.fromhex(ciphertext)
iv = bytes.fromhex(iv)
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
if is_pkcs7_padded(plaintext):
return unpad(plaintext, 16).decode('ascii')
else:
return plaintext.decode('ascii')
print(decrypt_flag(shared_secret,iv_hex, enc_flag_hex))
```
**Flag** : crypto{n07_3ph3m3r4l_3n0u6h}
## 2. Static Client2

Chall này có vẻ giống bài ở trên nhưng dùng cách đấy lại không hiệu quả .
Mình thử một cách khác, thay đổi parameters gửi cho Bob như sau :
* g' = 2
* p' sao cho p'-1 là [smooth-number](https://en.wikipedia.org/wiki/Smooth_number) và số bit của p' > p.
* A' = A
Sau khi gửi thì chúng ta sẽ nhận lại từ Bob B = g^b^ mod(smoothp).Với cách chọn p' như trên cho chúng ta có thể áp dụng thuật toán Pohlig–Hellman để giải quyết bài toán logarit rời rạc B từ đó tìm được b.
Mọi người có thể tìm hiểu thêm về Pohlig–Hellman [tại đây](https://en.wikipedia.org/wiki/Pohlig%E2%80%93Hellman_algorithm).
solve.py
```python=
from pwn import *
from Crypto.Util.number import *
import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
from sympy.ntheory.residue_ntheory import discrete_log
r = remote('socket.cryptohack.org', 13378)
def json_recv():
line = r.recvline()
return json.loads(line.decode())
def json_send(hsh):
request = json.dumps(hsh).encode()
r.sendline(request)
def smooth_p():
mul = 1
i = 1
while 1:
mul *= i
if (mul + 1).bit_length() >= p.bit_length() and isPrime(mul + 1):
return mul + 1
i += 1
r.recvuntil("Intercepted from Alice: ")
res = json_recv()
p = int(res["p"], 16)
g = int(res["g"], 16)
A = int(res["A"], 16)
r.recvuntil("Intercepted from Bob: ")
res = json_recv()
B = int(res["B"], 16)
r.recvuntil("Intercepted from Alice: ")
res = json_recv()
iv = res["iv"]
ciphertext = res["encrypted"]
s_p = smooth_p()
print(s_p.bit_length())
r.recvuntil("send him some parameters: ")
json_send({
"p": hex(s_p),
"g": hex(2),
"A": hex(A)
})
r.recvuntil("Bob says to you: ")
res = json_recv()
B = int(res["B"], 16)
b = discrete_log(s_p, B, 2)
shared_secret = pow(A, b, p)
def is_pkcs7_padded(message):
padding = message[-message[-1]:]
return all(padding[i] == len(padding) for i in range(0, len(padding)))
def decrypt_flag(shared_secret: int, iv: str, ciphertext: str):
# Derive AES key from shared secret
sha1 = hashlib.sha1()
sha1.update(str(shared_secret).encode('ascii'))
key = sha1.digest()[:16]
# Decrypt flag
ciphertext = bytes.fromhex(ciphertext)
iv = bytes.fromhex(iv)
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext)
if is_pkcs7_padded(plaintext):
return unpad(plaintext, 16).decode('ascii')
else:
return plaintext.decode('ascii')
print(decrypt_flag(shared_secret, iv, ciphertext))
r.interactive()
```
**flag:** crypto{uns4f3_pr1m3_sm4ll_oRd3r}