4.elf

runwu2204 Lv6

装好了ubuntu

它的glibc版本够用

通过动态调试找到了其存储数据的正确顺序

image-20230106230217327

先依次输入数组中存起来备用

1
2
3
4
5
6
7
8
9
10
11
12
if ( v3 == v9 )
{
for ( i = 0; i <= 16; ++i )
{
if ( (unsigned __int8)s[i] > 0x60u && (unsigned __int8)s[i] <= 0x7Au )
s[i] = (s[i] ^ 0x47) + 1;
if ( (unsigned __int8)s[i] > 0x40u && (unsigned __int8)s[i] <= 0x5Au )
s[i] = (s[i] ^ 0x4B) - 1;
v6[2 * i] = (unsigned __int8)s[i] >> 4;
v6[2 * i + 1] = s[i] & 0xF;
}
}

根据其加密方式需要判断输入的字符的大小,z3无法检验flag具体的大小来建模

所以可以设立多种情况

1
2
3
4
out1[i]=(flag[i]^0x47)+1#只经过前一次异或
out2[i]=(flag[i]^0x4B)-1#只经过后一次异或
out3[i]=(((flag[i]^0x47)+1)^0x4b)-1#两次异或都经过
out4[i]=flag[i]#未经过异或

所以约束条件可为

1
f.add(((a[2*i]==v61[2*(17-i)-2])and(a[2*i+1]==v61[2*(17-i)-2]))or((a[2*i]==v62[2*(17-i)-2])and(a[2*i+1]==v62[2*(17-i)-2]))or((a[2*i]==v63[2*(17-i)-2])and(a[2*i+1]==v63[2*(17-i)-2]))or((a[2*i]==v64[2*(17-i)-2])and(a[2*i+1]==v64[2*(17-i)-2])))

整体求解如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from z3 import *
a=[
0X07,0X0D,0X00,0X05,0X01,0X0C,0X01,
0x00,0x00,0x0D,0X05,0X0F,0X00,0X09,
0X05,0X0F,0X03,0X00,0X02,0X05,0X03,
0X03,0X01,0X07,0X07,0X0B,0X02,0X01,
0X02,0X07,0X02,0X0C,0X02,0X02,0X00]
flag = [BitVec('flag[%2d]' % i, 8) for i in range(17)]
out1=[0]*17
out2=[0]*17
out3=[0]*17
out4=[0]*17
v61=[0]*34
v62=[0]*34
v63=[0]*34
v64=[0]*34
v0=0
for i in range(17):
out1[i]=(flag[i]^0x47)+1
out2[i]=(flag[i]^0x4B)-1
out3[i]=(((flag[i]^0x47)+1)^0x4b)-1
out4[i]=flag[i]
v61[2*i]=out1[i]>>4
v61[2*i+1]=out1[i]&0xF
v62[2*i]=out2[i]>>4
v62[2*i+1]=out2[i]&0xF
v63[2*i]=out3[i]>>4
v63[2*i+1]=out3[i]&0xF
v64[2*i]=out4[i]>>4
v64[2*i+1]=out4[i]&0xF
f=Solver()
for i in range(17):
f.add(((a[2*i]==v61[2*(17-i)-2])and(a[2*i+1]==v61[2*(17-i)-2]))or((a[2*i]==v62[2*(17-i)-2])and(a[2*i+1]==v62[2*(17-i)-2]))or((a[2*i]==v63[2*(17-i)-2])and(a[2*i+1]==v63[2*(17-i)-2]))or((a[2*i]==v64[2*(17-i)-2])and(a[2*i+1]==v64[2*(17-i)-2])))
while(f.check()==sat):
condition = []
m = f.model()
p=""
for i in range(17):
p+=chr(int("%s" % (m[flag[i]])))
condition.append(flag[i]!=int("%s" % (m[flag[i]])))
print(p)
f.add(Or(condition))

上述代码是有解的,但增加约束条件时会抽风

因为不知道具体flag格式,无法具体限制其条件只能限制末尾是’}’之类的,但输入条件时就会报错

未输入其他条件就会有非常多的解下图只是一部分

image-20230106231208987

只不过不知道z3中的And,Or是否效果跟原来的逻辑符and,or是否等效

但在我使用下列求解时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from z3 import *
a=[
0X07,0X0D,0X00,0X05,0X01,0X0C,0X01,
0x00,0x00,0x0D,0X05,0X0F,0X00,0X09,
0X05,0X0F,0X03,0X00,0X02,0X05,0X03,
0X03,0X01,0X07,0X07,0X0B,0X02,0X01,
0X02,0X07,0X02,0X0C,0X02,0X02,0X00]
flag = [BitVec('flag[%2d]' % i, 8) for i in range(17)]
out1=[0]*17
out2=[0]*17
out3=[0]*17
out4=[0]*17
v61=[0]*34
v62=[0]*34
v63=[0]*34
v64=[0]*34
v0=0
for i in range(17):
out1[i]=(flag[i]^0x47)+1
out2[i]=(flag[i]^0x4B)-1
out3[i]=(((flag[i]^0x47)+1)^0x4b)-1
out4[i]=flag[i]
v61[2*i]=out1[i]>>4
v61[2*i+1]=out1[i]&0xF
v62[2*i]=out2[i]>>4
v62[2*i+1]=out2[i]&0xF
v63[2*i]=out3[i]>>4
v63[2*i+1]=out3[i]&0xF
v64[2*i]=out4[i]>>4
v64[2*i+1]=out4[i]&0xF
f=Solver()
for i in range(17):
f.add(Or(And((a[2*i]==v61[2*(17-i)-2]),(a[2*i+1]==v61[2*(17-i)-2])),And((a[2*i]==v62[2*(17-i)-2]),(a[2*i+1]==v62[2*(17-i)-2])),And((a[2*i]==v63[2*(17-i)-2]),(a[2*i+1]==v63[2*(17-i)-2])),And((a[2*i]==v64[2*(17-i)-2]),(a[2*i+1]==v64[2*(17-i)-2]))))
if f.check()==sat:
print("yes")
else:
print("error")

其输出的是无解

image-20230106231121538

非常奇特

  • 标题: 4.elf
  • 作者: runwu2204
  • 创建于 : 2023-01-06 22:54:33
  • 更新于 : 2023-01-07 01:14:48
  • 链接: https://runwu2204.github.io/2023/01/06/CTF WP/Re/pythonz3/4.elf/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
4.elf