
刚学pwn那会儿我踩过最大的坑不是看不懂ROP而是环境搭得稀烂。第一次兴致勃勃跟着教程跑一个堆利用demo程序在物理机上执行到一半直接把我的home目录吐了个乱七八糟几个还没保存的writeup也跟着遭殃。后来才明白pwn题本质上是拿一个充满漏洞的二进制文件在你的机器上做实验有些题目甚至会自带破坏性逻辑物理机上裸奔纯属赌命。这篇pwner入门宝典要解决的就是最让人头大的第一步从创建虚拟机到配置一套能正经打CTF题的pwn环境。我会把这套流程按我实际操作的顺序拆开每一步都说明为什么这么做适合所有新人照着一步步来。1. 为什么pwner非要虚拟机不可物理机裸奔的代价与VMware选型理由1.1 隔离不是洁癖是CTF题目的基本卫生习惯很多人刚开始学pwn觉得题目不就是个本地程序吗直接在物理机上跑不就行了我第一次也是这么想的直到被那个“自带删除功能”的题目教育了一顿。CTF的pwn题里漏洞利用成功后往往意味着你拿到的是一个shell一旦你在物理机上拿到的是自己的shell倒还好但如果题目本身藏了恶意逻辑比如尝试删除文件、修改权限、写入开机启动项你的开发环境、个人文件、甚至整个系统都可能变成试验品。虚拟机加快照就是给这个风险上一个保险。不管题目把虚拟机内部折腾成什么样我只要回滚快照系统立刻恢复成干净状态。pwner真正该练的是漏洞分析和利用能力而不是反复重装系统的能力。所以不管你是Windows、macOS还是Linux用户只要想认真学pwn第一件事就是划出一个虚拟化隔离的“实验区”。除了安全隔离还有个现实问题不同题目依赖不同版本的libc、不同架构的运行环境。今天这个题要glibc 2.31明天那个题要2.35直接在物理机上一通乱装很快库和库之间就会打架。虚拟机里跑一套独立的环境物理机上的日常工作完全不受影响。我见过有人在物理机上装了一堆pwn工具之后连日常开发都开始报奇怪的链接错误就是因为环境被污染了。1.2 VMware与VirtualBox怎么选免费、稳定、教程多虚拟机软件的选择我一直推荐VMware Workstation Pro。以前它是收费的很多人为此纠结但现在VMware Workstation Pro已经面向个人用户免费个人非商业使用直接下载安装就能用。如果你不想折腾VirtualBox开源免费也是完全可以的功能同样足够。不过对pwn入门来说我仍然建议优先VMware。理由是网上能找到的pwn环境搭建教程十个里有八个用的都是VMware遇到问题搜解决方案时对照着做最省心。VMware在稳定性、显示效果、共享文件夹的易用性上都做得比较成熟。VirtualBox也不是不行只是你踩坑时需要花更多时间去适配。工具这事不必纠结“哪个最强”选“教程最多、踩坑记录最丰富”的那个才是对新人最友好的。我在实际使用中也遇到过VMware偶尔抽风的情况比如虚拟网络服务起不来、系统镜像安装时无限转圈但这类问题大多能在社区里找到对应解法。相比之下VirtualBox在某些Windows版本上同样存在虚拟化冲突问题。两者半斤八两那就选更容易查资料的那个。1.3 虚拟机参数的“够用就好”原则创建虚拟机之前先说说参数分配。很多新人容易走两个极端要么给虚拟机分配过多资源把自己物理机卡到没法用要么分配太少虚拟机里开个浏览器就动弹不得。我给的建议是“够用就好留有余量”。参数项建议值理由处理器数量1个内核数2~4pwn工具链大部分是单线程的给太多核物理机反而吃力内存8GB同时开虚拟机、GDB调试、pwntools脚本和浏览器8GB比较从容物理机内存小于16GB就降到4GB硬盘60~80GB系统加工具大概占20GB留出空间装题目和快照建议拆分为单个文件性能略好网络模式NATpwn题基本不需要外部网络服务NAT既能上网又天然隔离比桥接更省心3D加速关闭我们不需要虚拟机里渲染图形开着只会增加资源消耗虚拟硬盘选“将虚拟磁盘存储为单个文件”这个设置在VMware创建向导里会问。拆分成多个文件是为了方便迁移但对pwn这种IO密集型调试场景单个文件的读写开销更小。我们后面测试程序时经常要在gdb里跑成千上万次循环磁盘性能细微差距也会影响体验。网络模式选NAT还有一个原因pwn题有时需要我们本地起一个服务端口来模拟远程环境比如用socat监听某个端口。NAT模式下虚拟机和物理机之间通信需要端口转发稍微麻烦一点但这恰恰是安全隔离的体现。真到了要互通的时候再临时改桥接也不迟。2. VMware机器创建与Ubuntu安装参数、固件、分区一次性到位2.1 新建虚拟机向导里的几个关键选项镜像我推荐Ubuntu 22.04.5 LTS不要用最新尝鲜版也不要退回太老的版本。LTS版本生命周期长网上pwn环境教程大多以Ubuntu为示例踩坑时容易找到对应记录。下载ISO时注意去官网或国内开源镜像站文件名里要看清是desktop版不是server版。打开VMware点击“创建新的虚拟机”选择“自定义”而不是“典型”。自定义模式下你能看到硬件兼容性、固件类型、磁盘类型这些关键选项而不是被向导牵着走。硬件兼容性保持默认的最新Workstation版本即可不需要刻意调低。虚拟机向导会问固件类型这里建议选BIOS。现代UEFI也没问题但很多老教程和GDB脚本的默认假设是BIOS启动方式选BIOS能少踩一些出其不意的坑。等你以后对启动机制熟悉了再用UEFI也不迟。操作系统类型选Linux版本选Ubuntu 64位VMware会根据这个选择设置默认磁盘控制器。在I/O控制器类型那里选NVMe还是SATA都行。NVMe在虚拟机里模拟出来的速度感知上更好但对pwn实际影响不大。如果你完全不想纠结默认的NVMe即可。2.2 Ubuntu安装时容易被忽略的细节ISO挂载好之后启动虚拟机进入Ubuntu安装界面。选择语言时我建议选English整个系统界面用英文。这不是装逼而是pwn相关的工具报错、GDB输出、教程里的路径名称大多以英文为主英文系统能减少编码和路径中文字符带来的各种奇怪问题。中文环境虽然用着亲切但在处理CTF工具链时偶尔会遇到某些Python脚本对非ASCII路径处理不友好的情况。安装类型选择“最小安装”然后取消勾选“安装时下载更新”。这样做能让安装过程更快更新放到系统装完之后再统一做。如果你在安装时就选择下载更新往往会卡在网络和镜像源上白白浪费时间。第三方软件和媒体编解码器那些选项全部不勾pwn环境用不到装了反而拖慢安装速度。分区策略这里最容易让人迷惑。新手直接选择“Erase disk and install Ubuntu”这个erase操作只针对虚拟磁盘不影响物理机上的任何数据。虚拟机就是给你随便折腾的不需要搞复杂的双系统分区。安装完成后会有重启步骤重启时如果卡在黑屏或提示移除安装介质直接在VMware里把CD/DVD设备的“启动时连接”取消勾选再重启一次就行。这一步很多教程没提我第一次装的时候就在这卡了十几分钟后来才发现是ISO还挂在光驱位上系统每次尝试从光驱启动就会失败。2.3 装完系统的第一张快照系统装好、用户名密码设好、能正常登录桌面之后先别急着装任何工具做的第一件事是拍摄快照。VMware菜单栏里选“虚拟机”-“快照”-“拍摄快照”名字取一个容易识别的比如ubuntu-22.04-clean。这张快照就是你的后悔药。后面不管apt装坏了、A工具和B工具起冲突、还是某个脚本把系统配置改乱一条命令回到最初干净状态。我在给朋友演示环境搭建时最常看到的问题就是他们装到一半发现某个包依赖错了然后开始手工一顿乱删越删越乱。有了最初的干净快照这些都不是事回滚重来就行。拍快照的时机也很重要。我建议在“系统装好但还没装任何东西”这个节点拍一张之后每完成一轮工具安装再拍一张比如装完基础包拍一张、装完pwntools和pwndbg再拍一张。这样万一后面装坏了你可以精确回退到上一步而不是从头再来。3. 系统落地后的第一波配置换源、基础包与Python环境3.1 先把apt源指到国内镜像虚拟机系统装好第一件事不是急着装pwntools而是把软件源换成国内镜像。Ubuntu默认连的是官方源在国内网络环境下apt update可能要几分钟甚至超时换成清华或阿里镜像后速度立竿见影。Ubuntu 22.04的源配置文件是/etc/apt/sources.list操作前先备份sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i s|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g; s|http://security.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g /etc/apt/sources.list sudo apt update如果你用的是更新版本的Ubuntu比如24.04源文件换到了/etc/apt/sources.list.d/ubuntu.sources格式不一样但同样可以手动把URL替换成镜像站地址。改完之后跑一遍sudo apt update看到一堆下载源不再报错就算成功。换源后顺手做一次系统升级sudo apt upgrade -y这个过程会更新内核和基础库可能要几分钟升级完重启一下虚拟机确保后续安装的工具跑在新内核环境上。3.2 一次性装齐编译、调试和网络工具接下来安装基础工具包。我经常看到教程让你一个一个装太浪费时间这里直接给一份我认为覆盖pwn入门90%场景的清单sudo apt install -y build-essential git vim curl wget net-tools openssh-server \ htop gdb gcc-multilib libc6-dev-i386 python3-dev python3-pip python3-venv \ socat netcat-openbsd file strace ltrace patchelf逐个说下为什么需要这些东西build-essential包含GCC和make编译C程序必备。gcc-multilib和libc6-dev-i386是编译32位程序必需的很多pwn题给的是32位ELF没有这两个包你连编译demo都会报错。gdb是调试程序的根本后面搭配pwndbg插件使用。patchelf用来替换ELF程序的动态链接器和依赖库做libc版本切换时离不开它。socat和netcat-openbsd用来在本地模拟远程服务比如你需要调试一个网上的远程题目可以先起一个本地socat服务来练手。strace和ltrace分别跟踪系统调用和动态库调用遇到看不懂程序行为的题目这两个工具能帮你快速理清执行路径。openssh-server安装在必要时从物理机SSH登录虚拟机不过一般VMware界面操作就够了装上备用。32位题目的运行依赖也需要提前配好否则跑demo时会遇到no such file or directory或cannot execute binary file的错误sudo dpkg --add-architecture i386 sudo apt update sudo apt install -y libc6:i386 libncurses6:i386 libstdc6:i386很多题目的程序是32位动态链接的它们需要32位libc才能运行。物理机上一般不会预装这些虚拟机上不装的话第一个demo就会教你做人。3.3 Python环境给pwntools一条干净的路Ubuntu 22.04自带Python 3.10这个版本满足pwntools的要求。但我不建议直接往系统Python里pip3 install一堆包。Ubuntu对系统Python有严格的包管理策略用pip往系统目录装包时会遇到externally-managed-environment的报错强行加--break-system-packages虽然能装上但后患无穷——哪天Python小版本升级或系统包更新这些被强装进去的包可能就崩了。更干净的做法是给pwn专门建一个虚拟环境python3 -m venv ~/.pwn-venv source ~/.pwn-venv/bin/activate pip install pwntools每次打开终端后只要执行source ~/.pwn-venv/bin/activate就能进入pwn环境。如果嫌麻烦可以把这一行写进~/.bashrc让每次开终端都自动激活。我实际用下来venv隔离的方案最稳系统Python保持原样pwntools随便装随便升级出了任何问题把~/.pwn-venv删掉重建就行。还有一个小坑pwntools安装之后它的命令行工具比如checksec默认落在~/.pwn-venv/bin/下。激活虚拟环境之后才能直接用checksec这个命令。如果你发现终端输入checksec报command not found多半是venv没激活或PATH环境变量没包含虚拟环境的bin目录。3.4 open-vm-tools与共享文件夹为了让虚拟机和物理机之间传文件方便安装open-vm-tools是必须的sudo apt install -y open-vm-tools-desktop装完后虚拟机窗口可以自适应分辨率剪贴板和物理机共享从物理机复制一段payload直接粘贴进虚拟机的终端里。这套工具比VMware菜单里的“安装VMware Tools”更轻量、更稳定我推荐直接用apt包而不是VMware自带的那个。共享文件夹还需要在VMware里配置一步虚拟机设置-选项-共享文件夹-始终启用添加一个物理机上的目录。配置好后在虚拟机里通过/mnt/hgfs/路径访问。我习惯把待分析的题目文件放到共享文件夹里这样物理机下载好题目虚拟机里直接复制到实验目录不需要走U盘或网络上传。open-vm-tools装好后可能需要重启虚拟机才能让共享文件夹和剪贴板完全生效重启一次一劳永逸。4. pwn专用工具链安装pwntools、pwndbg与ROP套件的联动逻辑4.1 pwntools写exp的地基pwntools是CTF的pwn题里最核心的Python库它把连接远程、启动本地进程、构造payload、计算偏移量这些繁琐操作全部封装成了简单函数。安装它之前先激活刚才建好的venvsource ~/.pwn-venv/bin/activate pip install pwntools验证是否装好python3 -c from pwn import *; print(ok)如果输出ok说明pwntools已经正常导入。日常写exp时最常用的几段代码长这样from pwn import * context.log_level debug # 打印调试信息方便看收发内容 context.arch i386 # 告诉pwntools当前是32位程序 p process(./demo) # 启动本地进程 p.recvuntil(binput:) # 接收数据直到出现指定字符串 p.sendline(bA * 64) # 发送payload p.interactive() # 拿到shell后交互如果你要打远程题目把process(./demo)换成p remote(目标域名, 端口)就可以从本地打远程服务。pwntools还提供了ELF类来解析程序结构、cyclic生成pattern、p32/p64/u32/u64做整数与字节序转换。写exp的大部分日常操作基本都绕不开这几个接口。4.2 pwndbg调试器插件首选但不是唯一GDB原生的交互界面在分析pwn题时不够直观所以需要一个给GDB加buff的插件。pwn方向最常见的三个GDB插件是peda、gef、pwndbg。我给新手的建议是直接用pwndbg理由有两点一是pwndbg对堆利用的支持做得最好比如heap、bins、arena这些命令在分析堆题时几乎是刚需二是它的输出信息排版比peda合理栈上数据、寄存器变化、内存布局一眼扫过去就能抓住重点。安装pwndbggit clone https://github.com/pwndbg/pwndbg cd pwndbg ./setup.shsetup.sh会自己处理依赖包括gdb的Python扩展支持。安装完成后重新打开gdb如果看到提示符上方有一行pwndbg的彩色输出就说明生效了。pwndbg最常用的几个命令vmmap查看进程内存映射看栈、堆、libc的加载地址。heap查看堆块布局配合bins查看fastbin、unsorted bin等空闲链表。telescope从某个地址开始连续查看多层指针指向分析栈上指针链好用。cyclic直接集成在pwndbg里配合cyclic -l可以快速定位溢出偏移。我一个人同时装了pwndbg和gef两个插件但新手阶段建议只用pwndbg专注一个插件才能快速形成肌肉记忆。如果以后想换gef试试在~/.gdbinit里改一行source路径就能切换。4.3 ROP与libc套件ROPgadget、ropper、one_gadget、libc-database与patchelf涉足栈溢出之后你会发现很多题不是简单ret2win就能打的而是需要ROP链。系统化安装这套工具可以避免每遇到一种题型就临时装一个新东西。ROPgadget用来搜索二进制文件里的gadgetpip install ROPgadget ROPgadget --binary ./demo --only pop|ret | head -20ropper是另一个gadget搜索工具本质上和ROPgadget重叠。选一个当主力就行我习惯用ROPgadget因为它在脚本化集成上更轻便。one_gadget用来在libc里搜索“一条指令直接getshell”的位置sudo apt install -y ruby gem install one_gadget one_gadget ./libc.so.6它会列出若干个满足约束条件的execve(/bin/sh, ...)地址。这些地址对寄存器、栈布局有特定约束但知道了备选地址再配合调试选择能用的那个比手动拼system和/bin/sh参数快很多。libc-database用来从泄露地址识别远程用的libc版本git clone https://github.com/niklasb/libc-database cd libc-database ./get ubuntu这个仓库下下来之后如果某个题泄露了printf和puts的地址就可以用它的find命令匹配出对应的libc版本。题目目录里会给libc文件但远程环境用了什么libc还是需要这份数据库来辅助判断。patchelf用来替换程序依赖的libc让本地可以复现远程运行环境。典型用法是patchelf --set-interpreter ./ld-2.31.so ./pwn patchelf --replace-needed libc.so.6 ./libc-2.31.so ./pwn有些题给的二进制文件是动态链接直接跑会报version GLIBC_XX not found用patchelf把解释器和libc换成题目给的版本就能在本地把远程环境完整复现出来。这个工具在分析远程服务型pwn题时几乎是必备的。4.4 面向多架构题目的后备工具如果你只打算打x86平台的题目前面那些完全够用了。但CTF比赛偶尔会出现ARM、MIPS这些架构的pwn题正常的x86调试器跑不了。到那时需要两个后备工具sudo apt install -y qemu-user gdb-multiarchqemu-user可以以用户态模拟方式直接运行ARM/MIPS架构的ELF程序比如qemu-aarch64 -L /usr/aarch64-linux-gnu ./chall。gdb-multiarch则是支持多架构的GDB配合qemu做远程调试时可以单步跟踪跨架构程序。这两个工具建议现在先装上不用深入学但别等到比赛前一天才开始装。它们的依赖不多装完不占什么空间属于“放着安心”的工具。5. 零基础验证链路自己编译一个溢出demo并用pwntools打通闭环5.1 一个最小ret2win程序工具全部装完环境到底能不能用靠看教程是没法确认的。我建议你立刻自己写一个最小的漏洞程序把从编译、调试到写exp的完整链路跑一遍。这也是我验证环境是否配好的固定方法。新建一个demo.c#include stdio.h #include string.h void win() { puts(you win!); } void vuln() { char buf[64]; gets(buf); } int main() { vuln(); return 0; }这个程序存在一个典型的栈溢出gets(buf)无条件读取任意长度输入到64字节的缓冲区只要输入长度超过64字节就会覆盖栈上的返回地址。如果我们把返回地址覆盖成win函数的地址程序执行完vuln后就会跳转到win函数打印字符串。5.2 编译选项与checksec验证编译时关掉所有现代保护机制方便观察gcc -m32 -no-pie -fno-stack-protector -z execstack -o demo demo.c-m32生成32位程序-no-pie关闭地址随机化函数地址固定-fno-stack-protector关闭栈保护-z execstack允许栈可执行。这四个编译选项对应的就是pwn题里常见的几种保护机制后续分析题目时要一一对照这些保护项。编译好之后用checksec验证checksec demo输出里会列出Arch: i386-32-little、RELRO: Partial RELRO、Stack canary: No、NX disabled、PIE disabled等字段。看到Stack canary: No和PIE disabled说明这个demo确实关掉了主要防护可以直接打。5.3 三种方式拿win函数地址打ret2win前提是拿到win函数的地址。有三种常用方法nm demo | grep win objdump -d demo | grep winnm给出的是一行符号地址加名字比如080491a2 T win080491a2就是win在内存中的固定地址。objdump -d demo | grep win则能看到win函数的汇编代码和对应的起始地址。如果已经打开了gdb-pwndbg也可以直接在gdb里执行p win三种方法任选其一本质都是一样的。拿到地址后我们要构造的payload结构是64字节缓冲区 4字节被覆盖的旧ebp 4字节返回地址。所以溢出偏移是64 4 68字节最后用4字节的32位地址替换返回地址from pwn import * context.arch i386 p process(./demo) p.sendline(bA * 68 p32(0x080491a2)) print(p.recvall())p32会把整数0x080491a2打包成32位小端字节序因为x86的内存字节序是小端。如果地址不正确或者payload结构算错程序多半会直接段错误连you win!的影都看不到。5.4 用pwntools写exp并运行把上面的脚本保存成exp.py运行前激活venvsource ~/.pwn-venv/bin/activate python3 exp.py如果一切正常输出里会有you win!。看到这个就说明你的环境不仅装好了而且整条“编译、调试、写payload、执行exploit”的链路全部打通了。如果没打通最常见的坑有两个。一个是bash: ./demo: cannot execute binary file这是32位运行库缺失回头检查第3章那个dpkg --add-architecture i386和libc6:i386有没有装对。另一个是跑了但没有you win!可以用gdb ./demo调试在win函数下断点看程序到底跳转到了哪里。把context.log_level debug加进exp里也能看到pwntools收发数据的详细过程定位问题会快很多。6. 实战中绕不开的杂项core dump、32位兼容与快照回滚6.1 让崩溃现场留下core文件分析pwn题时程序段错误是家常便饭。默认情况下Ubuntu不生成core文件程序一崩现场就没了。提前配置好core dump可以让每次崩溃都留下一个可供gdb分析的转储文件。打开core dump需要两步ulimit -c unlimited echo core | sudo tee /proc/sys/kernel/core_patternulimit -c unlimited是当前shell这次会话允许生成core文件关掉终端就失效了所以建议写进~/.bashrc每次开终端自动生效。/proc/sys/kernel/core_pattern设置core文件的生成位置和名字这个设置重启后会重置需要就再执行一遍。配置完成后跑一次崩溃程序目录下会出现一个名字以core开头的文件然后gdb ./demo coreGDB就会自动加载崩溃时的寄存器、栈、内存状态是定位segfault原因和计算溢出偏移的利器。6.2 32位程序跑不起来的GLIBC与multilib问题我见过太多新人在这一步卡死题目文件在物理机上跑不了传到虚拟机也跑不了报错或者直接没反应。原因往往是缺32位运行库或libc版本不匹配。最常见的是运行32位ELF时报错bash: ./pwn: cannot execute binary file: Exec format error或者./pwn: error while loading shared libraries: libc.so.6: cannot open shared object file前者说明系统连可执行文件格式都不认检查file ./pwn如果是32位ELF就回到第3章确认i386架构支持和32位libc装好了没。后者是动态链接器的搜索路径问题用ldd ./pwn看依赖了哪些库缺哪个装哪个。更复杂的情况是libc版本不匹配比如题目给的是glibc 2.23系统自带的是2.35直接跑会报版本符号找不到。这种工作patchelf就要上场了把题目自带的ld-2.23.so和libc-2.23.so链接进去再配合gdb本地调试。这也是为什么第3章建议安装patchelf它平时看似不起眼遇到libc版本不匹配时就是唯一解法。6.3 快照回滚的时机与实验区边界快照虽好用但有一个大前提要理解清楚快照恢复的是拍摄时刻的整个磁盘状态拍摄之后创建、修改的文件都会消失。所以重要资料绝不能只存在虚拟机里我习惯把writeup、题目文件、exp同步到共享文件夹或提交到git仓库。d实验目录的规划也值得一开始就做好。在home下建一个pwn目录每个题目一个子文件夹里面放题目二进制、libc、exp脚本、writeup。这个目录就是你“实验区”的边界所有可疑的操作都限制在这个目录里进行不动系统的其他地方。这样即使题目文件里带了恶意脚本最多霍霍这个目录回滚快照也不心疼。日常使用节奏是每完成一个阶段拍快照比如“基础环境装完”、“工具链全装完”遇到一个难缠的题目先把题目原样保存好再开始打打完后把writeup同步出去。一旦虚拟机系统被搞到不可用的程度直接回滚到上一个可用快照再重新从备份里拉题目十分钟就能恢复到能打题的状态。6.4 VMware本身的一些常见故障最后补充几个VMware本身的常见故障处理思路。虚拟机开机后黑屏或紫屏优先重启VMware或者以管理员身份运行如果电脑物理机的Windows启用了Hyper-V相关功能VMware和Hyper-V会抢占虚拟化权限导致“无法启动虚拟机平台”之类的报错需要在“启用或关闭Windows功能”里关掉Hyper-V再重启。还有人是装了多个虚拟机软件之后VMware的网络服务起不来导致虚拟机完全没网这时去Windows服务管理器里重启VMware相关的几个服务基本都能恢复。这类问题听起来和pwn无关但环境搭不上时最磨人。我的经验是不要试图在报错当下深究具体原理先把网上可搜到的高频解法挨个试一遍记录哪些动作有效问题解决后再回头理解原因。pwner的时间应该花在漏洞分析上而不是和虚拟机软件搏斗。写在最后这套流程我这两年反复用过很多次最长的一次帮朋友远程搭环境从新建虚拟机到跑通demo用了不到半小时但最初我自己第一次搭时折腾了整整一天一夜。现在回头看弯路主要走在对每个步骤背后的原理不了解只知道照着敲命令。所以这篇宝典里我特意把每条命令为什么存在、每个参数为什么这么设都写了出来。环境搭好之后pwn的路才算真正开始。最后分享一个小习惯把现在这整套配置快照和一份干净的模板虚拟机都保留好以后不管是开新机器还是环境彻底崩了都能快速回到“拿到就能打题”的状态。