PWN基础知识及基础栈溢出手法

本文详细介绍了栈溢出的概念、原理及其在x86和x64架构下的实现方法,包括return to libc技术、ROP(返回导向编程)以及GOT劫持。栈溢出涉及的主要寄存器、函数调用约定和危险函数也在文中进行了讲解,为理解安全漏洞和逆向工程提供了基础。
摘要由CSDN通过智能技术生成

一、pwntools常用函数

函数 用途
send(data) 发送数据(字符串形式发送)
sendline(data) 发送一行数据,默认在行尾加 \n(字符串形式发送)
recv(numb=1096,timeout=default) 接收指定字节数的数据
buf = p.recvuntil(“\n”, drop=True) 直到接收到\n为止,drop=True表示丢弃\n,buf为接收到的输出但不包括丢弃的\n
recvrepeat(timeout=default) 接收数据直到 EOF 或 timeout
recvall() 接收数据直到 EOF
recvline(keepends=True) 接收一行,可选择是否保留行尾的 \n
listen(端口) 开启一个本地的监听端口
remote(‘IP地址’, 端口) 与目标IP建立一个套接字管道与之远程交互(在线的)
interactive() 可同时读写管道,相当于回到 shell 模式进行交互,在取得 shell 之后调用
p8() p16() p32() p64() 把括号内数据打包成8位/16位/32位/64位的二进制数
u8() u16() u32() u64() 把括号内字符串解包成二进制数
process(‘文件路径’),p = process(argv=[‘./vuln’, payload]) 与本地文件建立一个交互通道,可传递参数
sendlineafter(“string”,payload) 接收到string后发送payload
close() 关闭交互的通道
ELF(‘文件路径’) 获取文件对象或者libc库对象
plt[‘函数名’] 获取函数在PLT表中的地址
got[‘函数名’] 获取函数在GOT表中的地址
symbols[‘函数名’]
或sym[‘函数名’]
获取函数plt地址,用在libc里面就是获取libc里的偏移地址
asm(“汇编指令”) 把汇编指令转换成对应的机器码,机器码是以字符串形式返回
bss(offset) 返回 .bss 段加上 offset 后的地址
asm(shellcraft.amd64.linux.sh(),arch=‘amd64’)(这里是指明x64环境,如果已经有context设置环境就直接写为asm(shellcraft.sh())) 生成shellcode,一般与asm进行联用,转为对应机器码
context(arch='amd64’或‘i386’,os=‘linux’,log_level=‘debug’) 设置环境
gdb.attach(p,‘b* main’) 调动gdb进行脚本调式

栈溢出

一、x86架构下的栈溢出

栈区:简单来说就是c语言中创建的局部变量(例如函数花括号里的变量)的存储位置。内存中的栈区指的是系统栈,由系统自动维护。

栈在程序加载进内存后就会出现

入栈:每个函数都有一个属于自己的栈帧空间,最先压入栈内的是函数的返回地址(用来返回到下一条指令),之后是函数的基地址、参数入栈。例如主调函数在调用函数a时,主调函数先存入自身栈帧的为返回地址、自身基地址、传入函数a的实参(如果有的话),然后替函数a创建一个新栈帧,在新栈帧中先压入函数a的返回地址(为了函数调用结束时,可以返回到下一条指令继续程序),再压入主调函数的基地址(函数调用结束时,返回到主调函数的基地址)以及函数a中的局部变量。此时是高地址往低地址生长(主调函数在的位置为高地址)

退栈:而函数调用结束,则与调用时相反,先从被调函数的局部变量开始直接弹出栈,栈顶指向存储着被调函数基地址(存储主调函数基地址),被调函数基地址被弹出后,释放出主调函数的基地址给ebp,然后将返回地址弹出交给eip去执行,之后便返回到下一条指令的地址(这里举例为主调函数直接调用一个函数,如果层层嵌套,则先会返回到上一个主调函数的栈帧),继续程序的运行,ebp指向此刻的主调函数的基地址

系统中当前正在运行的函数总是在栈顶

与函数状态相关的主要寄存器:esp,ebp,eip:

(1)esp:栈指针寄存器,存放一个指针,该指针永远指向系统栈正在运行的栈帧的栈顶(存储函数调用栈的栈顶地址),在压栈和退栈时发生变化

(2)ebp:基地址指针寄存器,该指针永远指向系统栈正在运行的栈帧的底部,在函数运行时不变,可以用来索引确定函数参数或局部变量的位置

(3)在esp和ebp之间的内存空间为当前栈帧

(4)eip:用来存储即将执行的程序指令的地址,cpu 依照 eip 的存储内容读取指令并执行,eip 随之指向相邻的下一条指令

因此,所谓的栈溢出漏洞,就是利用一些危险函数进行读取远超一个变量所需的数值,覆盖到相邻栈中的数值,从而修改相邻栈中的变量的值,往这些修改的值中注入我们所需要的跳转的例如shellcode,函数地址等,使程序崩坏或是让程序执行一些我们想要执行的程序,达到破坏的目的

x86下的CPU包含的8个四字节的通用寄存器:

在这里插入图片描述

寄存器使用约定:寄存器eax、edx和ecx为主调函数保存寄存器(caller-saved registers),当函数调用时,若主调函数希望保持这些寄存器的值,则必须在调用前显式地将其保存在栈中;被调函数可以覆盖这些寄存器,而不会破坏主调函数所需的数据。寄存器ebx、esi和edi为被调函数保存寄存器(callee-saved registers),即被调函数在覆盖这些寄存器的值时,必须先将寄存器原值压入栈中保存起来,并在函数返回前从栈中恢复其原值&#

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShouCheng3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值