安全通信
感謝impakho師傅!
題目:
#!/usr/bin/env python
import sys
import json
from Crypto.Cipher import AES
from Crypto import Random
def get_padding(rawstr):
remainder = len(rawstr) % 16
if remainder != 0:
return '\x00' * (16 - remainder)
return ''
def aes_encrypt(key, plaintext):
plaintext += get_padding(plaintext)
aes = AES.new(key, AES.MODE_ECB)
cipher_text = aes.encrypt(plaintext).encode('hex')
return cipher_text
def generate_hello(key, name, flag):
message = "Connection for mission: {}, your mission's flag is: {}".format(name, flag)
return aes_encrypt(key, message)
def get_input():
return raw_input()
def print_output(message):
print(message)
sys.stdout.flush()
def handle():
print_output("Please enter mission key:")
mission_key = get_input().rstrip()
print_output("Please enter your Agent ID to secure communications:")
agentid = get_input().rstrip()
rnd = Random.new()
session_key = rnd.read(16)
flag = '<secret>'
print_output(generate_hello(session_key, agentid, flag))
while True:
print_output("Please send some messages to be encrypted, 'quit' to exit:")
msg = get_input().rstrip()
if msg == 'quit':
print_output("Bye!")
break
enc = aes_encrypt(session_key, msg)
print_output(enc)
if __name__ == "__main__":
handle()
解答 :
從 get_padding 和 aes_encrypt 能夠看出這是一個 AES ECB 256位分組加密加密密鑰是 16字節 隨機生成,ECB明文分組相同,對應的密文分組也相同。
由此可以通過改變 agentid 的長度,使flag中的字符依次落入前面已知的明文分組中,逐字節爆破。
貼出腳本:
from pwn import *
import string
LOG = False
flag = ''
mission_key = '********************************'
agent_id = ''
while True:
r = remote('116.85.48.103', 5002)
r.recvuntil('mission key:')
r.sendline(mission_key)
r.recvuntil('communications:')
agent_id = 'a' * (13+16*8-len(flag))
r.sendline(agent_id)
r.recvline()
enc = r.recvline().rstrip()[32*11:32*12]
if LOG: print 'enc=%s' % enc
for i in string.printable[:-5]:
r.recvuntil('to exit:')
message = 'Connection for mission: %s, your mission\'s flag is: %s' % (agent_id, flag + i)
r.sendline(message[-16:])
r.recvline()
enc_tmp = r.recvline().rstrip()
if LOG: print 'enc_tmp=%s' % enc_tmp
if enc_tmp == enc:
flag += i
break
r.close()
if flag[-1:] == '}': break
print 'flag=%s' % flag
print 'Flag: %s' % flag
Flag: DDCTF{87fa2cd38a4259c29ab1af39995be81a}
2018DDCTF-Writeup