第二届CN-fnstCTF web题解
字数 1179 2025-08-22 12:22:15

CN-fnstCTF Web题解教学文档

题目1: ez_python

题目分析

这是一个基于Flask的Python Web应用,主要功能点:

  1. 文件读取功能
  2. 模板注入功能
  3. 使用了速率限制

源码分析

文件读取功能

@app.route('/')
@limiter.exempt
def index():
    file_path = request.args.get('file')
    if file_path and "proc" in file_path:
        return "只过滤了proc,别想用这个了,去读源码", 200
    if file_path:
        try:
            with open(file_path, 'r') as file:
                file_content = file.read()
            return f"{file_content}"
        except Exception as e:
            return f"Error reading file: {e}"
    return "Find the get parameter to read something"
  • 通过file参数读取文件
  • 仅过滤了包含proc的路径
  • 可以读取任意文件(如app.py

模板注入功能

@app.route('/shell')
@limiter.limit("10 per minute")
def shell():
    if request.args.get('name'):
        person = request.args.get('name')
        if not waf.waf_check(person):
            mistake = "Something is banned"
            return mistake
        template = 'Hi, %s' % person
        return render_template_string(template)
    some = 'who you are ?'
    return render_template_string(some)
  • 通过name参数进行模板渲染
  • 存在WAF防护

WAF防护

def waf_check(value):
    dangerous_patterns = ['os', 'set', '__builtins__', '=', '.', '{{', '}}', 'popen', '+', '__']
    for pattern in dangerous_patterns:
        if pattern in value:
            return False
    return True

过滤的关键字和符号:

  • os, set, __builtins__, popen
  • =, ., +
  • {{, }}
  • __

解题步骤

  1. 文件读取

    • 通过?file=app.py读取源码
    • 通过?file=waf.py读取WAF规则
  2. 模板注入绕过

    • 绕过.过滤:使用[]代替点号访问属性
    • 绕过__过滤:使用十六进制或Unicode编码
    • 示例payload:?name={% print(request["application"]["__globals__"]["__builtins__"]["__import__"]("os")["popen"]("ls")["read"]()) %}
  3. 实际利用

    • 构造无.__的payload
    • 使用字符串拼接绕过关键字过滤
    • 最终获取flag

关键点

  • Flask的SSTI漏洞利用
  • WAF绕过技巧
  • Python属性访问的多种方式

题目2: 三千零一夜

题目分析

  • 明显的SQL注入漏洞
  • 存在过滤机制
  • 需要双写绕过

解题步骤

  1. 探测注入点

    • 输入\或单引号测试闭合
    • 确认存在字符型注入
  2. 绕过过滤

    • =被过滤 → 使用like
    • like被过滤 → 使用双写likelike
    • 注释符被过滤 → 使用逻辑闭合
  3. 信息收集

    • 联合查询确定回显位(位置1)
    • 查询数据库:flaginit
    • 查询表:fflllaaaagggg
    • 查询列:trueflag
  4. 获取flag

    • 构造最终查询语句获取flag
    • 由于题目下架,最终flag未获取

关键点

  • SQL注入双写绕过技术
  • =like时的替代方案
  • 逻辑闭合代替注释符

总结

ez_python关键技巧

  1. 文件读取漏洞利用
  2. Flask SSTI绕过WAF:
    • 属性访问:request["application"]代替request.application
    • 字符串拼接绕过关键字过滤
    • 编码绕过特殊字符过滤

三千零一夜关键技巧

  1. SQL注入双写绕过
  2. =时的替代方案
  3. 逻辑闭合代替注释

防御建议

  1. 对于文件读取:

    • 限制可访问目录
    • 使用白名单而非黑名单
  2. 对于模板注入:

    • 避免使用render_template_string
    • 使用安全的模板引擎
    • 严格过滤输入
  3. 对于SQL注入:

    • 使用参数化查询
    • 最小权限原则
    • 多层防御机制
CN-fnstCTF Web题解教学文档 题目1: ez_ python 题目分析 这是一个基于Flask的Python Web应用,主要功能点: 文件读取功能 模板注入功能 使用了速率限制 源码分析 文件读取功能 通过 file 参数读取文件 仅过滤了包含 proc 的路径 可以读取任意文件(如 app.py ) 模板注入功能 通过 name 参数进行模板渲染 存在WAF防护 WAF防护 过滤的关键字和符号: os , set , __builtins__ , popen = , . , + {{ , }} __ 解题步骤 文件读取 : 通过 ?file=app.py 读取源码 通过 ?file=waf.py 读取WAF规则 模板注入绕过 : 绕过 . 过滤:使用 [] 代替点号访问属性 绕过 __ 过滤:使用十六进制或Unicode编码 示例payload: ?name={% print(request["application"]["__globals__"]["__builtins__"]["__import__"]("os")["popen"]("ls")["read"]()) %} 实际利用 : 构造无 . 和 __ 的payload 使用字符串拼接绕过关键字过滤 最终获取flag 关键点 Flask的SSTI漏洞利用 WAF绕过技巧 Python属性访问的多种方式 题目2: 三千零一夜 题目分析 明显的SQL注入漏洞 存在过滤机制 需要双写绕过 解题步骤 探测注入点 : 输入 \ 或单引号测试闭合 确认存在字符型注入 绕过过滤 : = 被过滤 → 使用 like like 被过滤 → 使用双写 likelike 注释符被过滤 → 使用逻辑闭合 信息收集 : 联合查询确定回显位(位置1) 查询数据库: flaginit 查询表: fflllaaaagggg 查询列: trueflag 获取flag : 构造最终查询语句获取flag 由于题目下架,最终flag未获取 关键点 SQL注入双写绕过技术 无 = 和 like 时的替代方案 逻辑闭合代替注释符 总结 ez_ python关键技巧 文件读取漏洞利用 Flask SSTI绕过WAF: 属性访问: request["application"] 代替 request.application 字符串拼接绕过关键字过滤 编码绕过特殊字符过滤 三千零一夜关键技巧 SQL注入双写绕过 无 = 时的替代方案 逻辑闭合代替注释 防御建议 对于文件读取: 限制可访问目录 使用白名单而非黑名单 对于模板注入: 避免使用 render_template_string 使用安全的模板引擎 严格过滤输入 对于SQL注入: 使用参数化查询 最小权限原则 多层防御机制