buuctf-[GXYCTF2019]simple CPP1

题目下载:下载

拖入查壳工具,无壳,64位程序,载入IDA。

因为代码较长,就不截图了,分块分析。(部分变量进行了改名)

ced3015d234c4ea298f313764b428baa.png

 通过上面知道Block是输入,可能为flag。其中有一个if语句,容易知道不能走这里,所以v44要小于等于30。然后分配了一些内存空间给v7,v7赋值给v8。

第二部分:

4e82938d6c054464ab681c1d7815260a.png其中第86行是一个异或,只有这一个地方是异或运算,所以这里应该是关键加密。整体是一个do...while循环,把Block的地址给了v11,又因为v45==15小于16,所以if语句不会执行,然后把off_7FF66C3C6048地址给了v12,if语句还是不会执行(条件不成立),然后进行关键异或,v11与v12遍历异或赋值给v8。

接下来是另一个关键代码:a45dd38ae36148bab281561d8fd784f7.png

把异或后的结果给了v18,然后do...while循环。经过分析知道,这是在获取异或后的v8的值,是在进行字节叠加,首先从v8的第一个字节开始,赋值给v19,然后v19在左移8位,在加上v8的第二个字节,这不就是相当于把v8的值在给v19嘛,但是不同的是,当v17为8,16,24时便将v19分别进行赋值转移给v16,v15,v14,v13,在重新开始,所以就是相当于把v8数值分成4组,前三组分别8Byte,最后一组4字节(后面也算出)。

最后部分:bf13baee37bf4bb68804ba688e8e0df1.png

这里发现有很多已知数值,和v8分4组过后的4个未知数,用a0,a1,a2,a3表示,在这里用z3约束器能求解

from z3 import *
s=Solver()
a0=BitVec('a0',64)
a1=BitVec('a1',64)
a2=BitVec('a2',64)
a3=BitVec('a3',64)
s.add((a2 & ~a1 & a0) | a2 & ((a1&a0) | a1 & ~a0 | ~(a1 | a0))==577031497978884115)
s.add((a2&~a0 | a1&a0 | a2&~a1 | a0&~a1)==4483974544037412639)
s.add(((a2&~a0 | a1&a0 | a2&~a1 | a0&~a1)^a3)==4483974543195470111)
s.add((a2&~a0 | a1&a0 | a1&a2)==(~a0 & a2)|864693332579200012)
s.add((a2&~a0)==1176889593874)
if s.check()==sat:
    answer=s.model()
for i in answer:
    print("%s = 0x%x"%(i,answer[i].as_long()))

结果为52f56d1441da4d2ea60016617ce99c6b.png

as_long()方法从模型对象中提取具体值。 

所以就知道v8的值了。在回到关键异或5dea68c32d2444d093350ff13540a2f9.png

要求v11,需要知道v12,在off_7FF66C3C6048交叉引用,5d112adfbcb44bab9eec7fc8b35f8288.png 所以v12也已知(也可以通过动态调试获取v12),然后就可以求出v11即flag

v8 =[0x3e,0x3a,0x46,0x05,0x33,0x28,0x6f,0x0d,0x1,0x08,0x48,0x00,0x00,0x80,0x00,0x04,0x8,0x02,0x07,0x17,0x15,0x3e,0x30,0x13,0x32,0x31,0x06,0x00]
v12 = "i_will_check_is_debug_or_not"
flag = ""
for i in range(len(v8)-1):
	flag += chr((ord(v12[i%27])) ^ v8[i])
print(flag)

 求出为 We1l_D0nim+k_és[lgebra_am_i,发现并不是flag,原来原本题目中有个条件,即第二组数据为e!P0or_a,所以对上面的进行修改

flag为 We1l_D0ne!P0or_algebra_am_i

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值