几个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,感觉还是按题型来刷比较好