本文主要是介绍跟着大佬学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 intv10 = 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 statesolution = found_state.solver.eval(input_str, cast_to=bytes)flag = solution.split(b'\x00')[0] # Split to remove trailing null bytesprint(flag.decode('utf-8', errors='ignore')) # Decode to string and ignore errors
else:print('no success')
en,感觉还是按题型来刷比较好
这篇关于跟着大佬学RE(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!