记一次某 CMS 的代码审计(下)

VSole2021-12-31 16:21:37

接下来再看 g 方法,g 方法也是将 f 方法的返回值作为参数传入。

首先第 113 行从配置文件中获取了路由的相关信息,并赋值给 $u。随后 115 行判断传入的 $q 参数,这里判断为 false,不进入语句。

第 119 行将路由信息进行遍历,匹配传入的 url 路径信息。匹配成功则将 url 路径信息中的路由键替换为路由值,最后将替换后的 url 路径信息返回。

i 方法也是将刚刚返回的 url 路径信息传入,我们来看一下具体实现。第 133 行从配置文件中读取了配置模块信息,注意这里第二个参数为 true,所以 $w 为一个数组(home,admin,api)。

程序第 134-139 行将传入的 url 路径信息分割为数组 $r_array。第 140-155 行是程序的路由分配,根据数组元素的长度,将值分别赋值给 $h 数组元素。

注意这里的 m、c、f 并非是我们自定义的元素,而是 Kernel.php 文件中所原有的,我们可以回顾最开始被解密的文件。因此猜测 m 对应模块,c 对应控制器,f 对应方法。

继续阅读代码,第 156-167 行是为 m、c、f 进行初始化。第 168-171 行是判断模块是否存在于预定义的数组中,最后返回包含路由信息的数组 $h。

接下来我们再看看 k 方法,k 方法传入了包含程序路由信息的数组。第 178-180 行,定义了代表模块的常量 M,并根据模块定义了模块下的模型路径、控制器路径常量。

第 181-195 行判断模块模板路径是否存在于当前模块的模板路径中,以及网站根路径是否存在于当前模块的模板路径中,将路径赋值给 APP_VIEW_PATH 视图模板常量。

第 194 行,判断控制器中是否存在.字符。若存在则将其替换为/字符,获取其路径中的文件名,并将首字母大写赋值给 $controller 变量。

若不存在.字符,则直接进行首字母大写并赋值给 $controller 变量。第 205 行获取完整的控制器路径,第 208-223 行根据模块及控制器来定义常量。

第 226 行定义控制器常量 C,第 227-235 行根据 REQUEST_URI 值来定义 URL 常量。第 227-246 行根据包含路由信息的变量 $a 元素数及 $dd 值,获取 GET 请求参数,最终返回控制器名称。

随后返回 Kernel.php 文件,我们还剩 l、m 方法没有看,下面看一下 l 方法。

第 251 行判断程序是否处于调试模式,debug 默认为 false,若处于调试模式会获取一些配置文件并检查关键文件是否存在。

第 252-265 行判断,如果当前模块为 api 时,request 函数判断用户请求是否携带了 sid 参数,若存在则开启 Session,我们跟进看一下 request 函数。

第 532-536 行检查用户的请求类型(POST/GET),随后将其传入数组 $condition 中,并参数名及数组传入 filter 过滤函数中,我们再次跟进 filter。

代码首先在第 289 行判断传入的参数是否在数组键中,且是否拥有对应的变量描述文本。

若满足条件则将其赋值给 $vartext 变量,不满足则将参数赋值给 $vartext。随后第 296-316 行,根据请求类型获取对应的参数值赋值给 $data。

随后的代码对数据进行了非常严格的类型检测、过滤、转义等操作,最终返回数据。

过滤代码使用了自定义的 preg_replace_r 函数,其作用是递归替换。

转义代码将数组、对象数据类型分别转化为字符串类型,随后又用了 htmlspecialchars 函数以及 addslashes 函数进行处理,htmlspecialchars 函数使用 ENT_QUOTES 参数,无法单引号绕过,同时指定了 UTF-8 编码。

读完后我们回到 Kernel.php 文件继续读 l 方法。程序第 261-265 行,若当前模块不为 api,则对用户的浏览器及操作系统进行检测。

分别跟进 checkBs 和 checkOs 方法。首先 checkBs 注释写的很明确,首先 105-106 行读取配置文件,获取黑/白名单。

随后使用 get_user_bs 方法获取客户端浏览器类型,并根据黑/白名单进行拦截/放行。

我们跟进 get_user_bs 方法,首先判断 UA 信息是否存在,若存在则将其转化为小写,并赋值给 $user_agent 变量。

其次检测参数 $bs 是否存在,若存在则判断 $user_agent 是否包含在 $bs 中,并返回 true/false。

随后即进行与已定义的浏览器进行固定检测,由于 $user_bs 的值为写死的,无法通过修改 UA 来进行日志注入等操作。

随后 get_user_os 函数原理相同,不再记录。随后 266-279 行都是在检测相应文件是否存在,若存在则进行包含。第 280-284 行,程序检查对应控制器文件是否存在,存在则进行实例化。

