日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[BSidesSF2020]haystack

發(fā)布時間:2025/3/21 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BSidesSF2020]haystack 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

[BSidesSF2020]haystack

題目

This vendor claims they have figured out a way to preserve the integrity and confidentiality of a message using signing instead of encryption. We only have a binary pycache file and a message off the wire – can you find the content of the message?

解題

該供應(yīng)商聲稱,他們已經(jīng)找到了一種使用簽名而不是加密來保護(hù)消息完整性和機(jī)密性的方法。我們只有一個二進(jìn)制pycache文件和一條離線消息——你能找到消息的內(nèi)容嗎?

pcap文件是常用的數(shù)據(jù)報存儲格式,可以理解為就是一種文件格式,只不過里面的數(shù)據(jù)是按照特定格式存儲的,所以我們想要解析里面的數(shù)據(jù),也必須按照一定的格式。普通的記事本打開pcap文件顯示的是亂碼,用安裝了HEX-Editor插件的Notepad++打開,能夠以16進(jìn)制數(shù)據(jù)的格式顯示,用wireshark這種抓包工具就可以正常打開這種文件,愉快地查看里面的網(wǎng)絡(luò)數(shù)據(jù)報了,同時wireshark也可以生成這種格式的文件。當(dāng)然這些工具只是我經(jīng)常使用的,還有很多其它能夠查看pcap文件的工具。

pyc文件是python程序編譯生成的字節(jié)碼文件,uncompyle工具或者在線反編譯工具可以很容易將pyc文件反編譯,通過加入混淆指令可以達(dá)到在不影響運行的情況下欺騙過反編譯工具的目的,從而達(dá)到保護(hù)目的。混淆的方法可以是加入一些無意義的跳轉(zhuǎn)分支,錯誤的語句使反編譯工具工作失敗,但又在跳轉(zhuǎn)語句的作用下跳過了執(zhí)行。

這道題應(yīng)該并沒有加入混淆指令,先來下載uncompyle工具😂

最方便的就是使用pip安裝
pip install uncompyle
uncompyle6 --help 查看幫助
uncompyle6 models.pyc > models.py 將models.pyc反編譯成py文件
uncompile -o . *.pyc 將當(dāng)前文件夾中所有的pyc文件反編譯成后綴名為.pyc_dis的源文件

反翻譯得到:

# uncompyle6 version 3.7.4 # Python bytecode 3.7 (3394) # Decompiled from: Python 3.8.7 (tags/v3.8.7:6503f05, Dec 21 2020, 17:59:51) [MSC v.1928 64 bit (AMD64)] # Embedded file name: /home/david/Projects/BSidesCTF/2020/challenges/haystack/challenge/chaffing.py # Compiled at: 2020-01-22 09:37:26 # Size of source mod 2**32: 2094 bytes import hmac, hashlib, random, struct CHAFF_SIZE = 32 SIG_SIZE = 16 ALL_BYTES = set((c for c in range(256))) KEY = 'af5f76f605a700ae8c0895c3e6175909'def byte(v):return bytes([v])def sign_byte(val, key):return hmac.new(key,val, digestmod=(hashlib.sha256)).digest()[:SIG_SIZE]def chaff_byte(val, key):msgs = {}msgs[val[0]] = sign_byte(val, key)while len(msgs) < CHAFF_SIZE:vals = list(ALL_BYTES - set(msgs.keys()))c = random.choice(vals)if c == val:raise ValueError('Chose duplicate!')fake_sig = bytes(random.choices((list(ALL_BYTES)), k=SIG_SIZE))msgs[c] = fake_sigpieces = []for k, v in msgs.items():pieces.append('%s%s' % (byte(k), v))random.shuffle(pieces)return ''.join(pieces)def chaff_msg(val, key):if not isinstance(val, bytes):val = val.encode('utf-8')msg_out = []for b in val:msg_out.append(chaff_byte(byte(b), key))outval = ''.join(msg_out)return struct.pack('>I', len(val)) + outvaldef winnow_msg(val, key):if not isinstance(val, bytes):val = val.encode('utf-8')msglen = struct.unpack('>I', val[:4])[0]val = val[4:]chunk_len = (SIG_SIZE + 1) * CHAFF_SIZEexpected_len = chunk_len * msglenif len(val) != expected_len:raise ValueError('Expected length %d, saw %d.' % (expected_len, len(val)))pieces = []for c in range(msglen):chunk = val[chunk_len * c:chunk_len * (c + 1)]res = winnow_byte(chunk, key)pieces.append(res)return ''.join(pieces)def winnow_byte(val, key):while val:c = byte(val[0])sig = val[1:SIG_SIZE + 1]if sign_byte(c, key) == sig:return cval = val[SIG_SIZE + 1:]raise ValueError('No valid sig found!')def main():inp = 'This is a test message!'msg = chaff_msg(inp, KEY)ret = winnow_msg(msg, KEY)if inp != ret:print('Wrong ret: %s' % ret)if __name__ == '__main__':main() # okay decompiling chaffing.pyc

