CTF手册按赛道拆解:从PDF检索到Pwn/Web复现

发布时间:2026/10/30 5:11:08

CTF手册按赛道拆解:从PDF检索到Pwn/Web复现 简介《CTF-All-In-One》是一份面向CTF入门到进阶选手及网络安全学习者的系统化学习文档围绕夺旗赛知识体系梳理逆向、Pwn、Web、密码学、杂项与移动安全等方向帮助读者解决知识点零散、学习路线不清的问题。压缩包内共1个PDF文件大小约6.69MB单文档结构便于离线阅读、目录跳转与全文检索。内容从CTF赛制和学习方法讲起覆盖Linux与Web基础、ELF/PE、静态链接与动态链接、内存管理及glibc malloc并延伸到gdb、IDA Pro、pwntools等常用工具以及栈溢出、ROP、堆利用、内核漏洞、SQL注入、XSS、Fuzz测试、符号执行和CVE实战分析目录分层清楚兼顾基础概念与专题深入。已有599人学习适合希望建立完整知识框架、按模块查漏补缺并积累实战思路的网络安全学习者。1. 从一份六百多页的 PDF 说起先把目录读三遍再动手我第一次拿到这份《CTF-All-In-One》的时候用法是错的——从第一页顺着往下读读到 HTTP 协议基础就断了因为后面全是逆向和 Pwn 的内容前面的 Web 知识还没用上就先饿死了。后来换成另一条路先花半小时把八篇目录结构抄一遍标出Reverse、Pwn、Web、Crypto、Misc、Mobile六条赛道各自落在哪些章节再从自己最想打的那条赛道纵向切进去效率完全不一样。这份手册的价值不在于“全”而在于它把网络安全竞赛需要的知识按“基础 → 工具 → 专题 → 技巧 → 高级 → 题解 → 实战”排成了一条能走通的路径而且每个专题后面都挂着可复现的题解。它适合两类人一类是刚接触 CTF、想知道 PWN 和 WEB 到底要学什么的新手另一类是已经会打几道题、但知识碎片化、想补全二进制和密码学底子的熟手。下面按我实际拆这份 PDF 的顺序讲。2. 拆骨架七篇结构怎么对应六大赛道与一套本地检索库2.1 目录层面先建一张能力地图这份文档的八篇不是并列关系而是递进关系。基础知识篇铺底工具篇给手感分类专题篇按赛道展开技巧篇补零碎手法高级篇上自动化题解篇给可复现案例实战篇用真实漏洞练手附录收工具和系统调用表。真正决定学习顺序的是“赛道”这条纵轴不是“篇”这条横轴。赛道基础章节专题章节配套工具一个可交付成果ReverseC 语言、x86/x86-64 汇编、ELF/PE、静态与动态链接Reverse 专题、反调试、反编译gdb、IDA、radare2手写一份某 crackme 的伪代码还原Pwn内存管理、glibc malloc、调用约定格式化字符串、整数溢出、栈溢出、ROP、堆利用三章pwntools、gdb、one-gadget一条能打通本地演示程序的 expWebHTML、HTTP、JS、常见服务器、OWASP Top Ten、PHP 审计SQL 注入、XSS抓包代理、本地靶场每个漏洞类型一个最小 PoCCrypto初等数论、近世代数、流/分组/公钥密码、哈希、签名古典密码专题Python、Z3一套可复用的解密脚本Misc编码知识、流量分析Misc 专题binwalk、流量分析工具一张隐写/取证类题目的工具清单MobileAndroid 环境、Dalvik 指令集、ARM 汇编Mobile 专题JEB、反编译工具一个 APK 的静态分析笔记建完这张表你会发现一个反直觉的结论基础篇不需要按顺序读完。逆向和 Pwn 共同依赖的是 ELF 格式、调用约定和内存布局那几节Web 依赖的是 HTTP 和 PHP 那几节Crypto 依赖数论那几节。先把“你这周要打的赛道”对应的格子填满剩下的当字典查。我自己的做法是把这张表贴在便签里每读完一节就去填“可交付成果”那一列。填不出来的说明那一节只是读过去了没有真的落地。这个习惯比做笔记有用因为它逼着你产出东西而不是产生“我读过”的错觉。2.2 工具篇的取舍为什么只锁一条调试链工具篇列了虚拟机、gdb/peda、OllyDbg、WinDbg、radare2、IDA、pwntools、zio、JEB、binwalk、抓包代理、LLDB 这一长串。新手最容易在这里翻车全装一遍环境冲突最后连 gdb 都起不来。我的建议是分三档锁第一档必须当天就位gcc、gdb、python3 加 pwntools、readelf/objdump。这四个东西构成 Pwn 的最小闭环缺一个就写不出第一条 exp。第二档按赛道补打 Reverse 装 IDA 或 radare2二选一不要都装打 Mobile 装 JEB打 Misc 装 binwalk。第三档看情况QEMU 只在碰内核题时启用WinDbg 只在碰 Windows 内核时启用。装完之后不要凭感觉判断“装好了”跑一遍验证脚本让环境自己回答。# 只验证核心链路是否就位不追求一次装全 gdb --version | head -1 python3 -c import pwn; print(pwntools, pwn.__version__) readelf --version | head -1 objdump --version | head -1 rabin2 -v 2/dev/null || echo radare2 未安装可后补head -1只取版本行避免刷屏2/dev/null把“命令不存在”的报错吞掉用||后面的 echo 给出可读提示import pwn必须用 python3 解释器执行很多“pwntools 装了但用不了”的情况实际是装进了 python2 或者装进了另一个虚拟环境。这里有个选型理由值得说清楚为什么先锁 gdb 而不是先上 IDA。因为 Pwn 的调试是“带交互的”你要在进程跑到断点的时候往 stdin 灌数据、看栈上的字节、算偏移这套动作 gdb 加 pwntools 的gdb.attach()最顺。IDA 强在静态反编译和交叉引用适合 Reverse 阶段看逻辑不适合盯着栈帧一字节一字节对。两者不是替代关系是阶段关系。2.3 把 PDF 拆成可 grep 的文本库六百多页的 PDF 用阅读器翻最痛苦的是“我记得讲过 unsorted bin但忘了在第几页”。解决办法是先把它拆成纯文本用命令行检索。mkdir -p ctfbook/pages ctfbook/text # 按页拆 PDF得到 page-0001.pdf 这种可预测命名的文件 pdfseparate -f 1 -l 700 ctf-all-in-one.pdf ctfbook/pages/page-%04d.pdf # 逐页转文本-layout 保留原始缩进汇编清单和代码块靠它才不乱 for f in ctfbook/pages/*.pdf; do base$(basename $f .pdf) pdftotext -layout -enc UTF-8 $f ctfbook/text/${base}.txt done # 合并成一个大文件方便跨页检索 cat ctfbook/text/page-*.txt ctfbook/all.txt wc -l ctfbook/all.txt-f 1 -l 700是页范围实际页数按你的文件调整写大了pdfseparate会自己停在最后一页%04d保证按数字而不是字典序排序否则page-10会排在page-2前面-layout是关键参数关掉之后代码块会被压成一整行后面检索到的内容没法读-enc UTF-8避免中文标题变成乱码。拆完之后检索就自由了# 带上下文检索-C 3 表示前后各三行 rg -n --no-heading -C 3 unsorted bin|fastbin ctfbook/all.txt | head -60 # 只看文件名和命中次数快速定位集中在哪几页 rg -c one-gadget ctfbook/text/*.txt | sort -t: -k2 -nr | head -10-n带行号--no-heading不打印文件名分组头-C 3给上下文head -60防止一次刷出几百行。第二条命令用-c统计每页命中次数再按次数倒序能一眼看出“one-gadget 这个概念在哪几页被反复讲”比从头翻快得多。更进一步可以把章节标题抽出来做成跳转表检索到内容之后能顺着页码回到原 PDF 对照排版# 抽出形如 “1.5.3 栈溢出” 的标题行生成 行号 → 标题 的对照 rg -n --no-heading ^\s*[0-9](\.[0-9]){1,2}\s\S ctfbook/all.txt \ | awk -F: {printf %s\t%s\n, $1, $2} \ | head -80awk -F:以冒号切分rg的输出$1是行号$2是标题内容注意标题里本身可能带冒号所以只取前两段就够了。生成的表存成toc.tsv以后检索到正文用行号反查最近的标题就知道自己在哪一章。这一步做完这份 PDF 就从“一份要读完的资料”变成了“一个可以随时查的知识库”。后面所有章节的复现我都是先在这个文本库里搜关键词再回原文对照。3. 二进制线闭环从 ELF 节头到 pwntools exp 的五个台阶3.1 ELF/PE 与调用约定阅读顺序不能反手册在逆向工程基础里排的顺序是 C 语言 → 汇编 → ELF → PE → 静态链接 → 动态链接 → 内存管理 → glibc malloc。这个顺序是对的原因是 Pwn 的每一步都在跟“链接结果”和“内存布局”打交道栈溢出算偏移要知道栈帧怎么分配ROP 要找 gadget 要知道代码段怎么映射堆利用要知道 malloc 从哪拿内存。跳过链接直接看堆等于背结论。我的读法是每一节都配一条命令边看边验证。先编一个本地演示程序故意关掉所有现代防护让教科书里的栈溢出能复现# 仅用于本地学习的演示程序关闭 canary、关闭 PIE、开启可执行栈 gcc -fno-stack-protector -no-pie -z execstack -m64 demo.c -o demo # 看 ELF 头类型、入口、节头表偏移 readelf -h demo # 看段表代码段、数据段、栈的对齐与权限 readelf -l demo | head -30 # 看重定位表哪些符号走 GOT/PLT readelf -r demo # 反汇编指定函数-M intel 用 Intel 语法更好读 objdump -d -M intel demo | sed -n /vuln:/,20p四个 gcc 参数分别是-fno-stack-protector关掉栈保护 cookie否则溢出会被__stack_chk_fail拦下-no-pie关掉地址随机化让函数地址在每次运行中固定方便先理解原理-z execstack把栈标记为可执行让 shellcode 类打法成立-m64生成 64 位程序。这四个参数是教学配置真实程序里全部相反这一点必须记牢否则后面拿到真实题目会误以为“怎么打不进去”。sed -n /vuln:/,20p的意思是找到函数标签行从那里开始打印 20 行比objdump | grep -A 20更稳因为它锚定的是函数边界而不是字符串匹配。看到sub rsp, 0x40这类指令就要能在纸上画出栈帧返回地址在哪、局部缓冲区多大、偏移是多少。这一步画不出来后面的 exp 就是抄的。3.2 用 pwntools 写一个可复现的栈溢出 exppwntools 的核心价值是把“连进程、收发数据、打包地址、解析 ELF”这四件事压成几行。先看一个最小骨架目标是自己编的本地demo不指向任何真实服务from pwn import * # 调试期开 debug上线前改成 info context(log_leveldebug, archamd64, oslinux) elf ELF(./demo) # 解析符号表拿 backdoor 的真实地址 io process(./demo) # 起本地进程换成 remote 就是打远程 offset 72 # 缓冲区 64 字节 保存的 rbp 8 字节 payload bA * offset p64(elf.symbols[backdoor]) io.sendlineafter(bname:, payload) # 等到提示符再发避免时序问题 io.interactive() # 交还控制权方便手工继续操作context里的arch和os决定p64的字节序和 shellcraft 生成的代码ELF(./demo)会解析符号表elf.symbols[backdoor]拿到的就是函数虚拟地址在-no-pie下等于运行地址process起子进程标准输入输出接到管道sendlineafter比sendline稳因为它会等到指定字符串出现再发避免程序还没打印提示符你就把数据塞进去导致错位interactive()把终端交还给进程适合打完拿 shell 之后手工敲命令。偏移 72 这个数字不要靠猜。用 cyclic 模式让程序自己告诉你from pwn import * context(log_levelerror, archamd64) io process(./demo) io.sendline(cyclic(200, n8)) # n8 生成 8 字节一组的循环串 io.wait() # 等进程崩溃确保 core 落盘 core io.corefile # 读取 core 文件 rsp_value core.read(core.rsp, 8) offset cyclic_find(rsp_value, n8) print(offset , offset)cyclic(200, n8)生成 200 字节、每 8 字节一个唯一模式的字符串n8对应 64 位程序32 位程序要用n4io.wait()是必须的进程没死之前 core 不会生成core.read(core.rsp, 8)从崩溃时的栈指针读 8 个字节那正好是被覆盖的返回地址cyclic_find反查这个模式在原始串里的位置得到的就是偏移。这段代码跑不通九成是 core 没落盘。检查两件事ulimit -c unlimited有没有设/proc/sys/kernel/core_pattern是不是被设成了管道以|开头管道模式下 core 会交给系统服务处理不会在当前目录生成文件。改成本地路径比如core.%p再跑一次。3.3 glibc malloc 三章的四个观察点堆利用是这份手册里最厚的部分分了三节上、中、下后面还跟了内核 ROP 和内核漏洞利用。堆难的地方不是概念多而是“看不见”——你以为写进去的字节实际被 chunk 头吃掉了你以为释放了内存实际进了 tcache 还在原地留着指针。我的做法是给每一节设一个可观察的验证点看完就去 gdb 里确认一次观察点要确认的事实验证方式chunk 头prev_size 与 size 的低三位含义PREV_INUSE、IS_MMAPPED、NON_MAIN_ARENA分配两个相邻 chunkx/8gx看头部字节bin 分类fastbin、smallbin、unsorted bin、largebin 的进出规则free 之后看bins命令输出落在哪个链表tcache2.26 之后每线程 64 个 bin、每个 bin 最多 7 个 chunk连续 free 8 个同尺寸 chunk看第 8 个进了哪里利用原语UAF、double free、off-by-one 各自能改到什么构造最小 PoC观察被改写的目标字段这四个点对应了绝大多数堆题的地基。观察点一最容易忽略size字段的低三位不是大小是标志位很多 off-by-one 打的就是最低位的PREV_INUSE。观察点三要特别注意 glibc 版本差异同一段代码在 2.27 和 2.31 上行为可能完全不同做题前先ldd --version确认环境版本或者直接看题目给的 libc 文件。3.4 高级篇的入口AFL、angr、Z3 什么时候值得上高级篇列了 Fuzz、动态二进制插桩、符号执行angr、Triton、KLEE、S²E、Clang/LLVM、Capstone/Keystone、SAT/SMTZ3、反调试、反编译、Unicorn。这一堆东西的共同点是“听起来很厉害用起来很挑场景”。先说结论自动化工具解决的是“手工太慢”的问题不是“手工不会”的问题。你连手工偏移都算不明白上 angr 只会得到一堆看不懂的状态树。符号执行的适用场景很窄但很准程序分支多、输入是短字节序列、没有复杂系统调用。angr 的最小用法长这样import angr # auto_load_libsFalse 很关键默认加载 libc 会让状态数暴涨 proj angr.Project(./demo, auto_load_libsFalse) state proj.factory.entry_state() simgr proj.factory.simulation_manager(state) # find 是想要到达的地址avoid 是要避开的地址 simgr.explore(find0x4011a2, avoid0x4011c0) if simgr.found: print(simgr.found[0].posix.dumps(0)) # 打印能到达 find 的 stdin 内容 else: print(未找到路径检查地址或加 hook)auto_load_libsFalse是新手最常漏的参数默认值为 True 时 angr 会把 libc 一起符号化状态数爆炸到跑不动。find和avoid传的是虚拟地址用objdump或 IDA 查函数入口posix.dumps(0)把文件描述符 0标准输入的内容 dump 出来就是要求的输入。程序里有scanf、strlen这类 libc 调用时angr 自带的 SimProcedure 通常能处理但遇到自定义加密函数就得自己写 hook。Z3 的定位更基础它是解约束的工具不是逆向工具。拿到一段形如“输入经过若干加减异或后等于某常量”的校验逻辑把每个字节建成BitVec把校验式翻译成约束交给 solver 就行。这类题目手工算也能算但 32 个字节的手工算必然出错Z3 的价值是“不出错”而不是“算得快”。3.5 内核 ROP 与内核漏洞利用的门槛判断手册把内核 ROP 和 Linux/Windows 内核漏洞利用放在专题篇末尾这个位置是有意的它是二进制线的天花板前置知识包括用户态 ROP、堆、内存管理、保护机制绕过。判断自己该不该现在上的标准很简单——用户态的 ret2text、ret2libc、栈迁移能不能不查资料写出来。不能就先回去。真要上手第一步是搭一个能调试的环境QEMU 是最常见的做法qemu-system-x86_64 \ -m 256M \ -kernel ./bzImage \ -initrd ./rootfs.cpio.gz \ -append consolettyS0 nokaslr \ -nographic \ -s-m 256M给虚拟机内存内核题一般给 128M 到 512M-kernel指定内核镜像-initrd指定打包好的根文件系统-append里consolettyS0必须和-nographic配合否则你看不到任何输出nokaslr关掉内核地址随机化方便第一次调通真实题目里通常开着-s在 1234 端口开 gdb stub宿主机上用gdb vmlinux再target remote :1234就能下断点。这套环境搭起来之后真正的难点才刚开始内核态的 ROP 要考虑swapgs、iretq恢复上下文要考虑 SMEP/SMAP 阻止你跳到用户态代码要考虑 KASLR 绕过的信息泄露点在哪。这些内容手册里都有但每一节都需要你在 QEMU 里真跑一遍才有体感。我的建议是把它当长期目标不要在打第一场线上赛之前硬啃。4. Web 与 Crypto 的脚本化复现靶场、审计与古典密码验证4.1 Web 基础六节的最小可练集Web 基础那六节HTML、HTTP、JS、常见 Web 服务器、OWASP Top Ten、PHP 源码审计看起来是科普实际每一节都对应一种题型。问题是新手容易“读完就过”所以要给每节定一个最小产出。手册小节要抓住的点最小可练产出HTML 基础表单 method、input name、隐藏字段手写一个带 GET 和 POST 表单的页面HTTP 协议基础请求行、首部字段、状态码、Cookie、分块传输用 nc 手工发一个请求看懂每一行JavaScript 基础同源策略、DOM 操作、前端校验写一个前端校验然后绕过它常见 Web 服务器基础路由规则、静态资源、默认页面、解析差异本地起一个服务观察访问日志OWASP Top Ten注入、XSS、文件包含、越权每类跑通一个最小 PoCPHP 源码审计危险函数、变量覆盖、过滤绕过用脚本定位 sink 并回溯入口第三行“用 nc 手工发请求”是最容易被跳过、但收益最高的一节。浏览器把太多细节藏起来了你只有手工发一次GET / HTTP/1.1加Host:首部才能理解为什么有的题目要改Content-Type、为什么要伪造X-Forwarded-For、为什么响应头里的Set-Cookie属性会影响利用。本地起靶场是最省事的做法PHP 自带的内置服务器就够用注意只绑回环地址# 只监听本机回环避免练习环境暴露到局域网 cd ./vuln-demo php -S 127.0.0.1:8080 -t ./ # 另开一个终端手工发一个请求看响应头 printf GET /index.php HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n | nc 127.0.0.1 8080php -S起的是单进程开发服务器够用来验证路由和参数解析不要拿它做压测-t ./指定文档根目录绑127.0.0.1而不是0.0.0.0是有意的练习环境不该被同网段的其他机器访问到。第二条命令用printf而不是echo因为echo在不同 shell 里对\r\n的处理不一致printf更可控Connection: close让服务端在响应后关闭连接nc才能正常退出。4.2 PHP 源码审计从危险函数回溯可控入参审计这一节的核心不是背函数名而是建立“sink → 数据流 → source”的回溯习惯。sink 是能执行代码或读写文件的地方source 是用户能控制的输入。手工看几百个文件不现实先写一个粗筛脚本把可疑行捞出来import re import pathlib # 能直接造成代码执行或文件读写的函数按危险程度排序 SINKS [ eval, assert, system, exec, shell_exec, passthru, popen, proc_open, preg_replace, unserialize, include, include_once, require, require_once, file_get_contents, file_put_contents, unlink, ] pattern re.compile(r\b( |.join(SINKS) r)\s*\(, re.I) for path in pathlib.Path(src).rglob(*.php): text path.read_text(errorsignore) for lineno, line in enumerate(text.splitlines(), 1): # 先排掉整行注释减少噪音 if line.strip().startswith((//, #, *)): continue if pattern.search(line): print(f{path}:{lineno}: {line.strip()[:120]})SINKS列表按危险程度排越靠前越值得优先看re.I让匹配不区分大小写因为 PHP 函数名大小写不敏感pathlib.rglob(*.php)递归遍历子目录errorsignore防止某个文件编码异常导致整个脚本中断行号从 1 开始和编辑器对齐[:120]截断超长行避免一行几百字符刷屏。这个脚本只解决“在哪”不解决“能不能打”。真正的判断要往上追这个 sink 的参数是不是来自$_GET、$_POST、$_REQUEST、$_COOKIE中间有没有经过intval、addslashes、白名单比较。常见做法是先从 sink 所在函数往上找变量赋值再看这个变量有没有跨函数传递跨了就跟进被调函数。这一步目前还得手工正则做不到数据流分析但脚本能把候选集从几千行压到几十行剩下的手工看是值得的。注意这个脚本的误报率不低注释、字符串字面量、文档里的示例代码都会命中。所以第一步先排注释第二步对命中行人工过一遍别直接把结果当漏洞列表。4.3 Crypto 前置数论怎么补一道古典密码的脚本验证Crypto 这条线的门槛不在工具在数学。手册把初等数论和近世代数放在最前面是有道理的模运算、逆元、欧拉函数、群环域这些概念不理解看 RSA 的推导就是看天书。但补数学不能只补数学要配着题走。古典密码是最适合入门的验证场因为它的逻辑足够简单可以完整走一遍“看题 → 建模 → 写脚本 → 验证”的流程。以维吉尼亚密码为例def vigenere_decrypt(cipher: str, key: str) - str: 维吉尼亚解密只对字母位移非字母原样保留且不消耗密钥位 out [] k key.lower() ki 0 # 密钥下标只在实际用到密钥时递增 for ch in cipher: if ch.isalpha(): shift ord(k[ki % len(k)]) - ord(a) base ord(A) if ch.isupper() else ord(a) out.append(chr((ord(ch) - base - shift) % 26 base)) ki 1 else: out.append(ch) # 标点、空格不参与位移 return .join(out) # 用经典的 lemon 密钥验证明文应为 ATTACKATDAWN print(vigenere_decrypt(LXFOPVEFRNHR, lemon))ki % len(k)保证密钥循环使用base区分大小写让大写字母解密后还是大写% 26处理负数取模Python 的%对负数返回正数这一点比 C 语言省事非字母字符走else分支原样拼接且不递增ki这是很多人写错的地方——如果标点也消耗密钥位后面全部错位。这段代码跑通之后再往上走到分组密码和公钥密码思路是一样的先把数学关系写成方程再把方程翻译成代码最后用已知答案验证。RSA 的小指数场景可以这样验证import gmpy2 from Crypto.Util.number import long_to_bytes c 0x1f8b0c1d # 密文题目给定 e 3 # 指数很小且明文未填充时可直接开方 root, exact gmpy2.iroot(c, e) print(是否精确开方:, exact) if exact: print(long_to_bytes(int(root)))gmpy2.iroot(c, e)返回二元组第一个是整数 e 次方根第二个是布尔值表示是否精确只有exact为真时开方结果才是明文否则说明密文是经过填充或多次加密的得换思路。long_to_bytes把大整数还原成字节串注意返回值是 bytes打印时要解码或者直接看 repr。依赖这两个库的话装gmpy2和pycryptodome就行。真正卡人的往往不是代码是“什么时候该用哪种攻击”小指数直接开方、共模攻击、低加密指数广播、维纳攻击每种都对应密文和参数的不同特征。手册里这些都有推导我建议每个攻击手写一遍再对着题验证别只跑现成脚本。5. 避坑排查五个卡点从环境到复现逐条对账5.1 环境类三个最容易翻车的地方卡点一拆出来的文本库检索全是重复内容。现象rg搜一个关键词命中几百条翻开一看全是目录页或者页眉页脚。原因PDF 每一页都带页眉目录页又把所有标题列了一遍拆页之后这些内容被原样保留检索时自然重复。解决先定位目录页的范围通常是前 10 到 20 页拆页时用-f 21跳过页眉用sed按行剔除比如sed -i /^CTF-All-In-One$/d ctfbook/text/*.txt。剔之前先head -20看一眼实际页眉长什么样别照抄别人的正则。另外rg -m 5可以限制每个文件最多命中几条用来快速判断“是不是只有目录在重复”。卡点二本地编的 demo 换台机器偏移就对不上。现象同一份 exp在自己机器上打通拷给同学就跑飞报错指向的地址完全不一样。原因偏移依赖三个东西——编译选项、glibc 版本、栈对齐。-fno-stack-protector换成默认值栈帧布局就变了glibc 从 2.27 换到 2.31某些函数的内部实现变化会影响栈上残留64 位下call指令要求 16 字节对齐进函数时rsp % 16 8多一个或少一个retgadget 都会崩。解决把编译命令写进Makefile或者一个build.sh谁跑都用同一条命令在 exp 开头打印elf.libc的路径和版本确认两边一致栈对齐问题用多插一个ret解决这是最常见的“地址全对但就是不通”的原因。我现在的习惯是每个题目目录下放一个env.txt记录 gcc 版本、libc 版本、编译参数出问题先对这三个。卡点三QEMU 起内核之后屏幕一片空白。现象命令敲下去没有任何输出进程也不退出只能 CtrlC。原因-append里的console参数和-nographic不匹配内核把输出送到了别的设备或者-initrd指定的 rootfs 里没有/init内核启动到一半挂住。解决先确认consolettyS0写对了不是tty0不是ttyS1再解包 rootfs 看一眼根目录有没有init或者linuxrccpio格式用cpio -idmv rootfs.cpio解gzip压缩的先gunzip实在没输出就加earlyprintkserial,ttyS0,115200让内核尽早往串口打日志。这一步急不得内核启动失败的原因往往在最后一行日志里看不到日志就什么都判断不了。5.2 复现类两个看起来成功其实是假的卡点四angr 跑了半小时没结果也没有报错。现象脚本挂在那里CPU 占满内存缓慢上涨就是不打印结果。原因状态爆炸。默认auto_load_libsTrue会把 libc 一起符号化一个strlen就能分裂出成千上万个状态程序里有循环时符号执行会沿着循环展开深度不受控。解决先加auto_load_libsFalse再给explore加num_find1找到一条就停循环多的话开veritestingsimgr proj.factory.simulation_manager(state, veritestingTrue)还不行就用 hook 把不关心的函数替换成 SimProcedure直接返回固定值。判断“是不是状态爆炸”的方法很简单看内存占用曲线线性上涨基本就是。卡点五PHP 审计脚本扫出一堆“漏洞”实际一个都打不了。现象脚本输出几十条system(、eval(逐条看过去要么在注释里要么参数是硬编码常量要么前面有intval卡死。原因正则只做字面匹配不理解作用域、不理解数据流、不理解过滤函数。注释和字符串字面量会被命中这是最基础的误报参数是常量时根本没有外部输入这是语义层面的误报。解决第一步排注释和字符串PHP 可以用token_get_all拿到 token 流只保留T_STRING类型且后面跟(的 token比正则准得多第二步人工回溯每个命中点的参数来源重点看有没有$_GET/$_POST第三步把“有过滤”的标记出来单独看因为过滤函数本身可能被绕过比如str_replace只替换一次、addslashes挡不住宽字节。这套流程走下来几十条能剩三两条真的效率反而比一条条试高。6. 把题解篇做成索引卡复盘一次比刷十题管用题解篇是我认为这份手册里最容易被浪费的部分。大多数人看完题解的反应是“哦原来是这样”然后关掉下次遇到同类题还是不会。原因很简单题解是别人的思路你没把它拆成自己的检索项。我的做法是给每道题建一张索引卡字段固定为六个题目代号用自己编的编号不用原始赛事名、赛道、考点关键词、关键偏移或关键参数、卡住我的那一步、一句话解法。存成一个 TSV 文件用rg检索比翻 PDF 快得多。# 新增一张卡字段用 tab 分隔方便后续按列过滤 printf %s\t%s\t%s\t%s\t%s\t%s\n \ P-007 pwn stack overflow;ret2text;no-pie \ offset72;backdoor0x4011a2 \ sendlineafter 的时机不对导致数据被当成菜单选择 \ 先等提示符再发 payload cards.tsv # 按考点检索只看 pwn 赛道里跟堆相关的卡 awk -F\t $2pwn $3 ~ /heap/ {print $1\t$5} cards.tsv # 统计各赛道的卡片数量 p a hrefhttps://download.csdn.net/download/weixin_51954811/90607366 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
延伸阅读