至此,l 方法我们也已经读完了,还剩下最后的 m 方法,我们跟进看看。

方法 m 接受一个控制器路径参数,第 288-291 行都是将控制器路径信息进行赋值。第 292 行判断对应的控制器文件是否存在,若不存在则返回 404 错误。第 306-309 行,判断类中是否存在对应的类方法,若不存在则返回错误信息。

第 310-332 行对类进行了实例化操作,并判断对应方法在类中是否存在。若存在则判断是否存在同名方法,若存在则执行方法,将返回值赋值给 $nn。若不存在同名构造方法,则返回赋值实例化后的值。

若类中不存在对应方法,判断类中是否存在 _empty 方法,若存在则执行获取返回赋值给 $nn,若不存在则返回报错信息。最后第 333-337 行判断返回的 $nn 是否为空,若不为空则输出 $nn。

至此,index.php 入口文件我们已经读完,接下来看看 admin.php 文件。

admin.php

可以看到,一切都是那么的熟悉,跟 index.php 的区别就是常量 URL_BIND 变为了 admin。

最后我们再来看一下最后一个入口文件 api.php

api.php

结构也是一样的,常量 URL_BIND 变为了 api。

04 漏 洞

操作系统/浏览器黑白名单绕过

Kernel.php 的第 250-262 行,若当前模块不为 api 时,系统会检查用户的操作系统/浏览器是否在黑白名单中。

跟进 checkBs,105-106 行检查浏览器浏览器是否在配置文件的黑白名单中,在 111 行获取用户浏览器。

跟进 get_user_bs,系统直接通过 UA 头获取用户浏览器,进行黑白名单比对。

因此我们直接去到 config.php 中设置黑名单,禁止 firefox 浏览器访问。

设置后发现页面已经无法访问

通过 BurpSuite 将 UA 头进行修改,即可绕过限制,操作系统相关黑白名单同理。


05 存储型 XSS

过滤不严格导致的存储型 XSS

后台文章内容 -> 新闻内容 -> 新闻新增处存在存储型 XSS

首先黑盒测了一波,随便新建了一篇文章,并上传了一张图片附件。

抓包并观察数据包,发现 content 字段为我们刚刚提交的正文部分。

将其进行 URL 解码,发现内容中存在 HTML 标签。

因此我们可以尝试在 HTML 标签中加入一段 XSS 的 Payload,触发存储型 XSS

将修改后的 content 值重新放到 Burp 中重发,并将标题名改为了 hello2022,服务器返回 200 成功

接下来我们回到前台,进入新闻中心进行查看,成功触发 XSS

代码分析:

首先根据数据包路由信息,我们定位到代码位置:

/apps/admin/controller/ContentController::add

可以看到,上来就是使用自定义的 post 方法获取一堆数据。

但是我们注意到,在这里的 post 方法大部分都是没有指定第 2 个参数的,而第 2 个参数的作用是限制数据类型。

而 add 方法也仅对部分变量做了规范化处理,并未对 content 进行相应处理,如过滤敏感标签、事件等。

随后将 content 变量放入了一个 data 数组中,调用 addContent 写入数据库,最终导致存储型 XSS。

由于逻辑相似,系统新闻内容、产品内容、案例内容、招聘内容等功能点均存在存储型 XSS漏洞。

上传 pdf 文件导致的存储型 XSS

在查看代码的配置文件 config.php 时,发现允许上传 pdf 文件,就想到了这个漏洞。

首先生成一个嵌有 js 脚本的 pdf 文件,然后正常作为附件上传即可,具体生成操作可参考百度。

前台访问文章附件触发:

06 反射型 XSS

看代码实在是看累了,就把网站丢进了扫描器。首先是扫到了一个 XSS ,我们验证一下结果。

好像还真的存在,类型的标签乱了。

我们随便敲个 ext_color=1,F12 看一下

可以看到图中的信息在 a 标签的 href 中被原样输出了,因此我们可以构造payload。

payload:http://127.0.0.1:8002/?product/&ext_color=1%22%3C/a%3E%3Cimg%20src=1%20onerror=alert(`1`)%3E

成功弹窗

07 SQL 注入

随后又扫到了一个 SQL 注入,我们验证一下结果。

恩?好像确实有东西

我们在 vscode 中搜索关键字 OR a.filename= 。发现第 559-566 行即拼接 SQL 语句的地方,$id 参数没有做过滤。

接下来我们最好能把拼接好的 SQL 语句打印出来,根据完整的语句构造注入。首先看到这个结构想到了 ThinkPHP,在 TP 中可以使用 fetchSql、buildSql 等方法打印 SQL 语句。

但尝试后发现行不通,使用 buildSql 后程序直接报错了,看来只能是用其他方法。


我们跟进最后的 find 方法,在第 992 行插入 var_dump 强行打印拼接后的 SQL 语句试一试。

