---
# System prepended metadata

title: '[Cryptohack] Static Client - Static Client2'

---

# [Cryptohack] Static Client - Static Client2

## 1. Static Client

![](https://i.imgur.com/rfb3Y6Z.png)

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

![](https://i.imgur.com/LSP0SvB.png)

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}

