[记录]常规栈溢出小结

Author : W22

这几天在学栈溢出,随手做的一些笔记 希望可以跟大家一起学习进步

————————————————————

常见溢出函数:

gets#读取字符

scanf#输入

strcpy#拷贝

sprintf#打印

memcpy#拷贝内存

strcat#拼接

….


常见保护机制:

ASLR:地址随机化

DEP(数据执行保护):可写的不可以执行,可以执行的不可以写

PIE(地址无关可执行文件):gcc编译时加上-fPIC -pie就可以开启,开启后data和code会地址随机化

Stack Guard:对栈溢出的保护机制,在函数调用时在stack前放上canary


常见类型:

1.ret2text#返回到程序本身

一般这种比较简单,大概程序为:


1.找溢出点

2.找system函数

3.覆盖ret到system

2.ret2shellcode#返回到自己输入的shellcode


1.找溢出点

2.找全局变量 .bss段的内容

3.赋值全局变量为自己的shellcode

4.找ret

5.控制ret跳转到自己的shellcode

3.ret2lilb#找lib库中的一些函数来用

还有一种直接给出libc的某个函数的地址 例如



ROPgadget#查找rop

ROPgadget –binary ./文件名

ROPgadget –binary ./文件名 –opcode <按操作符找 #eg:cd80c3>


tips:可以写入一个文本中 进行分析


1.找一个函数的.got.plt地址

ida里直接查看

2.找到基地址,方法见3

3.[重点]获取所用到的函数的地址(找libc的基地址(base)=实际地址-偏移地址)

实际地址:

输入.got.plt后获取到实际地址

实际中不一定会给,要自己调用一个函数把值传进去(一般会给一个lib.so)

可以利用puts 把函数的plt地址打印出来 就是实际libc的地址

被泄露的函数为got,要使用的函数为plt

plt# objdump -d -M intel

gdb调试执行后 info functions 函数名

偏移地址:

方法1:

ldd查看调用了哪个libc库

readelf -s libc库 |grep 需要找的函数

方法2:

pwntools中

from pwn import * libc = ELF(‘libc库’) 函数名_off = libc.symbols[‘函数名’]

(在指定了libc地址后 symbol为实际地址)

4.找到基地址后,就可以构造出其他地址的偏移地址写rop

方法:基地址+其他函数的偏移地址,偏移地址找法见3

5.找buffer的地址(参数,一个可写的地址)

vmmap

cat /proc/<pid>/maps

6.写bin sh进去

eg1:使用gets

rop=[

gets,

system,

buf,

buf

]

sendline(‘/bin/sh\x00’)

eg2:在libc中找binsh

binsh_addr = libc.search(‘/bin/sh’).next() //圆括号

system,

0x41414141,

binsh_add

栈转移

1.找gadget #leave ; ret

leave = mov esp,ebp ; pop ebp

在leave ret之前 把ebp的值改成一个新的值

pop ebp ret

buf-4#把ebp减掉,正好是rop2

核心: 找到gadget后 如何去堆栈

ROP:利用现有的片段组合出想要的功能

控制寄存器做systemcall(绕过DEP)

关键:给eax,ebx,ecx,edx(参数)赋值

pop eax;

2

相当于mov eax,2

使用原有程序里的function(绕过DEP)

使用libc里的gadget或function(绕过ASLR)

Gadget:一小段以ret结尾的code,组合起来 成为rop-chain

常用gadget

pop ebp ; ret

pop ebx , ecx , edx ; ret

leave ; ret


发表评论

电子邮件地址不会被公开。 必填项已用*标注