【PWN.0x03】Linux x86 用户态 Pwn 基本环境搭建
本文最后更新于:2024年5月15日 凌晨
信 Docker ,得永生
0x00.一切开始之前
CTF-wiki 上 Linux 用户态 Pwn 环境搭建的部分 Wiki 组咕了好久了, 作为 Pwn 模块默认的第一个页面,一直空着总归不是那么地雅观 ,因此作为 Wiki 组为数不多的活人(虽然也只是半个活死人罢了, 问就是 Wiki 组包括笔者在内的全员都在和牢大打复活赛 ),笔者决定还是找个时间给这一块补充上
虽然笔者已经很久很久很久没有正经做过用户态 Pwn 了,不过如果只是基础的常规题型的话,需要的工具其实基本上是万年不变的,因此笔者找了个时间( 其实就是在实验室偷偷摸鱼 )给这块内容稍微补充了一下,顺便水一篇博客这样子( 因为太忙 + 太懒实在是没写东西,简单混点更新 )
简介
现有的 CTF Pwn 题主要以 Linux 下的用户态 Pwn 为主,因此我们通常需要在本地拥有一个 Linux 运行环境,这通常可以通过安装 Linux 虚拟机来完成,此外你也可以在物理机上安装 Linux 操作系统。
绝大多数 Linux Pwn 题目的远程环境以 Ubuntu 为主,因此为了方便在本地调试题目,你通常需要搭建一个与题目版本相匹配的 Ubuntu 运行环境,不过 这并不意味着你必须要使用 Ubuntu 作为你的主力操作系统 。你仍旧可以选择继续使用你喜欢的其他 Linux 发行版(如,Arch、Debian、openSUSE、Fedora、NixOS 等),并使用 Docker 来搭建相应的 Ubuntu 做题环境。
传统 CTF Pwn 题目通常仅需要以下工具便能完成解题:
- IDA:用于对题目进行逆向分析。
- Python + pwntools:用于编写漏洞利用脚本。
- gdb + pwndbg/peda:用于调试题目二进制文件。
需要注意的是,在初学阶段我们并不推荐任何基于 pwntools 进行过度二次包装的软件包,也不推荐你在利用脚本中使用 lambda 语句进行过度简化,我们更推荐你在学习到一定程度后再去根据个人使用习惯进行决定。
此外,部分题目可能需要一些额外的环境(例如 kernel pwn 需要 qemu),我们将在后续介绍到对应题目时单独进行介绍。
0x01. 使用 Docker 搭建 CTF Pwn 做题环境(推荐)
为了保证利用脚本能够正常打通,我们通常需要在本地准备相同的运行环境,并在进行远程利用之前先在本地进行测试,但由于 CTF 题目远程环境众多,若是为每个不同的环境都单独准备一个 Ubuntu 虚拟机,则不仅要在每个虚拟机上都完整搭建一遍调试环境,且会占用大量磁盘空间,同时也无法保证本地环境小版本和远程环境一定相同——除非每个小版本都单独创建一个虚拟机并永不升级,这种解决方案并不优雅。
通过 LD_PRELOAD
参数在程序执行前 预先加载 libc 在某些程度上是一个可行的解决方案,在 libc 大版本相同的情况下载入不同的小版本通常并不会出现问题,但是由于不同系统环境中 ld 版本不同的缘故,对于跨 ld 版本加载不同版本的 libc 则可能出现 segmentation fault,从而导致无法正常运行与调试题目。
虽然 Linux 的用户环境并不似 Windows 那样有着强壮的二进制前向兼容性,但是用户环境依托于内核环境、依托于内核向用户态暴露的接口——系统调用,而这并不是会轻易发生变动以及兼容性破坏的一个东西,由此,通过重新开辟一个对应的新的用户环境的方式—— 即形如 Docker 这样的操作系统层上的虚拟化方案,我们便能非常简单地搭建不同的 Pwn 题所对应的原始环境。
Docker 环境搭建
Docker 的安装请大家根据自己所使用的 Linux 发行版自行参照 Docker 官网 或是发行版自己的 Wiki 进行配置,这里不再赘叙。
创建 Docker 镜像
我们以以下 Dockerfile 所创建的镜像作为模板,大家可以根据自己的需求自行修改:
1 |
|
在一个空白文件夹中创建一个名为 Dockerfile
的文件,并写入上述内容,随后运行如下指令:
1 |
|
完成之后你便拥有了一个名为 pwnenv_ubuntu22
的带有做题环境的 Ubuntu22 镜像,可以通过 docker images
指令查看:
1 |
|
你也可以根据需求修改第一行的基镜像,从而创建基于不同 Ubuntu 发行版的 docker 镜像。
从 Docker 镜像创建容器
我们只需要运行如下命令便能基于我们刚刚创建的 Docker 镜像创建一个新的容器,方便起见你可以将其创建为一个脚本,各参数说明如下:
-d
: 使容器在后台运行-p 25000:2222
: 容器的22
端口映射到本地的25000
端口--name=pwn22
: 容器名为pwn22
-v ~/Desktop/CTF:/CTF
: 将本地的~/Desktop/CTF
目录映射到容器中的/CTF
目录,这样我们便能在容器内访问到本地文件,而无需将文件重复拷贝进容器中pwnenv_ubuntu22
:创建容器所使用的镜像
1 |
|
之后通过如下命令便能进入到容器当中:
1 |
|
如果你不想将本地目录与容器进行共享,而是想要将所需文件拷贝一份到容器中,则可以使用 docker cp 命令:
1 |
|
由于我们为容器设置了 ssh 服务,我们也可以通过 ssh 连接入容器环境,这允许我们使用 vscode 等工具连接到容器内部:
1 |
|
若是容器环境被我们折腾坏了,则可以直接通过 docker rm 容器名
进行删除,之后再重新使用 docker run
创建新容器即可,需要注意的是这种方式会将新拷贝进容器的文件给删除(但不会删除挂载目录)。
将 Docker 容器接入本地图形界面
pwntools 自带的调试命令 gdb.attach()
需要创建新的窗口,而在容器中直接运行会失败,因此我们需要为容器接入本地的图形服务,以达成原生的运行效果(直接弹出一个新的窗口)。
若是觉得这种办法比较麻烦,也可以选择使用 tmux 配置多窗口,只需在运行
gdb.attach()
命令前运行context.terminal = ['tmux', 'splitw', '-h']
即可。
For Wayland
对于 Wayland 环境,在创建容器时我们需要额外附加一些参数:
1 |
|
之后在运行 gdb.attach()
之前运行如下 python 语句之一进行配置即可,请根据自己所使用的桌面环境进行选择。
1 |
|
For X11
对于使用 X11 图形服务的,在创建容器时我们则需要附加如下参数:
1 |
|
之后在运行 gdb.attach()
之前运行如下 python 语句之一进行配置即可,请根据自己所使用的桌面环境进行选择。
1 |
|
0x02. 在本地直接搭建 CTF Pwn 做题环境
除了使用 Docker 之外,你也可以直接在本地搭建做题环境,对于常规的 Linux 用户态 pwn 题目,我们通常仅需要如下软件:
- IDA:用于对题目进行逆向分析。
- Python + pwntools:用于编写漏洞利用脚本。
- gdb + pwndbg/peda:用于调试题目二进制文件。
获取 IDA
IDA Pro(interactive Disassembler Professional)是由 Hex-Rays 公司出品的一款交互式反汇编工具,也是软件逆向工程当中最流行的一个静态分析工具。通过 IDA Pro 我们可以很方便地复原二进制程序的运行逻辑,从而进一步审计出其中存在的漏洞。
IDA Pro 为付费软件,软件本体与不同架构的反编译引擎单独进行收费,你可以根据自己的需求在 Hex-rays 的官网自行购买相应的软件许可证以进行使用。
截至 2024 年 4 月, IDA Pro 本体许可证的价格为 1975 USD,任一指令集架构反编译功能的许可证价格为 2765 USD。
此外,Hex-rays 公司还提供基于云引擎的免费逆向工具 IDA Free,目前仅支持 x86 逆向,不过对于绝大部分 CTF 中 Linux 下的用户态 Pwn 题目而言通常已足够使用。
安装 Python
绝大部分 Linux 发行版目前已经自带 Python 运行环境,因此通常我们并不需要手动安装 Python。。若你的计算机上不存在 Python 运行环境,则可以根据自己所使用的发行版手动使用包管理器进行安装。
需要注意的是,部分 Linux 发行版中 Python 版本默认为 Python2,因此你可能需要手动指定安装 Python3。
配置 venv python 环境(可选)
在部分 Linux 发行版上(如 openSUSE Tumbleweed
)使用 pip
命令时,你可能会遇到如下报错,这是由于发行版自身安全策略限制的缘故:
1 |
|
对于这种情况,我们可以选择使用 venv 模块创建“虚拟环境”。虚拟环境在默认情况下与其他虚拟环境中的软件以及操作系统中安装的 Python 解释器和库保持隔离,这确保了软件包安装的安全性,且使得我们能够简单地删除并从头开始重建环境。
我们可以通过如下命令创建一个新的虚拟环境(若路径不存在,则将被创建):
1 |
|
完成创建之后,我们便可以通过 source
命令进入到 venv 中,请根据你所使用的 shell 进行选择其中之一:
1 |
|
你也可以选择将这条命令加入到
~/.bashrc
文件中,从而在打开 shell 时默认执行。
由于虚拟环境具有轻量、安全、可重构建的特性,因此即便是在你的计算机上并不存在安全策略限制,我们也更推荐你为 CTF/Pwn 创建一个单独的 Python 虚拟环境。
安装 pwntools
pwntools 是一个强大的 Python 软件包,其为我们提供了基本的 pwn 脚本编写环境,以及各类方便的利用工具,在安装好 Python 以及 pip 之后你可以很方便地使用如下指令进行安装:
1 |
|
之后在 Python 中便能很方便地通过 from pwn import *
指令使用该包中的各类工具,你也可以使用 from pwn import 名字
来仅导入所需的特定工具,或是使用 import pwn
导入包名后通过 pwn.名字
来使用对应的工具。
安装 gdb
GNU Debugger(GDB)是 GNU 项目开发的软件调试器,使用 gdb 我们可以很方便地对二进制程序进行动态调试。
gdb 在绝大部分 Linux 发行版上都已默认安装,你可以在 shell 中输入 gdb
命令进行确认(输入 q
退出):
1 |
|
若你的计算机尚未安装 gdb,则可以使用如下命令进行安装,请自行分辨你所使用的发行版。
Debian / Ubuntu:
1 |
|
openSUSE Leap / Tumbleweed / SLE:
1 |
|
Arch Linux / Manjaro / EndeavourOS:
1 |
|
Fedora / CentOS / RHEL:
1 |
|
安装 pwndbg
pwndbg (/paʊnˈdiˌbʌɡ/) 是一个强大的 GDB 插件,通过该插件我们可以在调试时很方便地查看运行环境以及获取堆内存布局等信息。
pwndbg 项目自带了安装脚本,因此我们可以很方便地从源码进行安装:
1 |
|
对于使用 nix 包管理器的发行版(如 NixOS),你可以通过如下命令进行安装:
1 |
|
安装 peda
注:peda 和 pwndbg 你只需要安装其中之一,由于功能重复,且为了避免插件冲突,我们并不推荐你同时安装这两个插件。
peda 是一个强大的 GDB 插件,通过该插件我们可以在调试时很方便地查看运行环境以及获取堆内存布局等信息。
peda 插件无需过多配置,我们只需要将源码下载到本地后更新 gdb 配置即可。
1 |
|
0x03. 杂项配置
为 Linux 下运行 IDA 配置 desktop shortcut
wine 对于 Windows 各种 API 的重写已经非常成熟了,这使得 IDA Pro 的 Windows 版本(或许也是绝大多数人会使用的版本)能够比较轻松地在 Linux 下运行,对于完全工作在 Linux 下的同学这是一件好事,因为这意味着不需要使用虚拟机来单独运行 IDA Pro
对于想要为 IDA 创建快捷方式的 Linux Desktop 用户,你可以参考如下模板编写 .desktop
文件:
1 |
|
完成编写后将该文件放到 ~/.local/share/applications/
目录下即可: