学习PWN一个月后能做什么?

本文介绍了作者学习PWN一个月后的成果,涵盖了栈溢出、格式化字符串、整数溢出漏洞的原理与利用方法,包括ret2shellcode、ret2syscall、ret2libc等技术,并通过攻防世界题目举例说明。通过学习,作者掌握了栈溢出的利用技巧,如ret2text、ret2shellcode、ret2syscall,以及格式化字符串漏洞的利用,包括信息泄露和修改内存。此外,还探讨了整数溢出漏洞的利用策略。
摘要由CSDN通过智能技术生成

本文为笔者初学pwn的知识梳理,如有错误之处,敬请斧正。

栈溢出漏洞

原理

栈是一种后进先出的数据结构。在调用函数的时候,都会伴随着函数栈帧的开辟和还原(也称平栈)。栈结构示意图如下(以32位程序为例):

如图所示,栈空间是从高地址向低地址增长的。但是,若函数中用到了数组作为局部变量时,向数组的赋值时的增长方向是从低地址到高地址的,与栈的增长方向相反。若对未限制数组的赋值边界,则可能对数组进行恶意的越界写入,便会把栈中的数据覆盖,造成栈溢出漏洞。常用的造成栈溢出漏洞的函数有:scanf,gets,strcpy,strcat,sprintf等。

如果对覆盖栈的内容进行精心构造,就可以在返回地址的位置填入我们希望函数返回的位置,从而劫持程序的执行。由于在编写栈利用 shellcode 过程中都需要用到ret指令,所以这样的利用方式被成为ROP

面对返回编程

ROP(Return-oriented programming)是指面向返回编程。在32位系统的汇编语言中,ret相当于pop EIP,即将栈顶的数据赋值给 EIP,并从栈弹出。所以如果控制栈中数据,是可以控制程序的执行流的。由于 NX 保护让我们无法直接执行栈上的 shellcode,那么就可以考虑在程序的可执行的段中通过 ROP 技术执行我们的 shellcode。初级的 ROP 技术包括 ret2text,ret2shellcode,ret2syscall,ret2libc。

ret2text

ret2text是指返回到代码段执行已有的代码。在 pwn 题中这种情况通常出现在程序里已经有system("/bin/sh")system("cat flag")。需要做的就是把这些调用的地址覆盖到返回地址处即可。

下面使用攻防世界中的 level0 题目作为例子进行解释。

checksec 指令查看程序的保护情况,有 NX 保护(No-eXecute,即数据不可执行保护)。考虑使用 ROP 技术进行利用。

漏洞代码:

可以看到,read函数可以读取0x200字节存入缓冲区,但是缓冲区只有0x80字节,可造成越界写入。

system 函数:

使用 pwndgb 插件的 cyclic 指令确定出返回的偏移为 136,所以构造填充字符大小为136个字节,后面紧接的便是返回的地址。控制这个返回的地址即可控制程序的执行流执行到我们指定的 system 函数。

EXP如下:

from pwn import *
r = remote("111.200.241.244", 57216)
payload = 'A' * 136 + p64(0x00400596)
r.sendlineafter("Hello, World\n", payload)
r.interactive()

在本地调试时执行脚本后可以看到,在执行vulnerable_function执行返回时, 0x88(136) 的位置已经被修改为system函数的地址。

ret2shellcode

如果 pwn 题中没有提供system函数,我们可以自己编写 shellcode 来执行相关 system 函数。

在没有 NX 保护的情况下,可以直接将函数的返回地址覆盖为 shellcode 的地址,在函数返回时控制程序执行流到 shellcode 出执行。被覆盖 shellcode 后的栈空间的形态如下图所示(图中只展示一种 shellcode 的位置,但实际上可以根据具体情况选择):

其中 padding 的长度可以使用 pwndbg 插件 中的 cyclic或者 peda 插件 pattern指令生成字符串模板并结合动态调试观察栈来确定。在 pwn 题目中,我们一般可以通过找到system函数地址,通过 shellcode 调用执行,就可以拿到 flag。所以在写 shellcode 过程中,我们按照 linux 系统调用的方式调用system函数的底层的sys_execve函数,传入/bin/sh作为参数即可。shellcode 可以使用 pwntools 工具编写,若需要更精简或特殊定制的 shellcode,也可以自己编写。具体的编写方式可以参考博客https://www.cxyzjd.com/article/A951860555/110936441。需注意的是,在生成 shellcode 之后需要进行字符的填充,使其保证具有足够的字节数覆盖到返回地址处。

我们用以下例子进行演示说明:

#include<stdio.h>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值