SSRF原理及绕过

520 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第四天,点击查看活动详情

简介

SSRF(Server-Side Request Forgery),即服务器端请求伪造,利用漏洞伪造服务器端发起请求,从而突破客户端获取不到数据限制,本质上是属于信息泄露漏洞

漏洞原理

一般浏览流程:用户在地址栏输入网址 --> 向目标网站发送请求 --> 目标网站接受请求并在服务器端验证请求是否合法,然后返回用户所需要的页面 -->用户接收页面并在浏览器中显示 SSRF漏洞出现在目标网站接受请求后在服务器端验证请求是否合法这一步中,是由于服务器端没有对用户请求做出严格的过滤以及限制,导致其可以从其他服务器获取一定量的数据。SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有发现在这个请求是合法的,然后服务器以他的身份来访问其他服务器的资源。 总的来说就是:利用一个可以发起网络请求的服务当作跳板来攻击内部其他服务

CSRF是跨站请求伪造,主要是基于前端进行的攻击,html代码 -->修改用户功能 csrf添加用户管理员。 SSRF是服务器端请求伪造,主要是基于服务器进行的工具, url链接 -->内网漫游/内网服务探测/内网开放端口探测/getshell/xss

SSRF测试协议利用

file:// 获取文件、 dict: url方案用于表示使用DICT协议可用的定义或单词列表。 sftp:// sftp代表ssh文件传输协议,也就是用来传输ssh文件 ladp:// 轻量级目录访问协议 ftp://简单文件传输协议是一种简单的锁步文件传输协议 gopher://是一种分布式的文档传递服务,它允许用户以无缝的方式探索、搜索和检索驻留在不同位置的信息。 比较常用是file、dict、ftp和gopher协议

dict协议

定义

词典网络协议,在RFC 2009中进行描述。它的目标是超越Webster protocol,并允许客户端在使用过程中访问更多字典。Dict服务器和客户机使用TCP端口2628。

使用

  1. dict://serverip:port/命令:参数
  2. 向服务器的端口请求为【命令:参数】,并在末尾自动补上\r\n(CRLF),为漏洞利用增添了便利
  3. 通过dict协议的话要一条一条的执行,而gopher协议执行一条命令就行了。

使用dict协议可以看出目标端口的指纹信息,探测端口的开放情况和指纹信息。 图片: https://uploader.shimo.im/f/L0zV9t2vbnHWaeiU.png

通过探测,可以发现是6379的redis数据库 可以使用dict协议利用redis的未授权访问反弹shell

file

file协议主要用于访问本地文件

使用

file://文件路径

图片: https://uploader.shimo.im/f/nsC54UFNqquDoxz3.png

什么是gopher协议

定义:

Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它。

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议 限制:gopher协议在各个编程语言中的使用限制 注意:gopher协议中的curl低版本不支持 curl --version可以查看版本以及支持的协议

gopher协议格式

URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流

如果发起post请求,回车换行需要使用**%0d%0a**,如果多个参数,参数之间的&也需要进行URL编码

gopher发送http get请求

前提:本地监听,Ubuntu发送请求 图片: https://uploader.shimo.im/f/2pAIiFXJCJ6DWFmq.png

图片: https://uploader.shimo.im/f/gahuSkT28lWzVV3i.png

如果要在gopher中发送http的数据需要三步:

  1. 构造HTTP数据包
  2. URL编码、替换回车换行为%0d%0a
  3. 发送gopher协议

构造HTTP包

首先打开我们写的一个PHP代码

 <?php
    echo "Hello ".$_GET["name"]."\n"
?>

request包的前两行为传参内容和Host

GET /php/ssrf/test.php HTTP/1.1 Host: 192.168.43.225

gopher编码后

curl gopher://192.168.43.225:80/_GET%20/php/ssrf/test.php%3fname=QLNU%20HTTP/1.1%0d%0AHost:%20192.168.43.225%0d%0A

注意点: 1、问号(?)需要转码为URL编码,也就是%3f 2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a 3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束) 图片: https://uploader.shimo.im/f/5YPLwWTIB5sVNaeZ.png

POST包也和GET类似,主要就是编码问题

一般使用gopher协议来打redis,比如有一个redis未授权漏洞的话,dict协议就是一条一条的执行命令,而gopher协议则是一条命令就可以执行成功,不过gopher协议有很多的限制,在不支持gopher的情况下可以使用dict。

接下来就是最重要的就是绕过啦

本地地址绕过

使用localhost或者[::]替换127.0.0.1

@

www.baidu.com@127.0.0.1/index.html = http://127.0.0.1/index.html

短网址绕过

使用网址生成一个短网址 suo.im/6b4B5R = http://127.0.0.1/index.html

指向任意IP的域名xip.io

127.0.0.1.xip.io/index.html = http://127.0.0.1/index.html

DNS解析绕过

将一个域名的记录设置为另一个网站

特殊编码

127.0.0.1 = ①2⑦.0.0.1 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

进制绕过

如果服务端过滤方式使用正则表达式过滤属于内网的ip地址时,就可以将ip地址转换为八进制、十进制、十六进制进行绕过,记得八进制前加0,十六进制前加0x SSRF绕过肯定要使用各种协议 今天主要学习的是gopher协议

参考链接:zhuanlan.zhihu.com/p/112055947 参考链接:zhuanlan.zhihu.com/p/112055947