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!

相关文章
相关标签/搜索