GXYCTF2019_simple_CPP
萧禾财 Lv4

知识考察

c++语言的基本语法

z3求解器的使用

查壳

image-20221023202154785

64位程序,无壳

开始逆

很容易找到main函数

image-20221023202344293

可以看到我们输入的值,存入了input(已改名)中,还可以看出输入的长度为30。

image-20221023202640901

这里有一个异或操作,输入的input和一串字符异或,查看字符为什么

image-20221023202824821

全为0,这是很不正常的,可能需要动调一下,之后在试

image-20221023203118181

首先还是检查长度 0<len<30

之后的函数是,将字符串(字符对应的数值)转化尾大整数存储 例:‘abz’ ->61 62 7a-> 61617a

这里以8个字节为一组存储,v16存前8位字符的数值、v15存第9~16位…. 这样子,不足补零

image-20221023204113293

后面这里将v16,v15,v14,v13存在一个数组v20中

image-20221023204234557

接下来对v20进行很多操作,这里可以用z3求解一下的v20的值,这题差不多就分析完了

求解

动调一下

image-20221023205154364

得字符串

image-20221023205238420

写一下z3代码

1
2
3
4
5
6
7
8
9
10
11
12
from z3 import*
x,y,z,w=BitVecs('x y z w',64)
s=Solver()
s.add((~x)&z==1176889593874)
s.add(4483974544037412639^w==4483974543195470111)
s.add(((z&~y)&x|z&((x&y)|y&~x|~(y|x)))==577031497978884115)
s.add(((z&~x)|(x&y)|(z&~y)|(x&~y))==4483974544037412639)
s.add(((z&(~x)) | (x&y) | y & z) == (((~x)& z)|864693332579200012))
s.check()
m=s.model()
for i in m:
print("%s = 0x%x"%(i,m[i].as_long()))

image-20221023205514929

将这些大整数一个一个字节得提取出来得未叠加过的字符串值,和动调出得字符串异或一遍后得flag

1
2
3
4
5
6
7
8
# tem='i_will_check_is_debug_or_not'
tem=[ 0x69, 0x5F, 0x77, 0x69, 0x6C, 0x6C, 0x5F, 0x63, 0x68, 0x65,
0x63, 0x6B, 0x5F, 0x69, 0x73, 0x5F, 0x64, 0x65, 0x62, 0x75,
0x67, 0x5F, 0x6F, 0x72, 0x5F, 0x6E, 0x6F, 0x74]
flag=[0x3E,0x3A,0x46,0x05,0x33,0x28,0x6F,0x0D,0x8C,0x00,0x8A,0x09,0x78,0x49,0x2C,0xAC,0x08,0x02,0x07,0x17,0x15,0x3E,0x30,0x13,0x32,0x31,0x06]
for i in range(len(flag)):
flag[i]=flag[i]^tem[i%27]
print(chr(flag[i]),end='')

image-20221023205958226

但这个算出来flag是不对的,好似原因是多解问题但我试了很多遍结果唯一,需要有提示才能得真正得解

y=e!P0or_a 比赛方的提示 打多刷题平台都没有提示,只有当时打比赛的人才知道

1
flag = We1l_D0ne!P0or_algebra_am_i
  • 本文标题:GXYCTF2019_simple_CPP
  • 本文作者:萧禾财
  • 创建时间:2022-10-23 20:19:00
  • 本文链接:https://ipartmentxhc.github.io/2022/10/23/GXYCTF2019-simple-CPP/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!