給出了一個能夠鏈接的地址,試着鏈接得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!