更多相关文章

2026/10/30 5:11:08

NeRF-SLAM复现:单目RGB稠密深度与辐射场工程链路

简介:围绕NeRF-SLAM复现过程整理的docx文档,面向已具备视觉SLAM基础、希望将神经辐射场用于稠密建图的研究生与算法开发者,着力解决复现链路理解、模块衔接与常见报错排查问题。压缩包内仅1个docx文件,体积约11.01MB,以…

2026/10/30 5:06:08

Tailor:语义感知视频智能裁剪工作流

简介:Tailor是一款面向视频创作者与AI初学者的开源视频智能处理工具,聚焦于降低视频剪辑技术门槛,解决手动裁剪低效、生成模板缺失、画质优化依赖专业软件等痛点。资源包共400个文件,以272个Python脚本(实现AI裁剪逻辑…

2026/10/30 5:06:08

XP系统i386完整包:目录结构、驱动注入与无人值守部署

简介:Windows XP i386 完整安装包面向需要在老旧硬件、虚拟机或模拟环境中复刻经典系统的用户,适合复古游戏玩家、旧版软件兼容性测试人员与系统维护学习者使用。压缩包共 291 个文件、约 12.95MB,以 116 个 dl_ 组件、40 个 htm 说明页、19 …

2026/10/30 6:21:13

Xpert注册、使用教程及问题解答——专家社区平台

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 6:21:13

阿里巴巴Qwen3-Coder-30B重磅发布:FP8量化技术引领AI编码效率革命

阿里巴巴Qwen3-Coder-30B重磅发布:FP8量化技术引领AI编码效率革命 在人工智能编码辅助领域,阿里巴巴最新推出的Qwen3-Coder-30B-A3B-Instruct-FP8模型正引发行业变革。作为Qwen系列大型因果语言模型的旗舰产品,该模型不仅集成了顶尖的代码生…

2026/10/30 6:21:13

支付系统数据一致性解决方案与分布式事务实践

1. 支付系统数据一致性挑战与核心诉求在电商、金融等涉及资金流转的场景中,支付系统作为核心基础设施,其数据一致性直接关系到资金安全与用户体验。典型场景如用户支付订单时,系统需要同时完成账户扣款、订单状态更新、积分发放等多个操作&am…

2026/10/30 6:21:13

Java开发同城KTV预约系统:Spring Boot与Redis实战

1. 项目概述"Java打造同城:自助KTV线上预约新体验源码"是一个基于Java技术栈开发的线上KTV预约系统。这个项目主要解决传统KTV行业面临的预约效率低、资源分配不均等问题,通过互联网技术实现同城KTV资源的线上化管理和预约。作为一个全栈Java项…

2026/10/30 6:21:13

小爱音箱DIY改造终极指南:从入门到精通的完整方案

小爱音箱DIY改造终极指南:从入门到精通的完整方案 【免费下载链接】xiaoai-patch Patching for XiaoAi Speakers (小爱音箱), add custom binaries and open source software. Tested on LX06, LX01, LX05, L09A 项目地址: https://gitcode.com/GitHub_Trending/x…

2026/10/30 6:16:13

LM Studio中使用Qwythos-9B:图文混合输入的最佳实践指南

LM Studio中使用Qwythos-9B:图文混合输入的最佳实践指南 Qwythos-9B是一个功能强大的多模态AI模型,专为图文混合输入而设计。这款基于Qwen3.5-9B优化的推理模型,在LM Studio中提供了卓越的视觉理解和文本生成能力。本文将详细介绍如何在LM St…

2026/10/29 17:05:52

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/29 17:06:02

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/29 17:06:13

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/30 0:00:46

NCP1342高频准谐振反激控制器:从设计约束到验收的完整方案

简介:NCP1342 高频准谐振反激控制器应用介绍译文文档,面向电源设计工程师、硬件研发人员及开关电源学习者,帮助读者跨越英文原版资料的语言门槛,系统理解这款高集成度 QR Flyback 控制器的设计要点。文档围绕芯片核心特性展开&…

2026/10/30 0:00:46

NCP1342准谐振反激电源设计:从选型到验收的全流程解析

简介:这份文档面向电源设计工程师与开关电源学习者,系统梳理NCP1342高频准谐振反激控制器的应用要点,帮助读者快速理解这款高集成度离线电源变换器控制芯片的工作机制与设计方法。内容涵盖芯片核心特性、引脚功能定义、电气特性参数表、最大额…

2026/10/30 0:00:46

Web系统自动登出机制设计与实现全解析

1. 系统自动登出机制的设计初衷在各类Web应用和后台管理系统中,自动登出功能早已成为标配。这个看似简单的功能背后,实际上涉及用户安全、资源管理和体验优化的多重考量。作为从业十多年的老开发,我见过太多因为登出逻辑设计不当导致的安全事…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