文章目录
- 代码审计-文件包含漏洞
- 文件包含漏洞种类
- 当检测到目标存在文件包含漏洞时可以怎么利用
- 文件包含中php可使用的协议
- PHPCMS V9.6.3后台文件包含漏洞
- 后台路由分析
- 漏洞寻找
代码审计-文件包含漏洞
文件包含漏洞种类
当检测到目标存在文件包含漏洞时可以怎么利用
文件包含中php可使用的协议
PHPCMS V9.6.3后台文件包含漏洞
后台路由分析
访问后台登录页面
从url可猜测出来大致的路由 m为模块,c为控制器,a为方法,pc_hash为参数
使用admin模块
中的index控制器
中的login方法
漏洞寻找
当我们拿到源码后,可通过seay
对文件包含的关键函数进行大致的正则搜索
此处为此CMS
包含漏洞产生的php
文件
打开文件查看,此处对$filepath
这个变量内容进行了包含
通过分析$filepath
的由来我们可以知道,$filepath
变量存放的是一个文件的路径
并且在下面还通过file_put_contens
函数来将$str
中的内容写入到了这个文件中
然后进行include
包含此文件
因为会把$str
变量中的内容写到这个文件中,所以如果我们能控制$str
变量中的内容就能把恶意代码写到此文件中,最后include
还会来包含这个文件
接下来关注点就在$str
变量上了,让我们看一下$str
变量是怎么来的
通过代码可以看到,$str
变量是由$template
变量经过两个函数处理后得到的
继续跟踪下$template
变量的由来
如果 isset($_POST['template']) && trim($_POST['template'])
为真就将POST
传入的参数名为template
的值赋给变量$template
,如果为假就赋值为空
isset():检测变量是否为NULL
trim():去除字符串两的空格
可以看到此处只是接收了POST
方式传递的值赋给了$template
让我们看一下上面的两个函数new_stripslashes
和template_parse
对$template
做了什么操作才赋值给的$str
new_stropslashes函数
此函数中调用了stripslashes函数
来去除反斜杠
如果传入的参数是字符串就直接将addslashes()函数
添加反斜杠去除并返回
如果传入的是数组就循环递归将数组中的字符串中的反斜杠去除并返回
template_parse函数
此函数主要对模板{}
中的内容进行替换,也不会影响恶意代码的写入
经过分析,这两个函数都没有对我们需要写入的恶意代码造成威胁
现在我们则需要知道怎样才能将恶意代码写入到$template
变量中
此处可以看到
当&data['type']==1
时直接返回错误提示
当&data['type']==2
时才会向下执行,将我们POST[‘template’]
传入的值赋给$template
,再将$template
的值赋给$str
,再将$str
的内容写入到$filepath
变量所存放的路径对应的php
文件中,并包含
跟踪一下&data['type']==2
的由来
发现$data
中的数据是根据$id
这个变量通过get_one()
来查询数据库得到的,get_one()
的参数是一个数组,键为'id'
,值为我们传入的$id
也就是说GET['id']
传进来的值赋给$id
,然后执行get_one()函数
,get_one()
的参数为一个数组,键为字符串'id'
,值为变量$id
继续跟踪get_one()
函数查看
此函数执行的是一个sql语句的查询操作
因为我们想让$data['type']
的值等于2,就需要寻找添加的操作也就是找此处的$data['type']
是从哪里添加的
此函数为添加的函数
此处对数据库进行添加操作的sql
语句中的参数都是可以用户传入的
只要根据上面的内容对参数url
进行构造让type
的值传入为2就可以了
对url
进行构造
index.php
路由到modules目录
,m
选择block模块
,c
选择block_admin控制器
,a
选择add方法
,pos
为GET方式
提交的参数
dosubmit=1&name=test&type=2
为POST方式
提交的必要参数
dosubmit=1
因为if
对POST
传递的dosubmit
的值做了判断,如果不存在就不会向下执行
POST
方式传递的name
和type
都是下面必要的参数,存在时才会进行赋值给对应的$name
和$type
变量
访问该地址
此cms
是通过pc_hash
的值来判断是否登录,登录后重新访问该地址在url
后加上pc_hash
的值
POST
提交之前构造好的参数,此时页面显示操作成功
此时跳转到该页面,上面添加操作的sql
语句也成功执行
此页面对应的函数位置
需要的参数有GET
传的id
,通过对id
进行查询返回结果为数组赋值给$data
此时返回的内容就是我们之前进行添加的,所以$data['type']
为2
,继续向下执行
这里需要POST
参数
所以我们在页面处通过POST
将需要的参数传入
函数上面的POST
可以不用传,当没有值时就将空赋值给变量了,并不会阻断程序执行不产生影响
下面的POST['template']
就是对应的碎片模块
的输入框,点击预览进行提交
写入恶意代码点击预览后$template
变量接收到POST
传递的值,再将值赋给$str
变量
file_put_content
函数将$str
中的恶意代码写入到$filepath
变量中存放的文件路径对应的文件中
最后include
将$filepath
变量中存放的文件路径对应的文件进行包含,导致恶意代码执行
新建test_shell.php
成功