CTF | wargame

codegate 2017 final / ransomware rsa 부분 (rsa 복호화, rsa 블록 형태)

nopdata 2017. 5. 2. 13:22
ransomware 복호화 부분. ransomware 프로그램을 돌리면 대회 시작 이전 레코드가 총 3개 있다. 해당 레코드의 public, private key 쌍을 뽑아 짝을 맞출 수 있으며 여기서 대회 문제에서 제공된 암호 복호화 시킬 수 있다.

(1) 키 쌍 확인하기
privatekey 1,2,3의 키쌍을 확인해보면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
>>> from Crypto.PublicKey import RSA
>>> def check_rsa(public,private):
...     pub = RSA.importKey(public)
...     pri = RSA.importKey(private)
...     
...     message = "Hello World!"
...     encrypted = pub.encrypt(message,public)
...     decrypted = pri.decrypt(encrypted)
...     
...     return decrypted
... 
>>> public_list = list()
>>> public_list.append(open('public1.key','rb').read())
>>> public_list.append(open('public2.key','rb').read())
>>> public_list.append(open('public3.key','rb').read())
>>> 
>>> private_list = list()
>>> private_list.append(open('private1.key','rb').read())
>>> private_list.append(open('private2.key','rb').read())
>>> private_list.append(open('private3.key','rb').read())
>>> 
>>> for i in range(0,3):
...     print check_rsa(public_list[i],private_list[i])
... 
Hello World!
Hello World!
Hello World!
 

백업을 해 온 키들의 쌍을 맞추어 볼 수 있다.

(2) 복호화 하기
이제 문제에서 제공된 암호를 풀어봐야 한다.  문제가 풀리지 않았던 이유는 암호문의 길이가 총 257 바이트 였는데 rsa의 암호화 된 값치고는 이상하다.
rsa도 내부적인 블록 형태를 사용하기 때문에 어찌되었건 떨어지는 256이 나왔어야 했다. 바로 문제가 되는 1바이트는 윈도우에서 텍스트 파일로 저장할 때 생기는
라인피드인 \r이 붙어버려 생긴 것. 따라서 암호문의 \r\n을 \n으로 고쳐서 풀어주면 답을 얻을 수 있다.

1
2
3
4
5
6
7
>>> enc = open('flag_enc.txt','rb').read()
>>> enc = '\n'.join(enc.split('\r\n'))
>>> key = RSA.importKey(privatekey3)
>>> key.decrypt(enc)
'FLAG{I_need_more_power_and_money!!!!!!}'
>>> 
 
cs