链接:https://pan.baidu.com/s/1gUrOhTiAQcjJmfB-Aq7fPA
提取码:e6o3
(安装时需要勾选模块)
参考文章:
https://www.freebuf.com/vuls/248912.html
0x00了解mvc架构
进入入口文件./index.php,先把defind定义的常量取出来
这里引用heihu师傅的代码,放在index.php的最后
foreach(get_defined_constants(true)['user'] as $k=>$v){echo $k.'---'.$v."\r\n";}
查看页面源码,复制出来,记在小本本上(文章下面的红体加粗的函数也建议拿出来记在小本本上)
做完这些来看index.php文件,第24行加载www/temmoku/run.php文件
跟进run.php文件,33行加载了functions.php文件,35行加载app.php文件,37行调用其中的run方法。
我们先跟进functions.php文件大体扫一下基本的函数,着重关注下一过滤函数,以及相关的获取头文件参数的函数,像其他的C方法在后面会遇到等遇到的时候再看就可以。
大体了解functions.php文件后,我们再回来看app.php下的run(),17行出现自动加载函数spl_autoload_register()
加载了类中的Load_Class(),跟进一下(有关自动加载类的函数知识https://www.bilibili.com/video/BV14p4y1a742,https://www.bilibili.com/video/BV1kt411Q7np?p=11)
找到Load_Class方法,第80行调用了str_caps_look()跟进。
传入的参数为1所以是将字符串转化为小写返回字符串
从81-84行$_class数组中就可以看出加载类的范围了分别是根目录下的php文件和/app下的php文件,87-94行为加载此范围的文件执行代码。
回到run()函数,18行setReporting()函数为检测开发环境以及配置日志,APP_DEBUG为空进入53-58行。
回到run,看第19行跟进default_config()函数。102-113行判断是否开启高速缓存,并判断是否开启。114-118行调用了Load_config()函数加载了两个文件。
我们先来看一下函数怎么用的,995行因为CACHING为空所以不会走995的if分支,进入1010行if语句,先对传过来的参数进行了处理,1014-1025行分割来进行模块识别,继续往下读。
看到1026行将输入的参数目录下的文件遍历,在1031-1033行包含此目录下的文件,后面1056-1059的else if分支直接进行了包含,看到这我们了解到Load_config方法是将参数下的文件全部包含。
回到app.php文件的116行,我们知道了116-118包含了conf目录下的文件和route下的文件。后面使用了几个C方法,我们直接看下C方法的功能。
从函数解释我们可以了解到C方法是获取配置参数和修改配置参数的,但其配置参数分成好几个文件在左边红框中,我们可以利用开头的if分支来获取全部的配置参数。
C方法调用若没有name值得输入,则会返回全部配置参数,我们在index.php最后将返回值返回到一个参数中再输出来获取全部配置信息,将获取得配置信息记在小本本上方便查阅。
读完C方法我们回到default_config方法,我们大概了解到此方法的功能即加载配置文件加载路由文件,获取配置参数并定义成常量,所以我们回到run方法继续向下,第28行new了一个route,根据之前的自动加载函数是加载www/下和/www/app下的php文件,但此处的的有个use temmoku/route,所以出入的$class为temmoku/class.php,此时的范围拼接一下为www/temmoku/class.php和www/app/temmoku/class.php。(自动加载类和命名空间的解释:https://blog.csdn.net/qingshuoyisheng123/article/details/79132669)
我们通过范围来寻找一下这个实例,路径为WWW/temmoku/route.php,有个魔术方法我们来看下,加载了个module_route.php文件,第21行调用Route()函数,跟进一下。
第一个if语句可以通过获取temmoku_dirs的值来设置$_SERVER[PATH_INFO]的值,第二个if语句为PATH_INFO为空时,设置为_SERVER[$type]的值
第三个if语句是用/对PATH_INFO进行分割,以获取M A C。第55行中的ROUTE值为空所以我们55-74暂时不看。
除去PATH_INFO后的后缀以及其他的字符
当MODULE为false时,89-92行将PATH_INFO分割,并将$paths[0]赋值给$test_module,97行验证$test_module的值是否存在于MODULE_ROUTE中,存在则说明是模块,将其赋值给MODULE,并将$_SERVER[PATH_INFO]的值改为paths[1]。若$test_module不存在于MODULE_ROUTE中,则判断是否是定义的路由插件,并定义is_plugin为true。后面的则对89行获取失败时的处理。
123-125对MODULE在未获取到的情况下进行默认设置,132-136则对在MODULE不为admin时进行处理,前面默认为home,所以我们获取到了m,c,a的值,139则对没匹配到的情况做了处理,141-143对MODULE为admin时,调用Admin_Route(),我们暂时先不看继续往下。
146-157对自定义的模块进系了处理,前面有提到is_plugin为true时的条件,此处是对模块的的处理,包含并实例化,159-172是对PATH_INFO进行分隔,分别当作控制器与方法,174-175行如果不存在则默认都为Index,到此Route就读完了。__construct魔术方法也完了,但此文件最后有个析构函数,我们来看下。
调用了filtering()和un_reg_ister_Globals()方法,跟进看下。
filtering函数过滤了传过来的参数,un_reg_ister_Globals()的232行因为php默认关闭此参数,所以我们一带而过。跟进下filtering方法。
对数组中的id进行了int和htmlspecialchars过滤,到此我们的Route就读完了。转一下此处heihu师傅的绕过姿势
(反斜杠\没有被转义,这样在SQL语句中我们可以通过\来对SQL语句进行打乱。前提是有两个可控点。
例如:SELECT FROM XXX WHERE A=’1’ AND B=’2’
在A中插入反斜杠在B中插入攻击语句,SQL语句变为SELECT FROM XXX WHERE A=’1\’ AND B=’ or updatexml(1,concat(1,user(),1),1) — ’
也可以进行SQL注入,第二种情况则是有一个可控点,但是没有被单引号包裹。
并且可控点A以及可控点B如果是由外部传递,都不可以键值为:’id’,’aid’,’cid’,’uid’,’mid’,’cmid’,’iid’,’nid’,’cityid’,’proviceid’,’countyid’,’townid’,’upcid’,’state’,’reply_id’,’lid’)
此处is_log为0,我们略过不读,22行为Load_Controller()我们跟进。
65行MODULE为admin、user、install、home时$home为空,否则为\home,67行是is_plugin为true时(前面提到过)则加载插件,$controller为加载模块或插件的位置,若存在则进入if分支new这个控制器(70),并调用传过来的$METHOD方法(71),不存在则报错。
到这我们就对这个框架有了大概的了解了相关的路由方式,过滤方法,以及函数库的存放。
一:http://www.temmoku.com/模块名/控制器/方法
./app/模块名/controller/控制器.php
二:http://www.temmoku.com/?temmoku_dirs=模块名/控制器名/方法名
./app/模块名/controller/控制器.php
0x01SQL注入
根据heihu师傅的经验(在我这就是我的了/狗头),sql注入多发生在where中的in里所以我们搜索in ( 找的了一个$uidDB变量,这个变量没在我们之前那个过滤的魔术方法的数组中,很可能存在sql,来测试一下。
可以看到时admin下的user的删除操作,所以应该时后台中的用户管理的删除操作,我们来抓一下包来测试。
0x02SQL注入
继续往下,看到这个$id变量,虽然在魔术方法中过滤了,但此处是通过$iddb参数传入的,所以可能存在SQL注入,我们来仔细看一下代码怎么走的。
看以看到我们传入参数$iddb时,我们可以进入elseif分支,之后会查询是否有删除评论的权限,所以利用这个漏洞需要删除评论权限,然后将$iddb参数赋值给$id,进行数据库查询,来确定是否是用户自己的评论,此处就是我们的注入点了。
先来设置一下删除评论的权限
抓包
放入sqlmap跑一下
0x03任意文件删除
搜索unlink函数,检查到这个文件
看一下怎么用的,发现$oldfile变量是可控的,变量$oldfile为删除文件的路径,260行检测路径中是否含有tmp,没有则返回img,反之执行下面操作。
找一下此函数的利用点,本文件下46-48行,去网页中瞅瞅。
直接访问 http://127.0.0.1/?temmoku_dirs=user/renzheng/index 页面,发现需要登入,跳转到登入页面发现验证码显示不出来,我们可以到存放插件的目录下,找到登陆插件将验证码检测屏蔽掉就能登录了(用户账号可以直接从后台注册不用验证码)。
登录成功后抓包,检测,删除成功。
0x04CSRF漏洞
通过我们对网站框架的了解,我们并没有发现防御CSRF的代码段,若不放心的可以去后台首页和用户登录后的界面处的代码去审计一下,或者直接黑盒(这样快一点),我们拿添加管理员测试一下。首先对请求抓包。
利用自带bp的工具生成测试代码,放到浏览器测试,生成超级管理员。
0x05双引号解析漏洞
配置信息是用双引号引起来的,如果我们可以设置控制信息,那么就有可能执行我们输入的命令。
后天中有一个可以控制上传目录的点,我们打开代码看下
定位到app/admin/controller/setting.php,调用了post()函数
获取到了一些传入参数后,又调用了模板类中的post()
将获取的参数更新到数据库中
修改为attachment${@phpinfo()}
可以看到phpinfo()已经插入到配置信息中并执行了
0x06总结
只看没啥用,复现一遍胜过看千遍。还有学一门外语很重要,至今没搞懂phpstorm的全局搜索,还得破解,试试notepad++
