4.elf z3暴力破解
装好了ubuntu
它的glibc版本够用
通过动态调试找到了其存储数据的正确顺序
先依次输入数组中存起来备用
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具体的大小来建模
所以可以设立多种情况
out1[i]=(flag[i]^0x47)+1#只经过前一次异或
out2[i]=(flag[i]^0x4B)-1#只经过后一次异或
out3[i]=(((flag[i]^0x47)+1)^0x4b)-1#两次异或都经过
out4[i]=flag[i]#未经过异或
所以约束条件可为
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])))
整体求解如下
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格式,无法具体限制其条件只能限制末尾是'}'之类的,但输入条件时就会报错
未输入其他条件就会有非常多的解下图只是一部分
只不过不知道z3中的And,Or是否效果跟原来的逻辑符and,or是否等效
但在我使用下列求解时
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")
其输出的是无解
非常奇特