成功返回了 SQL 语句,可以看到我们输入的12'" 在圆括号中包裹。

接下来我们就可以根据语句来构造特定语句了(这里要注意程序默认使用的是 sqlite 数据库)

Payload:http://127.0.0.1:8003/?1')/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,randomblob(1000000000)--

可以看到,根据右下角延时时间的对比,成功证明存在 SQL 注入漏洞。

文章到这里就结束了,出于个人原因这套 CMS 我并没有审计完成。后续如果时间允许的话,我也会继续以文章的形式分享出来。

文章中所写的内容只是我个人在进行代码审计学习时所记录的笔记,希望能帮助到一些想要学习代码审计的同学。其中如果有错误的内容也希望大佬们能帮我指出,大家一起学习和进步。

xss赋值语句
本作品采用《CC 协议》,转载必须注明作者和本文链接
前言本次审计的话是Seay+昆仑镜进行漏洞扫描Seay的话它可以很方便的查看各个文件,而昆仑镜可以很快且扫出更多的漏洞点,将这两者进行结合起来,就可以发挥更好的效果。$sql = 'select * from xtcms_manager where m_name = "'.$a_name.'" and m_password = "'.md5.'"';验证码的校验代码if ($_SESSION['verifycode'] !该文件的含义是用0-9中的任意四个数字作为验证码,也就是说js引用该文件来产生验证码。wap/seacher.php昆仑镜扫描利用seay查看源码//这只是一部分,具体的师傅们可自行查看此文件
接下来再看 g 方法,g 方法也是将 f 方法的返回值作为参数传入。 首先第 113 行从配置文件中获取了路由的相关信息,并赋值给 $u。随后 115 行判断传入的 $q 参数,这里判断为 false,不进入语句。 第 119 行将路由信息进行遍历,匹配传入的 url 路径信息。匹配成功则将 url 路径信息中的路由键替换为路由值,最后将替换后的 url 路径信息返回。
php代码审计总结
2021-09-21 09:27:39
在php中可由用户输入的变量$_SERVER$_GET$_POST$_COOKIE$_REQUEST$_FILES. 对于此类函数,可以使用php伪协议进行一个绕过。
sql注入已经出世很多年了,对于sql注入的概念和原理很多人应该是相当清楚了,SSTI也是注入类的漏洞,其成因其实是可以类比于sql注入的。BladeBlade 是 Laravel 提供的一个既简单又强大的模板引擎。它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
在刚接触安全渗透的时候,常对于各种各样庞杂的技术感到有些头皮发麻,sql注入,xss,csrf,ssrf等一众名词也让人有些望而生畏。后来在前辈的指引下认识到了sqlmap,nmap等工具,在进行了一段时间的学习后,慢慢对sqlmap的其中一个参数非常的感兴趣——m参数,也就是对文件中存在可注入的链接进行注入测试,这种批量的扫描漏洞的行为极大的激发了我学习的兴趣,同时也想要找到比sqlmap能更加
CTF-web--命令注入
2023-03-31 09:51:35
大佬总结的文章,本篇文章阅读时间大约30分钟。一 、基本原理 命令注入指的是,利用没有验证过的恶意命令或代码,对网站或服务器进行渗透攻击。注入有很多种,并不仅仅只有SQL注入。Injection)客户端脚本攻击(Script?injection)动态函数注入攻击(Dynamic?Evaluation)序列化注入&对象注入。这种题目又哪些常见的,一个是我们常用的文件包含,我们是可以使用system等函数的,或者是php函数,应该也属于命令注入的范畴。类似于 ?
个人认为,作为一个要入门代码审计的人,审计流程应该从简单到困难,逐步提升。而我在进行blueCMS审计之前,网上也搜索了blueCMS的审计文章。一般都是文章中只提到了两个漏洞,一个是位于根目录下的ad_js.php文件中,存在sql注入。
idea直接创建新建项目,自动导入xml文件,配置启动服务器导入sql文件mysql?这里需要注意一点儿,源码确实,无法打包war'包,解决不掉artifacts的问题配置端口启动tomgcat的时候会乱码,
服务器的相关信息(真实ip,系统类型,版本,开放端口,WAF等) 网站指纹识别(包括,cms,cdn,证书等),dns记录 whois信息,姓名,备案,邮箱,电话反查(邮箱丢社工库,社工准备等) 子域名收集,旁站,C段等 google hacking针对化搜索,pdf文件,中间件版本,弱口令扫描等 扫描网站目录结构,爆后台,网站banner,测试文件,备份等敏感文件泄漏等 传输协议,通用漏洞,ex
⽹上整理的⾯试问题⼤全,有些 HW ⾯试的题,已经收集好了,提供给⼤家。
VSole
网络安全专家