俚语词,象征着黑客成功入侵,在数据溢出后,向目标发出特定的数据,使其执行我们的恶意代码
eg.永恒之蓝病毒
web的XXS
当要表示的数据超出计算机所使用的数据的表示的范围时,则产生数据的溢出
原因
1:使用非类型安全(non-type-safe)C,C++等
C,C++没有进行边界的检查,比如数组,下标越界
2:以不可靠的方式存取或复制内存缓冲区
我们常用的一些函数没有对长度进行限制
3:编译器设置的内存缓冲区太靠近关键数据
栈的缓冲区和里面核心代码段太近了,核心代码容易被覆盖
PWN常用寄存器:ESP,EBP,EIP
ESP:用来存储函数调用栈的栈顶地址,在压栈和退栈时发生变化
push,pop
EBP:用来存储当前函数状态的基地址,在函数运行不变,可以用来索引确定函数参数或局部变量的位置
EIP:用来存储即将执行指令的地址
IP:16位
EIP(扩展的16位):32位
32位x86架构下汇编指令有两种格式intel与AT&T
intel:寄存器名称和数值前无符号
AT&T:寄存器名称前加“%”,数值前加“$”
MOV
数据传输指令,将SRC传至DST,
格式为:MOV DST ,SRC;
PUSH
压入堆栈指令,将SRC压入栈中,
格式为:PUSH SRC;
POP
弹出堆栈指令,将栈顶数据弹出并存至DST,
格式为:POP DST;
add / sub
加减法指令,将计算结果存到DST,
格式为:ADD/SUB DST , SRC;
lea
取地址指令,将MEM的地址存入REG,
格式为:LEA REG,MEM;
call
调用指令,将当前的eip压入栈顶,并将PTR存入eip,
格式为:call ptr;
栈的结构,是从下到上的,栈是从大地址到小地址,越来越小,如果满了的话就溢出了
HIGHT ADDR——>LOW ADDR/栈顶
EBP访问——>局部变量
-4返回局部变量1
-8返回局部变量2
+4返回地址
+8实际参数#1
+12实际参数#2(注:12为16进制)
ESP——>栈顶
栈帧:函数的执行环境
函数参数,函数变量,函数返回到哪里等
每一个栈帧代表一个未运行完的函数
.输入sudo su
使用管理员权限
不是变成这个
是这个
这样就是root权限了
我们可以看到 $ 变成了 #
PS:有些是要输入密码的,虚拟机输入密码是看不见的,直接输完,Enter就行
几个指令
.我们可以看到桌面有个文件夹
这样我们就可以操作文件夹里面的东东了
如果里面还有文件夹可以继续使用cd,直到找到你想操作的文件
如何建立一个.c的文件
touch 111.c //111是我瞎取名的
然后我们已经是在这个pwn的文件夹里面了
所以会多出一个111.c的文件
当然,111感觉不吉利的话我们可以通过下面的指令来删除它
rm -f 111.c
.接下来用到vi
关于vi编辑器
学习传送门
touch hello.c
vi hello.c
然后进入编辑
这个时候表示我们可以修改,按键盘上的insert键或者键盘上面的“i”键也是可以进入修改模式的
按“esc”退出该模式
如何退出vi?
“shift”+";"打出“:”即可进入末行模式(记得之前一定要退出其他模式)
然后最后一行就会出现这个
然后我们可以通过输入wq来保存退出,q!为强制退出
关于文件提权
我们可以就看到我们新建立的文件上面有个小锁
再看看权限
这样的文件是操作不了的
所以我们需要进行提权
输入chmod 777 hello.c
赋予它最高的权限
然后我们就可以使用它了
觉得很麻烦的话,还有一种更麻烦的方法,就是在桌面建立一个“文本文档”
拖进ubuntu,改后缀名改成“XXX.c”,之后点进去进行编辑也是可以的【doge】
.编译文件
输入gcc -m32 -o test hello.c
进行编译(32是标注32位来编译程序,避免出来是64位,-o是输出)
error,warning一目了然
.用GDB进行反汇编
这里笔者的GDB出了一点问题没办法编译,就暂时贴上别人的图片了,之后我会改回去的
输入disass main
我们的函数是main函数,所以用disass对main进行反汇编
有哪些指令一目了然
然后disass test
然后我们可以在主函数下下一个从断点
输入b *0x080483f6
加星号代表那是一个地址
输入 b text
也是可以断点的
输入r
运行,跑起来
断点很清晰
push ebp ,把原来的栈保存了一下
n
输入n
下一步指令(后面的继续自行输n
)
我们可以看到ebp已经被压入栈了
然后
然后栈顶和ebp重合,以当前esp为基准
继续可见
之后
esp会往上移动四格
相当于esp向上申请了一段内存空间
继续
1是我们的第一个函数参数
前面图片,有一个c源码的,test(1,2)的1
将参数1进行加八,放到edx里面)
继续n
同理参数2被放到EAX中
接下来
相加保存至EAX
之后EAX变成3
继续
将其写到我们之前申请的内存空间中
EBP -4一般就是申请栈空间
+4一般就是清理堆栈
继续
把返回值放到eax里面(一般看到eax代表函数返回值)
先把ebp放到esp
即把
esp的这一堆释放掉,使得他们合二为一,让esp指向ebp
之后pop弹栈
很显然是我们main函数的ebp
相当于还原了,这个函数执行前,执行后栈是保持不变的,除了返回值这些,即函数执行完不影响堆栈
继续
我们可以看到还原了
我们可以看到此时esp.ebp均指向main函数(其实差不多可以说重合了吧)
继续
+释放空间
我们可以看到下一步有压栈的操作,所以这一步直接清理了
之后我们栈顶也回到一起了
之后main函数调用完了,我们清理EAX(赋值为0)
之后差不多就运行完了
删除断点
delete <断点id>
注意
ebp是d548
执行之后我们发现这些几乎都没有变()除了EAX,只是返回了一个结果,对栈堆的影响是没有的
此外补充
si(step会执行到函数内部)
我们在遇到call的时候,需要“步入”,即输‘si’才能知道call里面是什么