先看read函数
函数名:write 头文件:<io.h> 函数原型: int write(int handle,void *buf,int len); 功能:获取打开文件的指针位置 参数:int handle 为要获取文件指针的文件句柄 void *buf 为要写入的内容 int len 为要写入文件的长度 返回值:返回实际写入文件内容的长度
那么这句就是从一串字符中获取长度为D的内容
转进下面函数
可以看到先是定义了一个buf变量,然后输入该变量后面200长度内容
但是看变量后面那句话
[rsp+0h] [rbp-80h]
主要看后面-80,就代表它实际上变量给的长度为80(这里暂时不详细解释)
那么很明显就是read读取长度长了,可以覆盖到别的内容
下一步就是寻找覆盖返回什么内容了,多看看可以发现一个callsystem函数
这个函数调用返回了system函数(它和“/bin/sh”连在一起可以给我提供类似cmd的功能),那么我们把vulnerable_dunction返回地址返回地址转到他身上不就ok了,这样我们就可以执行system函数了
下一步就是寻找vulnerable_dunction函数的返回值了
我们双击vulnerable_dunction里buf变量,就可以打开vulnerable_dunction的栈
这里显示buf变量80字节,然后是s 8个字节,然后r 8个字节。这里的r代表就是返回地址
我们想修改r那就要把前面的字节先填入好,这里不是填入88字节,因为这里都是16进制,因此要填入0x80+0x8个字节
然后r转到callsystem函数,查一下callsystem函数的位置
位置是0x400596(16进制)
那么payload就是 'a'*0x80+'a'*0x8+(0x400596)
我开始也奇怪为什么pwn最后都用python来输入,因为你nc过去不方便输入不可打印字符,而这里0x400596转换字符串是不可打印字符,因此用python传入比较方便
python:
from pwn import * r = remote("111.200.241.244","54479") #payload = b'1'*4 +p64(1853186401) payload=b'a'*0x80+b'a'*8+p64(0x400596) print(payload) r.sendline(payload) r.interactive()