sctf 2019 warmup

server.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

from Crypto.Cipher import AES
from Crypto.Util.strxor import strxor
from Crypto.Random import get_random_bytes
from FLAG import flag

class MAC:
    def __init__(self):
        self.key = get_random_bytes(16)
        self.iv = get_random_bytes(16)

    def pad(self, msg):
        pad_length = 16 - len(msg) % 16
        return msg + chr(pad_length) * pad_length

    def unpad(self, msg):
        return msg[:-ord(msg[-1])]

    def code(self, msg):
        res = chr(0)*16
        for i in range(len(msg)/16):
            res = strxor(msg[i*16:(i+1)*16], res)
        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        return aes.encrypt(res).encode('hex')

    def identity(self, msg, code):
        if self.code(msg) == code:
            msg = self.unpad(msg)
            if msg == 'please send me your flag':
                print 'remote: ok, here is your flag:%s' % flag
            else:
                print 'remote: I got it'
        else:
            print 'remote: hacker!'


if __name__ == '__main__':
    mac = MAC()
    message = 'see you at three o\'clock tomorrow'
    print 'you seem to have intercepted something:{%s:%s}' %(mac.pad(message).encode('hex'), mac.code(mac.pad(message)))
    print 'so send your message:'
    msg = raw_input()
    print 'and your code:'
    code = raw_input()
    mac.identity(msg.decode('hex'), code)
    exit()

這里主要用到一個(gè)如下原理:

C = A xor B。若我們想得到X,則有以下推導(dǎo)
C = A xor B ==>> C xor A xor B = 0 ===>> C xor A xor B xor X = X
而整個(gè)解密過程中,B(密文)是我們可以控制的,A由于key未知,而無(wú)法準(zhǔn)確控制,C是原始的明文,在輸出端,無(wú)法控制。
所以,我們可以控制B,讓B首先變成C xor B xor X (這里的C是指原始的明文),這樣最終A與B的異或操作就能變成X

參考文獻(xiàn): http://momomoxiaoxi.com/2016/12/08/WebCrypt/
https://www.anquanke.com/post/id/158233
在這道題中我們進(jìn)行偽造,偽造主要繞過一下兩個(gè)條件:

  • 使用code()的函數(shù)加完密的要等于你自己提供的code的值
  • 使用unpad(msg.decode('hex'))消除填充之后,必須等于:please send me your flag
    圖片.png

進(jìn)行偽造:
題目中會(huì)給出兩組數(shù)據(jù),如下圖所示:


圖片.png

偽造條件如下:

  • 構(gòu)造 A xor B,也就是:
    1.A的每十六字節(jié)“異或”并使用pad()填充:
msg=('706c656173652073656e64206d6520796f757220666c6167'+'8'*16).decode('hex')
print c
res = chr(0)*16
for i in range(len(msg)/16):
    res = strxor(msg[i*16:(i+1)*16], res)
  1. B的每十六進(jìn)制“異或”并使用pad()填充“”
res1 = chr(0)*16
msg1=('73656520796f75206174207468726565206f27636c6f636b20746f6d6f72726f77'+'0f'*15).decode('hex')
for i in range(len(msg1)/16):
    res1 = strxor(msg1[i*16:(i+1)*16], res1)

3.最終將他們異或 A xor B:

last_res = strxor(res1, res).encode('hex')
  • 構(gòu)造第一個(gè)輸入:
    1.由前一組16位和后一組16位異或:


    圖片.png

    2.我們只要構(gòu)造(A xor B) xor A =B:

(A xor B):

last_res = strxor(res1, res).encode('hex')

A:

msg

payload = (msg.encode('hex')+last_res).ljust(124,"a")+'27'
  • 繞過 msg = self.unpad(msg)的檢測(cè):
  1. 可以看出:他用來填充的單位使用的是16的差值.
def pad(self, msg):
        pad_length = 16 - len(msg) % 16
        return msg + chr(pad_length) * pad_length

2.去除填充函數(shù),通過最后一位的數(shù)值,進(jìn)行去除,這里可以偽造:
'''
def unpad(self, msg):
return msg[:-ord(msg[-1])]
'''
3.偽造內(nèi)容在最后加一個(gè)數(shù)值,數(shù)值等于去掉“please send me your flag”之后,即可繞過保護(hù)。

圖片.png

代碼我借用一下別人的,代碼如下:

from pwn import *
from Crypto.Util.strxor import strxor

p=remote('47.240.41.112',12345)

p.recvuntil('0f:')
c = p.recv(32)
msg=('706c656173652073656e64206d6520796f757220666c6167'+'8'*16).decode('hex')
print c1
res = chr(0)*16
for i in range(len(msg)/16):
    res = strxor(msg[i*16:(i+1)*16], res)

res1 = chr(0)*16
msg1=('73656520796f75206174207468726565206f27636c6f636b20746f6d6f72726f77'+'0f'*15).decode('hex')
for i in range(len(msg1)/16):
    res1 = strxor(msg1[i*16:(i+1)*16], res1)

last_res = strxor(res1, res).encode('hex')

payload = (msg.encode('hex')+last_res).ljust(124,"a")+'27'
print payload
p.recvuntil("so send your message:\n")
p.sendline(payload)
p.recvuntil("and your code:\n")
p.sendline(c)
p.interactive()

參考網(wǎng)站:
http://www.itdecent.cn/p/02ef24117d7b
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
基礎(chǔ)知識(shí):
異或兩個(gè)bytes

from Crypto.Util.strxor import strxor
strxor(b'abc', b'def')

參考網(wǎng)站:
http://www.itdecent.cn/p/02ef24117d7b
https://code.felinae98.cn/ctf/crypto/python%E4%B8%AD%E7%9A%84crypto%E5%9C%A8ctf%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容