re题(14)babyre

 下载:

链接: https://pan.baidu.com/s/1namyd7m2SrKpSzNrbCEoYg

提取码: 1234 

 

用ida打开文件,发现一点线索也没有

dccef94d0f0c43cab72b7ae332a1e08a.png

 

 

查一下壳,带着upx壳

 

 

b45d8714f5fb4d6aa31e5e1c1a06c309.png

 

 

用命令脱一下壳

可是我脱完壳之后用ida再打开还是没脱壳的样子,而再查壳是脱壳的状态,于是我拿着没脱壳的文件看了两天/(ㄒoㄒ)/~~,后来知道应该是我最开始用ida打开过了,不知道怎么回事只剩下一个ida打包的文件,把ida打包的文件脱壳之后再打开还是原来的样子,把文件删了再下载重新做就好了

 

 

bb0d37b8289249d5ae085433c8a5e689.png

 

脱完壳用ida打开,找到main函数反汇编,分析一下

part1-4是输入四个数并分别处理过了,然后v12也就是flag就是处理过的四个数,分析后边对v12的操作,发现对v12没有影响,所以直接算四个数就好了

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  unsigned __int64 v3; // rax
  unsigned int v5; // [rsp+0h] [rbp-110h] BYREF
  unsigned int v6; // [rsp+4h] [rbp-10Ch] BYREF
  unsigned int v7; // [rsp+8h] [rbp-108h] BYREF
  unsigned int v8; // [rsp+Ch] [rbp-104h] BYREF
  char v9[96]; // [rsp+10h] [rbp-100h] BYREF
  __int64 s2[2]; // [rsp+70h] [rbp-A0h] BYREF
  char s[32]; // [rsp+80h] [rbp-90h] BYREF
  char v12[104]; // [rsp+A0h] [rbp-70h] BYREF
  unsigned __int64 v13; // [rsp+108h] [rbp-8h]

  v13 = __readfsqword(0x28u);
  v5 = 0;
  printf("Part 1: ");
  __isoc99_scanf("%u", &v5);
  if ( (unsigned int)sub_1229(v5, -1380855784) )// v5==3821413212
    goto LABEL_7;
  v6 = 0;
  printf("Part 2: ");
  __isoc99_scanf("%u", &v6);
  if ( (unsigned int)sub_1257(v6) )             // v6==98124621
    goto LABEL_7;
  v7 = 0;
  printf("Part 3: ");
  __isoc99_scanf("%u", &v7);
  if ( (unsigned int)sub_12A4(v7) )             // v7==78769651
    goto LABEL_7;
  v8 = 0;
  printf("Part 4: ");
  __isoc99_scanf("%u", &v8);
  if ( (unsigned int)sub_1346(v8) )             // v8==4017045635
    goto LABEL_7;
  memset(s, 0, sizeof(s));
  sprintf(v12, "flag{%08x-%08x-%08x-%08x}", v5, v6, v7, v8);// flag{0xe3c6235c-0x5d9434d-0x4b1edf3-0xef6f4083}
                                                // flag{0x-372526695}
                                                // 
  sub_2481((__int64)v9);                        // 对v9变换
  v3 = strlen(v12);
  sub_24D3((__int64)v9, (__int64)v12, v3);      // 用flag对v9变换,flag没变
  sub_2578((__int64)v9, (__int64)s);            // 用v9对s变换
  s2[0] = 0x5C338CC28AC3B9C9LL;
  s2[1] = 0x4982C83EACACDBE0LL;                 // s2存的内容
  if ( memcmp(s, s2, 0x10uLL) )                 // s和s2对比
  {
LABEL_7:
    puts("Wrong!");
    return 0LL;
  }
  else
  {
    puts("Right!");
    printf("Your flag is: %s\n", v12);
    return 0LL;
  }
}

 

 

 

 

 

四个数的处理就是四个算式

要人工解四个算式的话基本不可能

所以我们要用到python的模块

 

df56615cba2b41938339398a896569dc.png

 

575b356436ba4e9f810cf3d421a89592.png

 

 

 

 

7f7250fac77c4683936fda2c99f66989.png

 

用python的z3模块就ok了

在这里学习:Z3求解器基础学习 (一) 从例子入门 - 说芬兰语的雪 - 博客园 (cnblogs.com)

 

from z3 import *

s = Solver()  # 设置一个解方程的类Solver(必须要设置)

v5=BitVec('v5',32)
v6=BitVec('v6',32)
v7=BitVec('v7',32)
v8=BitVec('v8',32)

s.add(v5 + 1380855784 == 907301700)

s.add((v6 | 0x8E03BEC3) - 3 * (v6 & 0x71FC413C) + v6 == -1876131848)

s.add(v7<=0x10000000)
s.add(4 * ((~v7 & 0xA8453437) + 2 * ~(~v7 | 0xA8453437))
     + -3 * (~v7 | 0xA8453437)
     + 3 * ~(v7 | 0xA8453437)
     - (-10 * (v7 & 0xA8453437)
      + (v7 ^ 0xA8453437)) == 551387557)

s.add(v8<=0x10000000)
s.add(11 * ~(v8 ^ 0xE33B67BD)
     + 4 * ~(~v8 | 0xE33B67BD)
     - (6 * (v8& 0xE33B67BD)
      + 12 * ~(v8 | 0xE33B67BD))
     + 3 * (v8 & 0xD2C7FC0C)
     + -5 * v8
     - 2 * ~(v8 | 0xD2C7FC0C)
     + ~(v8 | 0x2D3803F3)
     + 4 * (v8 & 0x2D3803F3)
     - -2 * (v8 | 0x2D3803F3) == -837785892)

print(s.check())#check是保证有解
answer=s.model()#model是输出运算结果
print(answer)

 

用z3解完得到4个数,但是提交flag是不对的,我们用devc爆破一下(c语言爆破更快),爆破就是

循环遍历一个范围,来找符合公式的数

be305dd3cae14b4bac325133d0adecc7.png

 

爆破完,发现是v8出错了,下面是v8的爆破

0439693761484791a60b8679cb4034d1.png

 

得到flag

 

data=[3821413212,98124621,78769651,67321987]
print('flag{'+'%08x-'%data[0]+'%08x-'%data[1]+'%08x-'%data[2]+'%08x'%data[3]+'}')

#flag{e3c6235c-05d9434d-04b1edf3-04034083}

 

此题用到了python的z3库,z3库主要用来解方程,还用到了爆破,爆破就是在一个数字范围内进行循环,把数字代入公式,直到找到一个数字代入之后与正确结果相同

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值