本文主要是介绍攻防世界-reverse-for-the-holy-grail-350,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目下载:下载
载入查壳工具,无壳,直接载入IDA。查看main函数。
从这里的std::cout,std:cin可以知道这应该就是输出与输入操作,输入为v11,和userIn。在main函数里观察v11好像没有什么重要操作,而userIn在construct函数中出现过,初步判断是flag。对于contruct函数应该就是简单的对执行对象进行初始化操作,并不是关键函数。那从后往前分析。
我们想要走到"Go on. Off you go. tuctf{",那就要v4大于等于0,而v4是由stringMod(v9)求出,所以这可能是个关键函数,跟进:有3个do...while循环语句,先看第一个。
创建空间给v14,然后把a1赋值给v2,然后又给了v12,v14。看if语句,如果条件符合则v4=-1,看到这里第一反应就是肯定不能走v4=-1这个路。(后面会解释)。所以让3*(v3/3)==v3且v12==firstchar[v3/3]就行。这个条件的意思是v3从0开始要是3的倍数并且以v3为下标的v12的那个数要等于firstchar[v3/3]。进入firstchar。有8个元素,并且满足v3/3在这个数组范围中,所以初步判断v3==0,3,6,9,12,15,18,21。也就对应flag的0,3,6,9,12,15,18,21位(其实这个flag一共18位,后面可知)。
解释为什么v4!=-1如果v4==-1,那么return的值为负数,回到函数调用处后赋值给v4,v4为负值,就会执行Ahhh,不会输出flag。
看下一个do...while。
上面可知把a1赋值给v14,这里又把v14的地址赋值给指针v5,v6,然后进行异或操作,所以这里是对v6即flag进行异或加密。
看第三个do...while
do...while循环中有if判断,如果v11为2执行子句1并且v11又赋值为0,所以v11不可能超过2。不是2就执行else语句,通过观察可知最初v11=0,而让v11变化的就是else语句中的++v11,所以v11一直是0,1,2,0,1,2...循环。搞懂了if...else后看看里面的关键的if语句
第一个if语句是确定flag的第2,5,8,11,14,17位。因为当do...while循环 2,5,8,11,14,17次时,v11==2,才会执行这里,而且v5在遍历flag正好遍历到2,5,8,11,14,17位。所以就剩下flag的1,4,7,10,13,16位未知,所以第二个if应该和这个有关。
在看第二个if,v10是flag的2,5,8,11,14,17位的前两位的乘积,如下图知
既然我们知道了其余的flag位数就能通过这个if条件求出flag的1,4,7,10,13,16位,这里用正向爆破比较容易。
为什么flag有18位
v8初值为1,并且v8==19时就停止循环了,而v5是在遍历flag,所以一共遍历18次,所以flag应该18位。
我们观察firstchar,thirdchar,masterArray数组是db类型,而我们需要dd型,利用内嵌python导出数据:
from idc_bc695 import *
addr=[0x601840,0x601860,0x601880]
list=[]
for a in addr:for i in range(6):list.append(Dword(a+4*i))
print('sucessful')
print(list)
代码:(注意flag异或解密回去)
firstchar=[65, 105, 110, 69, 111, 97] #变化后第0,3,6,9,12,15位
thirdchar=[751, 708, 732, 711, 734, 764]#变化后第2,5,8,11,14,17位
masterarray=[471, 12, 580, 606, 147, 108]#第1,4,7,10,13,16一系列操作后与之相等的数组#求对a1异或的数据列表v7
list=[666,]
v7=666
for i in range(17):v7=v7+v7%5list.append(v7)
print(list)#求flag第0,3,6,9,12,15位
flag= [0 for i in range(18)]
index1=0
for i in range(0,16,3):flag[i]=firstchar[index1]index1=index1+1
print(flag)
#求第2,5,8,11,14,17位
index2=0
for i in range(2,18,3):flag[i]=list[i]^thirdchar[index2]index2=index2+1
print(flag)
#求第1,4,7,10,13,16位
index3=0
for i in range(1,17,3):for j in range(32,127):if ((list[i-1]^firstchar[index3])*(list[i]^j))%thirdchar[index3]==masterarray[index3]:flag[i]=jindex3=index3+1break
print('tuctf{'+"".join(map(chr,flag))+'}')#tuctf{AfricanOrEuropean?}
这篇关于攻防世界-reverse-for-the-holy-grail-350的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!