然后讀程序:

set() 函數(shù)創(chuàng)建一個無序不重復(fù)元素集,可進(jìn)行關(guān)系測試,刪除重復(fù)數(shù)據(jù),還可以計算交集、差集、并集等。

isinstance() 函數(shù)來判斷一個對象是否是一個已知的類型,類似 type()。

hmac與hashlib類似,這兩個都是Python中加密的函數(shù),都是不可逆的加密,hashlib模塊實現(xiàn)了sha1,sha224,sha256,sha384,sha512,md5等算法,交易所的加密中一般使用sha256或md5。hmac模塊需要一個msg來進(jìn)行加密,hashlib并沒有msg這個參數(shù)。

random.shuffle() 隨機(jī)打亂序列

解題的話,來看一下大佬的代碼吧:

#exp.py import hmac, hashlib, random, struct from collections import Counter CHAFF_SIZE = 32 SIG_SIZE = 16 ALL_BYTES = set((c for c in range(256))) def extract(val):if not isinstance(val, bytes):val = val.encode('utf-8')msglen = struct.unpack('>I', val[:4])[0]val = val[4:]chunk_len = (SIG_SIZE + 1) * CHAFF_SIZEexpected_len = chunk_len * msglenif len(val) != expected_len:raise ValueError('Expected length %d, saw %d.' % (expected_len, len(val)))pieces = []for c in range(msglen):chunk = val[chunk_len * c:chunk_len * (c + 1)]res = extract_byte_sig_pairs(chunk)pieces.extend(res)return piecesdef extract_byte_sig_pairs(val):res = []while val:c = (val[0])sig = val[1:SIG_SIZE + 1]res.append((c, sig))val = val[SIG_SIZE + 1:]return resmsg = open('1.txt', 'rb').read() ret = extract(msg) c = Counter(ret) real = c.most_common(256) print(real)def decode(val, d):if not isinstance(val, bytes):val = val.encode('utf-8')msglen = struct.unpack('>I', val[:4])[0]val = val[4:]chunk_len = (SIG_SIZE + 1) * CHAFF_SIZEexpected_len = chunk_len * msglenif len(val) != expected_len:raise ValueError('Expected length %d, saw %d.' % (expected_len, len(val)))pieces = []for c in range(msglen):chunk = val[chunk_len * c:chunk_len * (c + 1)]res = decode_byte(chunk, d)pieces.append(res)return b''.join(pieces)def decode_byte(val, d):while val:c = (val[0])sig = val[1:SIG_SIZE + 1]if sig in d and d[sig] == c:return cval = val[SIG_SIZE + 1:]raise ValueError("WTF")d = {s: b for (b, s), c in real} print('\n') print('\n') print('\n') print(d) print(decode(msg,d))

其中:
struct.unpack(fmt,string)
顧名思義,解包。比如pack打包,然后就可以用unpack解包了。返回一個由解包數(shù)據(jù)(string)得到的一個元組(tuple), 即使僅有一個數(shù)據(jù)也會被解包成元組。其中l(wèi)en(string) 必須等于 calcsize(fmt),這里面涉及到了一個calcsize函數(shù)。struct.calcsize(fmt):這個就是用來計算fmt格式所描述的結(jié)構(gòu)的大小。

但是這個代碼是存在錯誤的,比如我們并沒有1.txt,但是我們還有一個名為message.pcap的文件,所以用這個替換1.txt,然而依然有錯誤,運行出來:ValueError: Expected length 1941859702304, saw 777384.也就是說,len(val) != expected_len。

總結(jié)

以上是生活随笔為你收集整理的[BSidesSF2020]haystack的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。