pwnable
blackjack
21点游戏,完全不懂规则。源代码中存在bug,再betting函数中,没有进行充分的输入限制,只要求输入金额小于现有金额,并再次要求输入。这里有俩个错误,1是可以直接输入负数,输掉游戏后直接胜利,2是连续两次输入非常大的金额,第二次不会要求重新输入而是直接bet,此时赢掉游戏即可胜利。
lotto
本题要求从标准输入流读入6个字符,这6个字符通过模运算将大小限制为1~45,之后是与一个未知数的比较,根据比较的那段代码可以看出,我们只需要输入中有一个字节与未知数匹配,match就能为6,这样我们可以将6个字节设置为相同的字节,而范围也已经确定是1~45,则我们可以通过标准输入流直接进行爆破。根据之前input一题构造标准输入流的方法,构造以下代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> int main(int argc, char* argv[], char* envp[]) { unsigned char c = 1; unsigned char submit[8] = {[0] = '1', [1] = ' ' }; pid_t child_pid; int pipe_stdin[2] = {-1, -1}; pipe(pipe_stdin); while (c <= 45) { child_pid = fork(); for (int i = 2; i < 8; i++) submit[i] = c; if (child_pid == 0) { close(pipe_stdin[0]); write(pipe_stdin[1], submit, 8); } else { close(pipe_stdin[1]); dup2(pipe_stdin[0], 0); execve("/home/lotto/lotto", argv, envp); } c++; } return 0; }
结果最终是跑出来了,但存在明显的bug,如何去掉该bug当前我还不知道,等对内核编程更加熟悉的时候再看吧。
reverse.kr
1.Easy_ELF:file命令查看文件格式为32位ELF可执行程序,拖入32位IDA,主函数调用了三个函数,分别是scanf的封装函数,判断结果的函数,打印的函数。进入判断结果的函数,发现是简单的内存对比,对三个字节进行了异或,再次异或即可还原,依次打印出ascii码即可
2.Easy_CrackMe:32位PE可执行文件,拖入32位IDA,运行程序发现是一个DialogBox程序,在导入表找到GetDialogText并跳转到代码调用处,发现也是明文对比,直接按顺序打印ascii码即可
3.Easy keygen:要求找出5B134977135E7D13序列号的用户名,用IDA打开程序,可以看到该程序要求先输入用户名,然后直接通过序列号算法将用户名转换为序列号与之后输入的序列号做对比。用户名的算法通过一个循环结构以及sprint函数完成,第一个参数为保存转换后序列号的地址,第二个参数为格式化字符串%s%x,第三个参数依然是序列号地址(在循环中每次把每个字符算出的序列号添加在已有数据之后),第四个参数即用户名当前位置i的字符c对应的序列号,它根据c ^ [16 ,32, 48][i % 3]得到,解密这个过程即可获取flag
4.Easy unpack:该程序被加壳,需要找到函数入口点,单步执行到入口点即可
看雪CTF2018
要逆向一个字典树的数据结构。没做出来。。。过一阵再上
南邮平台
WxyVM1
本题的逆向还是比较简单,主要有个十分大的数组(size=1.5w)需要获得,直接对文件数据进行读取然后对加密进行反向操作即可
f = open('WxyVM1', 'rb') f_conten = f.read() tmp = f_conten[0x1060:0x1060+24*4] m_data = f_conten[0x10c0:0x10c0+15000] tmp = list(tmp) m_data = list(m_data) box = [] for i in range(0, len(tmp), 4): num = 0 for j in range(4): num += tmp[i+j] << j*8 box.append(num) i = 14997 while i >= 0: v0 = m_data[i] v3 = m_data[i+2] result = v0 if v0 == 1: result = m_data[i+1] box[result] -= v3 elif v0 == 2: result = m_data[i+1] box[result] += v3 elif v0 == 3: result = m_data[i+1] box[result] ^= v3 elif v0 == 4: result = m_data[i+1] box[result] /= v3 elif v0 == 5: result = m_data[i+1] box[result] ^= box[m_data[i+2]] box[result] &= 0xff i -= 3 for j in range(len(box)): box[j] = chr(box[j]) print(''.join(box))