服务端请求伪造
What is SSRF?
SSRF ” allows an attacker to cause the server-side application to make requests to an unintended location.“
通常情况下,是向内部的服务。严重的情况下,可能说是请求外部的任意系统,这就会泄露敏感信息。
What is the impact of SSRF attacks?
通常会导致”unauthorized actions or access to data within the organization“ , 有些情况下,可能会使攻击者能够执行任意代码。
“An SSRF exploit that causes connections to external third-party systems might result in malicious onward attacks.”
An SSRF exploit that causes connections to external third-party systems might result in malicious onward attacks. these can appear to originate from the organization hosting the vulnerable application.
我的理解是,存在SSRF漏洞的服务器会被利用,用于进一步的攻击,像DDoS等等。会被当成肉鸡(?
Common SSRF attacks
SSRF通常是利用“可信关系”来发起攻击的。
SSRF attacks against the server
这里举出SSRF的一种攻击类型是通过,使应用自己给自己发请求,来实现的。“via its loopback network interface” , 比方说提交的URL改成127.0.0.1
或者localhost
。
这里它举了个例子,说会查询库存数量。
1 | POST /product/stock |
这种时候,就可以指定个URL来实现SSRF攻击。
1 | POST /product/stock |
此时,就泄露敏感数据了。因为攻击者正常情况下,是没办法访问/admin
的,而此时是server本身发的请求,因此是可信的,所以会被接受。“the request appears to originate from a trusted location.”
为什么会信任来自本地的请求,可能有以下几种原因:
access control check
可能跟server分开的,是server前边的另一个构件。所以自己给自己发送请求,这个check就被绕过了。- “For disaster recovery purposes”,可能说管理员密码忘了,登陆凭证丢了,就可以通过这种方式恢复系统。
- 管理界面跟main application不在一个端口,用户接触不到。(所以就放松警惕了?)
这种情况的漏洞,往往比较严重。
Lab: Basic SSRF against the local server
这里随便点进去一个商品页面可以看到有Check stock
的交互。request 如下:
1 | POST /product/stock |
这里修改stockApi
为
1 | stockApi=http%3a%2f%2flocalhost%2fadmin |
然后发现页面出现管理后台删除,注意还是要利用carlos
即可loopback
实现删除操作。这里删除使用的GET
方法,故将stockApi
修改为:
1 | stockApi=http%3a%2f%2flocalhost%2fadmin%2fdelete%3fusername%3dcarlos |
即可完成lab
SSRF attacks against other back-end systems
这种类型与上述类型大致相同,只不过对象从localhost
变成了后端的系统。
有些情况下,server可以与一些后端系统交互,用户就不可以。这些系统通常IP是不可路由的(non-routable),由网络拓扑来防护,防护较弱。而且,往往有些敏感功能。
举例:管理界面在后端https://192.168.0.68/admin
。攻击者就可以使用SSRF漏洞,使用管理界面。
1 | POST /product/stock |
Lab: Basic SSRF against another back-end system
这里给出了192.168.0.X
,一个范围,需要我们自己去扫描,emmm,它要介绍burp suite的什么功能是吗?
是的,不出所料。介绍了Burp Intruder
可以设置其中的参数,然后设置范围,然后发送数据包。
- 先将修改后的request送去
Intruder
,这里选中
1
,Add $
- 切换到
Payloads
标签页,将Payload type
切换到Numbers
,From
1To
255,step
=1 - 然后开始
start attack
,根据状态码排序可以很方便的看到管理后台在247 - 在截获个数据包可以看到
1
GET /http://192.168.0.247:8080/admin/delete?username=carlos
- 因此可以修改
stockApi=http%3a%2f%2f192.168.0.247%3a8080%2fadmin%2fdelete%3fusername%3dcarlos
即可完成。
Circumventing common SSRF defenses
circumvent verb. 规避(为什么不用bypass了?
SSRF with blacklist-based input filters
一些应用程序会限制输入,像常见的127.0.0.1
和localhost
,或者敏感的URL,像之前的/admin
。这种情况下,可以使用一些技巧来规避:
- 使用
127.0.0.1
的替代表达,2130706433
,017700000001
or127.1
- 注册自己的域名,解析到
127.0.0.1
- 利用URL编码或是大小写变化,来混淆字符串。
- 提供一个URL重定向到目标URL。可以尝试用不同的协议。像
https
withhttp
Lab: SSRF with blacklist-based input filter
The developer has deployed two weak anti-SSRF defenses that you will need to bypass.
- 尝试了
/127.1/admin
,不行 stockApi=http%3a%2f%2f2130706433%2fadmin
,blocked ,https
has been blocked toostockApi=%68%74%74%70%3a%2f%2f%6c%6f%63%61%6c%68%6f%73%74%2f%61%64%6d%69%6e
也不行- 看了题解,将
admin
中a
进行两次url编码就可以绕过。 - 我最后使用
127.1/admin
,其中n
进行了两次url编码来绕过。 - 显示管理面板后,截获数据包
1
GET /admin/delete?username=carlos
- 像之前一样发送数据包即可完成。
SSRF with whitelist-based input filters
You may be able to bypass this filter by exploiting inconsistencies in URL parsing.
- 可以用
@
把credentials插入到hostname前边https://expected-host:fakepassword@evil-host
- 可以用
#
指明URL分片(?https://evil-host#expected-host
- 可以利用DNS域名分级(根,顶级,一级那个),来把要求的输入放入可控的,验证过的,DNS域名(?
https://expected-host.evil-host
- 可以使用URL编码来混淆。特别是过滤的实现和发送后端请求的实现不大一样时。也可以使用double-encoding
[[Essential skills]]
Lab: SSRF with whitelist-based input filter
- 尝试
127.1/admin
并进行double encode,不成功 - 看到response
1
2
3
4
5
6400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 58
"External stock check host must be stock.weliketoshop.net" - 看了solution,最终是使用
@
插入,并使用#
来分片,同时需要对#
进行double-URL encode - 这里判断能使用
@
,URL支持embedded credentials.是通过发送URLhttp://username@stock.weliketoshop.net/
stockApi=http%3a//localhost%3a80%2523%40stock.weliketoshop.net/admin/delete%3fusername%3dcarlos
Bypassing SSRF filters via open redirection
如果应用的api存在重定向漏洞,就可以构建一个满足过滤规则,最终重定向到target的URL,来利用。
举例 :
1 | /product/nextProduct?currentProductId=6&path=http://evil-user.net |
1 | POST /product/stock |
这种情况能通过过滤,是因为:应用首先检验提交的stockAPI
是在一个允许的域上。
Lab: SSRF with filter bypass via open redirection vulnerability
- 这里看到
stockApi=%2Fproduct%2Fstock%2Fcheck%3FproductId%3D1%26storeId%3D1
,我初步的想法是像上述一样,加个&path=
- 结果是正常查询,看起来后端并没有解析
path
参数。 - 看了solution后,我意识到我找错了地方,
Check stock
并没有相应的open redirection vulnerability , 而是在next product
- 这里看到
next product
包1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16GET /product/nextProduct?currentProductId=1&path=/product?productId=2
Host: 0a7800870442333983d36f8000e800f3.web-security-academy.net
Cookie: session=zeo9BMgCcN4bjQC9fjrolDifIF0bKfmA; session=FllaMdiROXA8bis59Av3ZhGZwIbkHzVg
Sec-Ch-Ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0a7800870442333983d36f8000e800f3.web-security-academy.net/product?productId=1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9 - 可以看到这里是存在一个
path
参数的。 构建新的参数1
GET /product/nextProduct?currentProductId=1&path=http://192.168.0.12:8080/admin
哥们在写完之后的下午上网站一看,发现后边都没有?震惊了,看来这个用HTML实现多行注释不咋地行
- 我意识到我的问题了,我应当修改
stockApi
, 从而利用/product/nextProduct
来实现重定向。而非是直接使用GET
去请求,这样是没法绕过的。 - 构建相应
POST
requeststockApi=%2fproduct%2fnextProduct%3fpath%3dhttp%3a%2f%2f192.168.0.12%3a8080%2fadmin
- 成功访问管理界面
stockApi=%2fproduct%2fnextProduct%3fpath%3dhttp%3a%2f%2f192.168.0.12%3a8080%2fadmin%2fdelete%3fusername%3dcarlos
构建相应 request即可
Blind SSRF vulnerabilities
^69fef6
我理解的是,跟sql盲注一样,能执行,但不给你返回response。这种类型的漏洞很难利用(这一点也跟SQLi差不对么),但是有时会导致RCE。
Finding hidden attack surface for SSRF vulnerabilities
大多数SSRF漏洞都容易发现。但也有一些比较难定位的:
Partial URLs in requests
这种就是只在request参数中放hostname或者部分URL,到服务端再拼接成完整的。因为没办法控制整个URL,所以可能有点难利用。
URLs within data formats
一些应用可能采用特定的格式传输URL,比方说XML。如果用XML格式的话,可能就存在 XXE injection漏洞。
SSRF via the Referer header
一些应用在服务端会有分析软件来记录访客。这些软件通常会记录请求中的Referer头,而且通常会访问Referer头中的任意第三方URL,以此分析这些网站的内容。因此,Referer头就可能是一个非常有效的SSRF攻击面。
Blind SSRF vulnerabilities
What is blind SSRF?
[[#^69fef6]]
What is the impact of blind SSRF vulnerabilities?
The impact of blind SSRF vulnerabilities is often lower than fully informed SSRF vulnerabilities because of their one-way nature.
哦,影响是不如“fully informed”,虽然有些情况下可以实现RCE,但是没办法泄露敏感信息。
How to find and exploit blind SSRF vulnerabilities
探测blind SSRF漏洞最可靠的方式是,使用out-of-band
OAST技术。就是想办法向攻击者控制的外部系统发送HTTP请求。
它这里推荐了一个 Burp Collaborator , 可以生成唯一的域名,payloads, 监控与域名的交互活动。
这里还提到一个特征是:观察到DNS look-up, 但是没有后续的HTTP请求。这就表示,应用试图发送request,然后就先DNS lookup,但是HTTP request被network-level filtering过滤掉了。
由于这个“blind”,所以没法去浏览系统上的内容。但是可以用blind SSRF去进一步地探测内部网络,尝试去发送一些波及范围比较广的其它漏洞的payload。
另一个利用blind SSRF漏洞的目的就是去,诱导应用连接到攻击者控制的系统,然后攻击者借此返回恶意response。
Lab: Blind SSRF with out-of-band detection
这个就是上述的referer类型[[#SSRF via the Referer header ]],这个实验室也是利用Burp Collaborator的。
- 这个连
checkstock
都没有 - 截获查看产品的
GET
request,送去repeater,选中Referer
,右键Insert Collaborator Payload
, 然后发送 - 去
collaborator
查看,结果我啥也没看到。emmm,看了下event log,觉得是不是我没挂代理的问题。 - 上设置里跑了个health check,结果全红。把代理那边
do dns lookups over socks proxy
选上了,解决了一些问题,但是SMTP connection 还是会报错。 - 按理说这也不应该啥都搜不到?这个lab也用不到smtp啊
- 看了community solution ,也没法发现自己怎么不对。以后有机会自建collaborator 再试试把。
Lab: Blind SSRF with Shellshock exploitation
也是会用到collaborator
,直接不做了。