4.elf z3暴力破解

装好了ubuntu

它的glibc版本够用

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

image

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

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格式,无法具体限制其条件只能限制末尾是'}'之类的,但输入条件时就会报错

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

image

只不过不知道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")

其输出的是无解

image

非常奇特

posted @ 2023-01-06 23:14  润梧  阅读(99)  评论(1编辑  收藏  举报