跟着大佬学RE(四)

几个API函数

[ACTF新生赛2020]Universe_final_answer

一个很多方程组的函数,还有一个嗯,对input进行一些操作的函数

嗯,确实方程解出来得到 key 直接运行就可以得到 flag 了,不过还是去分析了一下。

v22 = __readfsqword(0x28u);                   // 获取栈保护值
  memset(space, 0, sizeof(space));
  v21 = 0LL;
  inputlen = strlen(input);
  index = 0;
  enc = 9;
  while ( index < inputlen )
  {
    v7 = input[index++];
    enc ^= v7;                                  // 计算校验值
  }
  if ( enc )
  {
    place = 0LL;
    space_pointer = space;
    while ( 1 )
    {
      space_pointer = (__int128 *)((char *)space_pointer + 4);// read a int
      v10 = place + 1;
      v11 = enc / 10;
      v12 = enc % 10;
      *((_DWORD *)space_pointer - 1) = v12;
      LOBYTE(v13) = v12;
      enc = v11;
      if ( !v11 )
        break;
      place = v10;
    }
    v14 = place - 1;
    v15 = a2;
    v16 = &a2[v10];
    v17 = &a2[place];
    for ( i = (int *)space + v14; ; --i )
    {
      *v15 = v13 + 48;
      if ( v17 == v15 )
        break;
      v13 = *i;
      ++v15;
    }
  }
  else
  {
    v16 = a2;
  }
  result = __readfsqword(0x28u) ^ v22;          // 读取栈保护值并与初始值 v22 进行异或操作
                                                // 检查栈是否被破坏
  *v16 = 0;                                     // 将输出缓冲区的最后一个字符设置为0
                                                // 作为字符串结束符
  return result;
}

是计算输入字符串的一个校验值,并将这个校验值转换为字符串形式存储在 a2指向的缓冲区。

最开始是硬解的 , 嗯,看了别人wp,意识到也可以用 angr 来解。

angr 脚本还是要搞些优化,不然半天跑不出来。

import angr
base_addr=0x400000
p=angr.Project('./universe',
               main_opts={"base_addr":base_addr},
               auto_load_libs=False)

init_state=p.factory.entry_state(add_options={angr.options.LAZY_SOLVES})

sm=p.factory.simgr(init_state)
sm.explore(find=base_addr+0x71A,avoid=base_addr+0x6ef)
if sm.found:
    found_state=sm.found[0]
    flag=found_state.posix.dumps(0)
    print(flag[:10])
else:
    print('no success')

那个 10 是自己算出来的长度,不然就是:

b'F0uRTy_7w@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\xeca@\x80\x02(\x91\x01' 

还有就是:在你当前的 angr 脚本中,输出结果中包含了很多非预期的字符,这是因为模拟过程中程序的输入没有正确处理,导致了缓冲区中存在未初始化的或多余的数据。这通常发生在模拟器没有严格控制输入长度或格式时。

1.缓冲区没有正确截断  2.输入数据没有被正确初始化

这是GPT给的脚本:

import angr
import claripy

# Initialize project
base_addr = 0x400000
p = angr.Project('./universe', 
                 main_opts={"base_addr": base_addr}, 
                 auto_load_libs=False)

# Create initial state
input_size = 100  # Adjust the size according to the expected input length
input_chars = [claripy.BVS(f'input_{i}', 8) for i in range(input_size)]
input_str = claripy.Concat(*input_chars + [claripy.BVV(b'\n')])  # Add a newline at the end

# Create initial state with symbolic input
init_state = p.factory.entry_state(stdin=input_str, add_options={angr.options.LAZY_SOLVES})

# Simulate the execution
sm = p.factory.simgr(init_state)
sm.explore(find=base_addr + 0x71A, avoid=base_addr + 0x6EF)

# Check if the solution is found
if sm.found:
    found_state = sm.found[0]
    # Extract the symbolic input from the state
    solution = found_state.solver.eval(input_str, cast_to=bytes)
    flag = solution.split(b'\x00')[0]  # Split to remove trailing null bytes
    print(flag.decode('utf-8', errors='ignore'))  # Decode to string and ignore errors
else:
    print('no success')

en,感觉还是按题型来刷比较好

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值