[re]硬猜flag:2020网鼎杯青龙组re_joker_wp

[re]硬猜flag:2020网鼎杯青龙组re_joker_wp

2020网鼎杯青龙组的一道逆向题joker,这道题其实并不是很难,但难在考心态和脑洞,获取flag的最后一步居然是硬猜,我吐了啊,而且没法爆破,因为这道题你拿到flag了,在程序中输入也不会告诉你flag正确。

题目分析

题目是一个32位windows程序:
在这里插入图片描述
逆向分析一下,main函数直接f5是不行的,堆栈不平衡。

但这里无需去纠正他,因为main函数的逻辑还算简单:

直接可以看出flag字符串长度是0x18也就是24
在这里插入图片描述
然后对输入的flag进行了下面两个操作,这两个函数都可以f5:

分别是wrong:
在这里插入图片描述
和omg:
在这里插入图片描述
首先对输入的flag的每个字节根据并1后是否为真进行了-下标或者亦或下标的操作,然后得到的结果跟一个全局变量比较,逻辑比较简单就可以还原:

result="fkcd\x7fagd;Vka{&;Pc_MZq\x0c7f"
i=0
flag=""
for j in result:
    if(i&1):
        flag+=chr(ord(j)+i)
    else:
        flag+=chr(ord(j)^i)
    i+=1
print flag

然而flag是假的(看flag的字符串也能看出来,而且程序还没结束)。
在这里插入图片描述
然后继续分析:
在这里插入图片描述
这里可以看到对一个函数进行了一些操作,很明显可以看出右边的操作是循环对这个函数进行解密,解密之后直接调用。直接点进这个函数也是一堆乱码:

好办,直接上od,在这个函数调用前的位置0x401833 下断点,然后执行到这:
在这里插入图片描述
可以看到函数已经解密了:
在这里插入图片描述
然后olldump直接脱壳,啥也不用选:

然后IDA打开,可以f5这个函数:
在这里插入图片描述
逻辑是,对输入的内容和hahahaha_do_you_find_me?这个字符串进行异或,然后和一个全局变量进行比较,注意只异或了19个字节,然后写出脚本还原一下:

result2="\x0e\x0d\x09\x06\x13\x05\x58\x56\x3e\x06\x0c\x3c\x1f\x57\x14\x6b\x57\x59\x0d"
flag=""
haha="hahahaha_do_you_find_me?"
for i in range(19):
    flag+=chr(ord(haha[i])^ord(result2[i]))
print flag

在这里插入图片描述
只有19个字节,还缺后5个字节,这个就体现这道题的恶心之处了。

IDA中看程序的逻辑发现调用flag校验函数之后还有一个finally函数,这个函数正常执行是执行不到的,当然执行到了也不是校验flag或者计算输出flag,这是个“逗你玩”的函数:

这个函数同样是加密的,从刚刚从OD中脱出来的程序中可以看到这个函数的明文:
在这里插入图片描述
5个字符:“%tp&:”,但后面的判断简直是在搞笑,每次都是随机的?这里显然不是,虽然说脑洞不是很大,但这样子加大难度真的很烦。

因为flag最后一个字节一定是‘}’,那么用‘:’^‘}’=0x47,然后使用“%tp&:”分别异或0x47得到最后5个字节。爆破没用,因为这个flag你就算是得到了,在程序中输入也会告诉你是错误的,只有在比赛页面提交才会正确,也就是说没有任何一个队伍在提交这道题的flag前是确定自己做对了的…

完整exp:

result="fkcd\x7fagd;Vka{&;Pc_MZq\x0c7f"
i=0
flag=""
for j in result:
    if(i&1):
        flag+=chr(ord(j)+i)
    else:
        flag+=chr(ord(j)^i)
    i+=1
print flag
result2="\x0e\x0d\x09\x06\x13\x05\x58\x56\x3e\x06\x0c\x3c\x1f\x57\x14\x6b\x57\x59\x0d\x47\x47\x47\x47\x47"
flag=""
haha="hahahaha_do_you_fin%tp&:"
for i in range(24):
    flag+=chr(ord(haha[i])^ord(result2[i]))
print flag

得到真的flag:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章