Switch Editions?
Cancel
Sharing:
Title:
URL:
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles

# 从一道题看cbc攻击-HITCONCTF2017-SecretServer

0
0

xman处看到一题特别有意思的题目，问了下老师，恍然大悟。

import os, base64, time, random, string
from Crypto.Cipher import AES
from Crypto.Hash import *
key = os.urandom(16)
return msg[:-ord(msg[-1])]
def encrypt(iv,msg):
cipher = AES.new(key,AES.MODE_CBC,iv)
encrypted = cipher.encrypt(msg)
return encrypted
def decrypt(iv,msg):
cipher = AES.new(key,AES.MODE_CBC,iv)
decrypted = cipher.decrypt(msg)
return decrypted
def send_msg(msg):
iv = '2jpmLoSsOlQrqyqE'
encrypted = encrypt(iv,msg)
msg = iv+encrypted
msg = base64.b64encode(msg)
print msg
return
def recv_msg():
msg = raw_input()
try:
msg = base64.b64decode(msg)
assert len(msg)<500
decrypted = decrypt(msg[:16],msg[16:])
return decrypted
except:
print 'Error'
exit(0)
def proof_of_work():
proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in xrange(20)])
digest = SHA256.new(proof).hexdigest()
print "SHA256(XXXX+%s) == %s" % (proof[4:],digest)
x = raw_input('Give me XXXX:')
if len(x)!=4 or SHA256.new(x+proof[4:]).hexdigest() != digest:
exit(0)
print "Done!"
return
if __name__ == '__main__':
proof_of_work()
with open('flag.txt') as f:
assert flag.startswith('hitcon{') and flag.endswith('}')
send_msg('Welcome!!')
while True:
try:
msg = recv_msg().strip()
if msg.startswith('exit-here'):
exit(0)
elif msg.startswith('get-flag'):
send_msg(flag)
elif msg.startswith('get-md5'):
send_msg(MD5.new(msg[7:]).digest())
elif msg.startswith('get-time'):
send_msg(str(time.time()))
elif msg.startswith('get-sha1'):
send_msg(SHA.new(msg[8:]).digest())
elif msg.startswith('get-sha256'):
send_msg(SHA256.new(msg[10:]).digest())
elif msg.startswith('get-hmac'):
send_msg(HMAC.new(msg[8:]).digest())
else:
except:
exit(0)

MmpwbUxvU3NPbFFycXlxRc/vKRt4fANSEpCk0agly4E=

base64解密之后得到的是iv+decryption:

2jpmLoSsOlQrqyqE + D(Welcome!!)

D(密文) = “Welcome!!” ^ IV1 明文 = D(密文) ^ IV2 明文 = “Welcome!!” ^ IV1 ^ IV2

IV2 = “Welcome” ^ IV1 ^ “控制的字符串”

def strxor(str1, str2):
return ''.join([chr(ord(c1) ^ ord(c2)) for c1, c2 in zip(str1, str2)])
def flipplain(oldplain, newplain, iv):
"""flip oldplain to new plain, return proper iv"""
return strxor(strxor(oldplain, newplain), iv)
msg = base64.b64encode(get_flag_iv + base64.b64decode(msg)[16:])

if msg.startswith('exit-here'):
exit(0)
if msg.startswith('get-flag'):
send_msg(flag)
elif msg.startswith('get-md5'):
send_msg(MD5.new(msg[7:]).digest())
elif msg.startswith('get-time'):
send_msg(str(time.time()))
elif msg.startswith('get-sha1'):
send_msg(SHA.new(msg[8:]).digest())
elif msg.startswith('get-sha256'):
send_msg(SHA256.new(msg[10:]).digest())
elif msg.startswith('get-hmac'):
send_msg(HMAC.new(msg[8:]).digest())
else:

msg = base64.b64encode(new_iv + cipher_flag + last_byte_iv + cipher_welcome) 最后能得到’get-md5’+flag[7:]的加密值，跳进去get-md5命令之后就能得到MD5(flag[7:])的值，不过这还不够，我们观察: def unpad(msg):

(tips: 其中52-53行的 new_iv = flipplain("hitcon{".ljust(16, 'x00'), "get-md5".ljust(16, 'x00'), iv_encrypt) 可以替换成我上面说的 new_iv = flipplain(pad("hitcon{"), pad("get-md5"), iv_encrypt) ,因为iv并不影响aes解密过程，所以也无妨，只能说liubaozheng老师想的更加细致了。)

Viewing all articles

### 雄韬生活 |潘刚，究竟开了十九大会议没有？

More Pages to Explore .....