Tags: pcap crypto ssl
Rating: 5.0
# Miro
## Challenge Description
Do you wanna play the game? :D
612 Pts
8 Solves
## Process
Fisrt we are given file name `bf083d4ab960620b645557217dd59a49` ,its zip file.Inside it we get 2 file, `client.py` and `miro.pcap`
This is the `client.py` looks like :
```python
from socket import *
from ssl import *
import time
def recv_until(s, string):
result = ''
while string not in result:
result += s.recv(1)
return result
client_socket=socket(AF_INET, SOCK_STREAM)
tls_client = wrap_socket(client_socket, ssl_version=PROTOCOL_TLSv1_2, cert_reqs=CERT_NONE)
print "[+] Connecting with server.."
tls_client.connect(('ch41l3ng3s.codegate.kr',443))
print "[+] Connect OK"
while 1:
data = recv_until(tls_client, "Input : ")
print data
#message
user_input = raw_input()
if user_input == "u":
print "Sorry.. Not support function.."
exit()
elif user_input == "d":
tls_client.send("6423e47152f145ee5bd1c014fc916e1746d66e8f5796606fd85b9b22ad333101\n")
elif user_input == "r":
tls_client.send("34660cfdd38bb91960d799d90e89abe49c1978bad73c16c6ce239bc6e3714796\n")
elif user_input == "l":
print "Sorry.. Not support function.."
exit()
else:
print "Invalid input!"
exit()
client_socket.shutdown(SHUT_RDWR)
client_socket.close()
```
When we run `client.py` we got little maze game like :
```bash
root@yeraisci:~/Downloads# python client.py
[+] Connecting with server..
[+] Connect OK
-- Labytinth Game --
You have to go to the [G]
Input List : u(go up), d(go down), r(go right), l(go left)
[O][O][O][O][O][O][*][O][O][O]
[O][O][O][O][O][O][ ][ ][ ][O]
[O][O][ ][ ][ ][O][O][O][ ][O]
[O][ ][ ][O][ ][ ][ ][ ][ ][O]
[O][ ][O][O][O][O][O][O][O][O]
[ ][ ][O][O][ ][ ][ ][ ][O][O]
[ ][O][O][O][ ][O][O][ ][O][O]
[ ][ ][ ][O][ ][O][O][ ][ ][O]
[O][O][ ][ ][ ][O][O][O][ ][ ]
[O][O][O][O][O][O][O][O][O][G]
Input :
d
[O][O][O][O][O][O][V][O][O][O]
[O][O][O][O][O][O][*][ ][ ][O]
[O][O][ ][ ][ ][O][O][O][ ][O]
[O][ ][ ][O][ ][ ][ ][ ][ ][O]
[O][ ][O][O][O][O][O][O][O][O]
[ ][ ][O][O][ ][ ][ ][ ][O][O]
[ ][O][O][O][ ][O][O][ ][O][O]
[ ][ ][ ][O][ ][O][O][ ][ ][O]
[O][O][ ][ ][ ][O][O][O][ ][ ]
[O][O][O][O][O][O][O][O][O][G]
Input :
u
Sorry.. Not support function..
```
As we can see,maybe we have to complete the maze to get the flag,but its a problem,because step `u` and `l` are not supported by `client.py`,it seem like the server recognize client's step by a bunch of number,obviously we can't bruteforce it because its too long,and then we take a look at `miro.pcap` and found some interaction between client and server :
![](https://raw.githubusercontent.com/rafiem/CTF/master/Screenshot%20from%202018-02-05%2017-52-12.png)
Hmmm,we know that server use ssl and tls as protocol to transfer data,if we look at the `miro.pcap`,file we notice that some of `application data` have been captured,but its encrypted.We want to know that data,maybe we found step `u` and `l` in there.We notice there is a handshake protocol beteween server.
The next thing we want to do is try to decrypt `application data` using the `certificate` from handshake protocol.We need to go to packet section `Server Hello,Certificate, Server Hello Done` >> `Secure Socket Layer` >> `Handshake Protocol` >> `Certificate` .
![](https://raw.githubusercontent.com/rafiem/CTF/master/Screenshot%20from%202018-02-05%2018-00-17.png)
And then we export the certificate bytes in file named `certif.der`.If we see on the `openssl` info of the `certificate` using:
```bash
openssl x509 -inform DER -in certif.der -text
```
we can see that encryption scheme using `Signature Algorithm: sha256 With RSA Encryption` we then convert this cerificate to `PEM` format file to gain the public key of RSA. with :
```bash
openssl x509 -inform der -pubkey -noout -in certif.der > certif.pem
```
We then try to factorize `n` and get the `p` and `q` using factor fermat,and we construct RSA private key and export to `PEM` format and save as `privkey.key` :
```python
from Crypto.Util.number import *
from Crypto.PublicKey import RSA
import gmpy
def factor_fermat(N):
a = gmpy.sqrt(N)
b2 = a*a - N
while not gmpy.is_square(gmpy.mpz(b2)):
b2 += 2*a + 1
a += 1
factor1 = a - gmpy.sqrt(b2)
factor2 = a + gmpy.sqrt(b2)
return (long(factor1.digits()), long(factor2.digits()))
def read_pubkey(pem_file):
pem = open(pem_file).read()
key = RSA.importKey(pem)
n = key.n
e = key.e
return (n, e)
n,e=read_pubkey("certif.pem")
p,q=factor_fermat(n)
phi=(p-1)*(q-1)
d=inverse(e,phi)
g=open('privkey.key','wb')
priv = RSA.construct((n,e,d))
g.write(priv.exportKey('PEM'))
g.close()
```
After that we go to wireshark,to decrypt `ssl traffic data`.Heading to `Edit` >> `Preferences` >> `Protocols` >> `ssl` .And we edit the RSA key lists form using previous private key,like :
![](https://raw.githubusercontent.com/rafiem/CTF/master/Screenshot%20from%202018-02-05%2018-49-34.png)
After that,we get to know the data transferred in `application data` .We then search specific string that use to make a `u` step and `l` step.We found them,and we just try the correct string between step `u` and `l`.Modify the `client.py` with :
```python
if user_input == "u":
tls_client.send("9de133535f4a9fe7de66372047d49865d7cdea654909f63a193842f36038d362\n")
```
And
```python
elif user_input == "l":
tls_client.send("27692894751dba96ab78121842b9c74b6191fd8c838669a395f65f3db45c03e2\n")
```
Finally,just run the script and finish the maze("we think this game have to be done in like several times,but its just 1 time,ok") and get the flag
`Flag is {C4n_y0u_d3crypt_th3_P4ck3t??}`