ctfshow-数学不及格

打开查壳,找到主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v4; // [rsp+14h] [rbp-4Ch]
  char *endptr; // [rsp+18h] [rbp-48h] BYREF
  char *v6; // [rsp+20h] [rbp-40h] BYREF
  char *v7; // [rsp+28h] [rbp-38h] BYREF
  char *v8; // [rsp+30h] [rbp-30h] BYREF
  __int64 v9; // [rsp+38h] [rbp-28h]
  __int64 v10; // [rsp+40h] [rbp-20h]
  __int64 v11; // [rsp+48h] [rbp-18h]
  __int64 v12; // [rsp+50h] [rbp-10h]
  unsigned __int64 v13; // [rsp+58h] [rbp-8h]

  v13 = __readfsqword(0x28u);
  if ( argc != 5 )
  {
    puts("argc nonono");
    exit(1);
  }
  v4 = strtol(argv[4], &endptr, 16) - 25923;    // 将字符串类型转换为相应的long类型
  v9 = f(v4);
  v10 = strtol(argv[1], &v6, 16);
  v11 = strtol(argv[2], &v7, 16);
  v12 = strtol(argv[3], &v8, 16);
  if ( v9 - v10 != 0x233F0E151CLL )
  {
    puts("argv1 nonono!");
    exit(1);
  }
  if ( v9 - v11 != 0x1B45F81A32LL )
  {
    puts("argv2 nonono!");
    exit(1);
  }
  if ( v9 - v12 != 0x244C071725LL )
  {
    puts("argv3 nonono!");
    exit(1);
  }
  if ( (int)v4 + v12 + v11 + v10 != 0x13A31412F8CLL )
  {
    puts("argv sum nonono!");
    exit(1);
  }
  puts("well done!decode your argv!");
  return 0;
}

 查找函数可知strtol()函数的作用是将字符串类型转换为相应的long类型。接着往下看,有很多方程组,可以想到用z3约束器来接方程组,其中V10,v11,v12可以用v9来表示。最后argv sum的方程式可以转换为v4+3*v9=...

先进入f()函数,查看v9与v4的关系,

f()函数如下:

__int64 __fastcall f(int a1)
{
  int i; // [rsp+1Ch] [rbp-14h]
  __int64 v3; // [rsp+20h] [rbp-10h]
  _QWORD *ptr; // [rsp+28h] [rbp-8h]

  if ( a1 <= 1 || a1 > 200 )
    return 0LL;
  ptr = malloc(8LL * a1);
  *ptr = 1LL;
  ptr[1] = 1LL;
  v3 = 0LL;
  for ( i = 2; i < a1; ++i )
  {
    ptr[i] = ptr[i - 1] + ptr[i - 2];
    v3 = ptr[i];
  }
  free(ptr);
  return v3;
}

可以发现v4应该在1~200之间,想到爆破方法求出v4.v9.

爆破出来v4,v9 分别为58,591286729879;

然后写代码接出v10,v11,v12的解

from z3 import *


v10= Real('v10')
v11 = Real('v11')
v12 = Real('v12')


s = Solver()



s.add(591286729879 - v10 == 3563142128)
s.add( 591286729879- v11 == 27692482650)
s.add( 591286729879 - v12 == 367672337)
s.add(58+ v12 + v11 + v10 == 19163201824812)
if s.check() == sat:
     result = s.model()
     print(result)
else:
    print("no")
v1=hex(591286729879- 0x233F0E151C)
v2=hex(591286729879-0x1B45F81A32)
v3=hex(591286729879-0x244C071725)

print(v1)
print(v2)
print(v3)

解出来的十六进制数转换为字符串,得到flag

flag{newbee_here}

学到的点:

  • 尝试使用爆破方法解题
  • strtol()函数含义是具体用法(此处参考一位大佬的文章)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值