ASIS CTF Finals 2020 - babymd5

給出了一個能夠鏈接的地址,試着鏈接得git

 讓咱們輸入一字符串,長度要爲15,且通過sha384加密後,最後六位字符爲'd709bb',可根據這些寫一個小小的腳原本找出符合這些條件的字符串github

以下:dom

import hashlib
import string,random

for i in range(100000000000000,199999999999999):
    temp=hashlib.sha384(str(i).encode()).hexdigest()
    if temp[-6:]=='d709bb':
        print(str(i))
        break

結果以下:函數

 

 

 

輸入字符串後,又顯示加密

 

輸入B後,顯示代碼以下:spa

def babymd5(m, n, x_head, y_head, x, y):
    if x.startswith(x_head) and y.startswith(y_head):
        for _ in range(m):
            xhash = md5(x.encode('utf-8')).hexdigest()
            x = xhash
        for _ in range(n):
            yhash = md5(y.encode('utf-8')).hexdigest()
            y = yhash
        if xhash == yhash:
            return True
    return False

輸入C後,顯示代碼以下:code

| (m, n, x_head, y_head) = (202, 201, 'nPz', 'dead')

輸入R後,提示讓咱們輸入xblog

總結一下,流程大概就是已知一個函數babymd5和參數條件,即函數的參數前4個爲(202,201,'nPz','dead'),讓咱們輸入讓函數babymd5返回結果爲True的x和ymd5

分析下函數babymd5的大概流程:utf-8

①判斷x是否以x_head開頭,y是否以y_head開頭,若此條件不經過,則直接返回false

②將x進行md5加密,並對每次的結果進行循環加密,總加密次數爲m次,最後加密結果爲xhash

③將y進行md5加密,並對每次的結果進行循環加密,總加密次數爲n次,最後加密結果爲yhash

④若最後xhash與yhash恆相等,那麼函數會返回True,不然返回False

這裏難點就是如何找到這樣的x和y,使得它們通過不一樣次數的md5加密後,值會相等,(我就被難倒了!參考了下wphttps://github.com/TalaatHarb/ctf-writeups/blob/main/asisctf2020/babymd5,寫的很詳細!)

函數中,很特殊的一個過程就是對結果反覆進行循環加密,而y_head='dead','dead'又是一個合法的十六進制表示,且x加密循環的次數m>對y循環加密的次數n,故,咱們能夠把y當作x循環md5加密n次後的一箇中間結果,即只要找到這樣的一個x,對它進行循環解密n次後,它的結果temphashx恰以'dead'開頭,而這個結果temphashx也就是咱們須要的y。腳本以下:

import hashlib
import string,random

def babymd5(m, n, x_head, y_head, x, y):
    if x.startswith(x_head) and y.startswith(y_head):
        for _ in range(m):
            xhash = hashlib.md5(x.encode('utf-8')).hexdigest()
            x = xhash
        for _ in range(n):
            yhash = hashlib.md5(y.encode('utf-8')).hexdigest()
            y = yhash
        if xhash == yhash:
            return True
    return False


dict=string.ascii_letters+string.digits+string.punctuation
print(dict)
counter=1
found=False
length=32
x_head='nPz'
y_head='dead'
m=202
n=201
while not found:
    tmp=x_head+''.join(random.choice(dict) for _ in range(length))
    possible_x=tmp
    res=tmp
    for _ in range(m-n):
        res=hashlib.md5(res.encode()).hexdigest()
    if res.startswith('dead'):
        possible_x=res
        x=tmp
        y=res
        print("x:",x)
        print("y:",y)
        found=babymd5(202, 201, 'nPz', 'dead',x,y)
        break
    if(counter%10000==0):
        print("attemp:"+str(counter)+'')
    if(counter%100000==0):
        print("attemp:"+str(counter)+'')
    counter=counter+1

獲得結果:

 

 輸入對應的x和y後,獲得flag!

相關文章
相關標籤/搜索