欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-19 14:17:55
...

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

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

题目分析

题目是一个32位windows程序:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
逆向分析一下,main函数直接f5是不行的,堆栈不平衡。
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
但这里无需去纠正他,因为main函数的逻辑还算简单:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
直接可以看出flag字符串长度是0x18也就是24
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
然后对输入的flag进行了下面两个操作,这两个函数都可以f5:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
分别是wrong:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
和omg:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
首先对输入的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的字符串也能看出来,而且程序还没结束)。
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
然后继续分析:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
这里可以看到对一个函数进行了一些操作,很明显可以看出右边的操作是循环对这个函数进行解密,解密之后直接调用。直接点进这个函数也是一堆乱码:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
好办,直接上od,在这个函数调用前的位置0x401833 下断点,然后执行到这:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
可以看到函数已经解密了:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
然后olldump直接脱壳,啥也不用选:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp

然后IDA打开,可以f5这个函数:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
逻辑是,对输入的内容和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

[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
只有19个字节,还缺后5个字节,这个就体现这道题的恶心之处了。

IDA中看程序的逻辑发现调用flag校验函数之后还有一个finally函数,这个函数正常执行是执行不到的,当然执行到了也不是校验flag或者计算输出flag,这是个“逗你玩”的函数:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp

这个函数同样是加密的,从刚刚从OD中脱出来的程序中可以看到这个函数的明文:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp
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:
[re]硬猜flag:2020网鼎杯青龙组re_joker_wp