2026獬豸杯wp-手机部分"

admin 2026-10-20 16:58:21 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

cover_image PASSWORD_FILE = \"常用密码.txt\"     # 密码字典路径
OUTPUT_DIR = \"./extracted_data\"   # 解压成功后的文件存放目录

def brute_force():
    if not os.path.exists(IMAGE_PATH):
        print(f\"[-] 错误:找不到图片文件 {IMAGE_PATH}\")
        return
    if not os.path.exists(PASSWORD_FILE):
        print(f\"[-] 错误:找不到密码文件 {PASSWORD_FILE}\")
        return

# 创建输出目录以防覆盖当前目录文件
    if not os.path.exists(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)

print(f\"[*] 开始爆破 {IMAGE_PATH},使用字典:{PASSWORD_FILE}...\")

# 读取密码字典
    with open(PASSWORD_FILE, 'r', encoding='utf-8', errors='ignore') as f:
        passwords = [line.strip() for line in f]

for index, password in enumerate(passwords, 1):
        # 打印当前进度(\r 实现原地刷新效果)
        print(f\"[{index}/{len(passwords)}] 正在尝试密码: {password:<20}\", end='\r')

# 构建 steghide 命令
        # -sf: 指定隐写文件
        # -p: 传入密码
        # -xf: 指定提取出的文件路径(避免污染当前目录)
        # -f: 如果文件已存在则强制覆盖
        cmd = [
            \"steghide\", \"extract\",
            \"-sf\", IMAGE_PATH,
            \"-p\", password,
            \"-f\"
        ]

try:
            # 运行命令,捕获输出并隐藏报错信息
            result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=5)

# 如果返回值是 0,说明密码正确,提取成功
            if result.returncode == 0:
                print(\"\
\" + \"=\"40)
                print(f\"[+] 爆破成功!\")
                print(f\"[+] 正确密码为: {password}\")
                print(f\"[+] 提取出的文件已保存在当前目录下。\")
                print(\"=\"
40)
                return
        except subprocess.TimeoutExpired:
            print(f\"\
[-] 密码 '{password}' 测试超时,跳过。\")
            continue
        except Exception as e:
            print(f\"\
[-] 运行 steghide 时发生异常: {e}\")
            return

print(\"\
\" + \"=\"40)
    print(\"[-] 爆破结束,字典中的密码均不正确。\")
    print(\"=\"
40)

if name == \"main\":
    brute_force()
```


7. 请分析检材1:嫌疑人向数据贩子购买公民个人信息共计多少条?【答案格式:123】

100

这个应该就是要找聊天app的题目了

翻了一下,这三个是嫌疑最大的

telegram包名下没看到文件,先翻看其他两个的

直接仿真起来(具体操作可见盘古石wp手机部分24题),但是发现两个都需要登陆账号密码

在连趣的包名文件夹下发现了登陆账号17706223971密码JHTJ88888


8. 请分析检材1:嫌疑人向数据贩子交易时使用的付款方式是什么?【答案格式:支付宝】

很行卡

提到了在i聊里面接着谈

找了半天找不到i聊的登陆密码,还是翻数据库吧

data/uni.app.UNI04963C4/files/1600123285\_3137373036323233393731/msg\_0.db

可以看到问wx、支咐宝、很行卡,数据贩子选择了YHK
9. 请分析检材1:数据贩子交易过程中提供的很行卡号是多少?【答案格式:6222351234482925678】

6222355973482923738

同上题图
10. 请分析检材1:接上题,嫌疑人所使用聊天工具的用户 ID 是多少?【答案格式:12345】

不确定1355997814/1778574712018

感觉这题没说清楚,是连趣还是i聊?

连趣app用户ID可以仿真直接看

![](https://mmbiz.qpic.cn/sz_mmbiz_png/tNS6iaKdc2uvG50XiancJPA43WQBM2UDHXiauicicnKmtQlLLKKk3YR7XE2TRNJFg4wwbwRjpuRjhH9p06xBwFFT38RiaD2rveA6Y6s2UwNhRqeh0/640?wx_fmt=png&from=appmsg&watermark=1#imgIndex=16)

,也可以翻com.lianqujiaoyou.chat/shared\\_prefs/FlutterSharedPreferences.xml

![](https://mmbiz.qpic.cn/mmbiz_png/tNS6iaKdc2utvhrsFJicNaT08mYghKmVATibrkIjjY2vyTFO5ATCesppLu7emb7icZF9XMom5nInq7ic4yWtOibnglQWRlaB7ib5OpPtAzKEs7DAHQ/640?wx_fmt=png&from=appmsg&watermark=1#imgIndex=17)

i聊app用户ID可以从这里看出来

![](https://mmbiz.qpic.cn/sz_mmbiz_png/tNS6iaKdc2uur1GhiaMmWTU8wr4Js0iazUPIa3Aw5ibOGsFv7IenbNib8jMF7MFXYicevcibeFk1myGA6royfsia8iaicibAiaBptNuPSAjdcswmN7GyWWE/640?wx_fmt=png&from=appmsg&watermark=1#imgIndex=18)

也可以从连趣app聊天记录的二维码看出来

“type”:“personal”,“userID”:“17706223971”,“nick”:“搁浅”,“timestamp”:1778574712018
  1. 请分析检材1:嫌疑人使用浏览器访问了该下载链接,该浏览器对应的包名是什么?【答案格式:com.heytap.market】

    com.meiit.browser

    上面i聊的聊天记录说,用百度网盘传了数据,且密码是嫌疑人手机号

    从仿真起来的连趣app可以看到手机号17706223971

    在apk列表搜索浏览器,有三个浏览器,最后在鲁班浏览器找到了下载记录包含百度网盘的:
    12. 请分析检材1:嫌疑人于何时下载数据商人发送的数据压缩包文件?【答案格式:2022-02-02 12:00:00】

    不确定,2026-05-12 17:00:05 / 2026-05-12 17:00:07

    这一题需要翻阅百度网盘app

    2026-05-12 17:00:05可能是一个答案

    但是百度网盘自带的数据库也记录了下载时间

    /user/0/com.baidu.netdisk/databases/stats.db

    这里是2026-05-12 17:00:07,究竟哪个才是对的,我更倾向于后者,因为前者2026-05-12 17:00:05只是上传时间


    13. 请分析检材1:接上题,该压缩包的解压密码是什么?【答案格式:根据实际值填写】

    17706223971

    密码是嫌疑人手机号,11题有讲
    14. 请分析检材1:接上题,年龄在 40 至 60 岁(含 40、60 岁)的富豪共有多少人?【答案格式:123】

    46

    解压数据.zip,得到一个有关富豪的个人信息表,对出生日期排序(担心平台因为出现隐私信息给ban了,只能这样了)

    40-60岁,就是1966-1986出生的,一共有59-14+1=46个


    15. 综合分析:请找出嫌疑人筛选的重点客户名单,并统计名单内共有多少人?【答案格式:1】

    5

    之前图片隐写爆破密码出来的文件还没用过,重点客户.z01

    用010editor打开发现是zip头,但是改后缀为zip发现解压失败,提示已损坏

    搜了一下知道这个是分卷解压,有主卷重点客户.zip才方便解压(只有分卷也可以,见下面ai给的脚本)

    ```
    from future import annotations

    import re
    import struct
    import sys
    import zipfile
    import zlib
    from datetime import UTC, datetime
    from pathlib import Path
    from xml.etree import ElementTree as ET
    from xml.sax.saxutils import escape

    DEFAULT_OUTPUT = \"\u91cd\u70b9\u5ba2\u6237.xlsx\"
    SHEET_NAME = \"\u91cd\u70b9\u5ba2\u6237\"

    def col_to_num(col: str) -> int:
        n = 0
        for ch in col:
            n = n * 26 + ord(ch.upper()) - 64
        return n

    def num_to_col(n: int) -> str:
        s = \"\"
        while n:
            n, r = divmod(n - 1, 26)
            s = chr(65 + r) + s
        return s

    def recover_partial_xlsx(z01_path: Path, partial_path: Path) -> tuple[str, int, int, int]:
        data = z01_path.read_bytes()
        header_offset = data.find(b\"PK\x03\x04\")
        if header_offset < 0:
            raise ValueError(\"PK local file header was not found\")

    header = struct.unpack_from(\"<IHHHHHIIIHH\", data, header_offset)
        sig, _ver, _flag, method, _mtime, _mdate, _crc, comp_size, uncomp_size, name_len, extra_len = header
        if sig != 0x04034B50:
            raise ValueError(\"invalid ZIP local file header\")
        if method != 8:
            raise ValueError(f\"unsupported compression method: {method}\")

    name_bytes = data[header_offset + 30 : header_offset + 30 + name_len]
        try:
            inner_name = name_bytes.decode(\"gbk\")
        except UnicodeDecodeError:
            inner_name = name_bytes.decode(\"utf-8\", errors=\"replace\")

    body_start = header_offset + 30 + name_len + extra_len
        compressed = data[body_start:]

    decompressor = zlib.decompressobj(-15)
        partial = decompressor.decompress(compressed)
        partial += decompressor.flush()
        partial_path.write_bytes(partial)

    return inner_name, comp_size, len(compressed), uncomp_size

    def extract_local_zip_files(zip_fragment: Path) -> dict[str, bytes]:
        data = zip_fragment.read_bytes()
        files: dict[str, bytes] = {}
        offset = 0
        while True:
            pos = data.find(b\"PK\x03\x04\", offset)
            if pos < 0 or pos + 30 > len(data):
                break

    sig, _ver, _flag, method, _mtime, _mdate, _crc, comp_size, _uncomp_size, name_len, extra_len = struct.unpack_from(
                \"<IHHHHHIIIHH\", data, pos
            )
            if sig != 0x04034B50:
                offset = pos + 4
                continue

    name_start = pos + 30
            name = data[name_start : name_start + name_len].decode(\"utf-8\", errors=\"replace\")
            body_start = name_start + name_len + extra_len
            body = data[body_start : body_start + comp_size]

    try:
                if method == 0:
                    content = body
                elif method == 8:
                    content = zlib.decompress(body, -15)
                else:
                    offset = pos + 4
                    continue
            except zlib.error:
                offset = pos + 4
                continue

    files[name] = content
            offset = pos + 4

    return files

    def parse_rows(files: dict[str, bytes]) -> list[list[str]]:
        shared_xml = files[\"xl/sharedStrings.xml\"]
        sheet_xml = files[\"xl/worksheets/sheet1.xml\"]

    ns = {\"m\": \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"}
        shared_root = ET.fromstring(shared_xml)
        shared: list[str] = []
        for si in shared_root.findall(\"m:si\", ns):
            parts = []
            for t in si.findall(\".//m:t\", ns):
                parts.append(t.text or \"\")
            shared.append(\"\".join(parts))

    sheet_root = ET.fromstring(sheet_xml)
        values: dict[tuple[int, int], str] = {}
        max_row = 0
        max_col = 0

    for cell in sheet_root.findall(\".//m:c\", ns):
            ref = cell.attrib.get(\"r\", \"\")
            match = re.match(r\"([A-Z]+)([0-9]+)\", ref)
            if not match:
                continue
            col = col_to_num(match.group(1))
            row = int(match.group(2))
            value_node = cell.find(\"m:v\", ns)
            value = value_node.text if value_node is not None and value_node.text is not None else \"\"
            if cell.attrib.get(\"t\") == \"s\" and value:
                value = shared[int(value)]
            values[(row, col)] = value
            max_row = max(max_row, row)
            max_col = max(max_col, col)

    return [[values.get((r, c), \"\") for c in range(1, max_col + 1)] for r in range(1, max_row + 1)]

    def write_xlsx(rows: list[list[str]], output_path: Path) -> None:
        max_cols = max(len(row) for row in rows)
        sheet_rows = []
        for r_idx, row in enumerate(rows, 1):
            cells = []
            for c_idx in range(1, max_cols + 1):
                value = row[c_idx - 1] if c_idx <= len(row) else \"\"
                ref = f\"{num_to_col(c_idx)}{r_idx}\"
                cells.append(f'{escape(value)}')
            sheet_rows.append(f'{\"\".join(cells)}')

    dimension = f\"A1:{num_to_col(max_cols)}{len(rows)}\"
        sheet_xml = f\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

     
     
     
     
      {\"\".join(sheet_rows)}
    \"\"\"

    content_types = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

     
     
     
     
     
     
    \"\"\"

    rels = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

     
     
     
    \"\"\"

    workbook_xml = f\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

     
    \"\"\"

    workbook_rels = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

     
    \"\"\"

    now = datetime.now(UTC).replace(microsecond=0).isoformat().replace(\"+00:00\", \"Z\")
        core_xml = f\"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

      recovered
      recovered
      {now}
      {now}
    \"\"\"

    app_xml = \"\"\"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>

      Recovered XLSX
    \"\"\"

    with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as archive:
            archive.writestr(\"[Content_Types].xml\", content_types)
            archive.writestr(\"_rels/.rels\", rels)
            archive.writestr(\"xl/workbook.xml\", workbook_xml)
            archive.writestr(\"xl/_rels/workbook.xml.rels\", workbook_rels)
            archive.writestr(\"xl/worksheets/sheet1.xml\", sheet_xml)
            archive.writestr(\"docProps/core.xml\", core_xml)
            archive.writestr(\"docProps/app.xml\", app_xml)

    def main() -> None:
        z01_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(\"focus.z01\")
        output_path = Path(sys.argv[2]) if len(sys.argv) > 2 else Path(DEFAULT_OUTPUT)
        partial_path = output_path.with_name(\"focus_partial.xlsx\")

    inner_name, claimed_size, actual_size, claimed_uncomp = recover_partial_xlsx(z01_path, partial_path)
        files = extract_local_zip_files(partial_path)
        rows = parse_rows(files)
        write_xlsx(rows, output_path)

    print(f\"input={z01_path}\")
        print(f\"inner_file={inner_name}\")
        print(f\"claimed_compressed_size={claimed_size}\")
        print(f\"actual_available_compressed_size={actual_size}\")
        print(f\"claimed_uncompressed_size={claimed_uncomp}\")
        print(f\"partial_xlsx={partial_path}\")
        print(f\"output_xlsx={output_path}\")
        print(f\"rows_including_header={len(rows)}\")
        print(f\"people_count={len(rows) - 1}\")

    if name == \"main\":
        main()
    ```

    感谢吴少指点,重点客户.zip在电脑回收站

将重点客户.zip与重点客户.z01放在同一个目录下,最后解压得到


    2026獬豸杯wp-手机部分" 网络安全文章

    2026獬豸杯wp-手机部分"

    本文档为2026年獬豸杯CTF手机取证题目解答,详细记录了对一加Ace5至尊版手机(序列号AM69VKKVU4CMGELB)的取证分析过程。核心发现包括:通过内核日志获取设备信息、恢复已删除联系人号码\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*、使用steghide工具破解图片隐写密码JHTJ@202605、分析聊天记录发现嫌疑人通过银行卡交易购买100条公民信息。文档提供了完整的取证技术路径,包括数据库解析、文件哈希计算和分卷压缩包恢复等
    WSL十大常见问题排查手册(附解决方案)" 网络安全文章

    WSL十大常见问题排查手册(附解决方案)"

    本文系统总结了WSL使用中最高频的十类问题及排查方案。核心结论在于多数故障可通过重启服务、更新版本或修改wsl.conf与.wslconfig配置文件解决。关键发现包括跨文件系统操作是导致Git变慢的根因,应将项目移至Linux原生目录;Vmmem内存飙升需通过.wslconfig限制资源;网络与端口问题推荐使用mirrored模式。建议用户遵循重启、查版本、看日志、搜Issue的四步法排查,遇到复杂故障时可导出备份后执行彻底重装。
    ActiveDirectory安全攻防(一)" 网络安全文章

    ActiveDirectory安全攻防(一)"

    本文系统介绍ActiveDirectory基础架构与安全风险,阐述AD作为企业核心身份认证服务的核心功能及LDAP协议基础。重点解析域控制器NTDS.DIT数据库的存储机制与攻击面,包括密码哈希存储位置、文件保护措施及攻击者常用提取手法。强调AD因集中化凭据管理和信任关系成为攻击首要目标,并概述从初始入侵到完全控制AD的典型攻击路径,提出需通过系统性工程构建防御体系。
    仅用两小时,我写了一个智能IoT固件安全Agent" 网络安全文章

    仅用两小时,我写了一个智能IoT固件安全Agent"

    本文介绍作者开发的一款智能IoT固件安全Agent,该工具能自主完成固件解包、文件系统分析、Qemu模拟环境搭建、漏洞扫描及PoC生成。通过分析iptimeax8004m路由器固件案例,展示了Agent在无需人工干预下发现并验证高危命令注入漏洞的能力,显著提升了IoT安全研究效率。
    评论:0   参与:  0