Week 1

其实就只打了week1的misc(

Misc

打好基础

Challenge

😛 ENJOY HGAME!

text
🐲👝🐱👁👠👮👌👞👂🐬🐽🐡👎👮🐪🐿🐾👞🐨👕🐫👤👏👟👍👉🐲👑👍👀👔👭🐩👮🐾👏🐮👑🐨🐩🐠👯👡🐮👍🐨👒🐘🐨🐮👔👍🐸🐥🐡👇🐶👝👏👱🐺👀👌🐢🐦🐦👟👂👮👝🐡🐳🐰👒👄👡🐶👤👀👴🐯🐭🐛👱👎👫🐭🐢🐫👨👭👬👌👲👧🐘🐮👊👕👊👦🐥👎👈👟🐴👈🐭🐶👭🐥🐡🐽👓🐨👝👛🐡👕🐫🐡🐽👯👱👌👁👡🐫🐲🐡🐲🐟🐶👪🐭👳👌👖👲👡👈👯🐘👇🐫🐡👈🐰👕👡🐩👎👁🐳👒👡👣👨👞👞🐫👠👈🐽🐲👤🐩👎👂🐤👟🐬👤🐴👣👛👃👳🐽🐢👃👀🐨👧🐠👎🐹👓👢🐼🐳👁🐱👚🐳👭🐨👔👍🐠👥🐸🐱🐣🐸👖🐰👓🐬👄🐳👱👐👉🐢👝🐠🐤👯👀👎👥🐤👔🐨👊👊👃🐽👱🐪👱👚👍🐵🐶👎🐻👛🐤👂🐳🐾🐟🐨👢👍👥🐼👟👕👙👣🐡👣👭🐿👦🐩👂👬🐞🐢👋🐠👙🐶🐤👥👋🐲👱🐩👕🐝🐺🐯👴👍🐡🐦🐰👍🐨👋👔👤🐚🐻👐🐽👟🐴🐷👎🐴👫👀👤🐦👡🐥👡🐵🐸🐺👫👛👮👲🐬👯👌👔👙👉🐷🐺👁👅🐪👒👈👕👅🐯🐩🐝👰👚👌👂🐵🐽

Solution

Base100 -> Base92 -> Base91 -> Ascii85 -> Base64 -> Base62 -> Base58 -> Base45 -> Base32

FLAG

text
hgame{L4y_a_sO11d_f0unDaTi0n}

shiori不想找女友

Challenge

Tremse正在帮Shiori找女友,但是他现在找不到Shiori了!但是他留下了他的头像,你可以帮我找找他在哪里吗🙏

Solution

查看 exif 发现 User Comment 藏有信息

json
{"block": 1, "start_x": 10, "start_y": 10, "step_x": 7, "step_y": 7, "column_num": 450}

放大图片发现图片有整齐排列的点,猜测上面的提示是指从 shiori.png(10, 10) 坐标开始,以 x 方向步长 7、y 方向步长 7 的间隔拾取像素,共 450 列,编写脚本提取像素组成新的图片

python
from PIL import Imageimport math def extract_pixels(input_file, output_file, rules):    try:        # 打开源图像        src_img = Image.open(input_file)        src_img = src_img.convert("RGB") # 确保是RGB模式        width, height = src_img.size                # 获取规则参数        block = rules.get("block", 1)        start_x = rules.get("start_x", 0)        start_y = rules.get("start_y", 0)        step_x = rules.get("step_x", 1)        step_y = rules.get("step_y", 1)        out_cols = rules.get("column_num", 100)                extracted_pixels = []         # 遍历源图像提取像素        # 假设按行优先顺序扫描 (先X后Y)        # 注意:这里采用了两层循环遍历整个图,按照步长提取        for y in range(start_y, height, step_y):            for x in range(start_x, width, step_x):                # 检查边界                if x + block <= width and y + block <= height:                    # 获取像素 (这里处理 block=1 的情况,直接取点)                    # 如果 block > 1,通常需要决定如何处理块(取平均值或左上角),这里默认取左上角像素                    pixel = src_img.getpixel((x, y))                    extracted_pixels.append(pixel)         # 计算输出图像的高度        total_pixels = len(extracted_pixels)        if total_pixels == 0:            print("未提取到任何像素,请检查规则和图像尺寸。")            return         out_rows = math.ceil(total_pixels / out_cols)                # 创建新的空白图像        out_img = Image.new("RGB", (out_cols, out_rows), (0, 0, 0))                # 填充像素        for i, pixel in enumerate(extracted_pixels):            x = i % out_cols            y = i // out_cols            out_img.putpixel((x, y), pixel)                    # 保存输出图像        out_img.save(output_file)        print(f"成功提取 {total_pixels} 个像素,已保存至 {output_file}")        print(f"输出尺寸: {out_cols} x {out_rows}")     except FileNotFoundError:        print(f"错误: 找不到文件 {input_file}")    except Exception as e:        print(f"发生错误: {e}") # 定义规则params = {    "block": 1,    "start_x": 10,    "start_y": 10,    "step_x": 7,    "step_y": 7,    "column_num": 450} # 运行提取if __name__ == "__main__":    extract_pixels("shiori.png", "output.png", params)

得到提示 This_is_a_key_for_u,这是压缩包的密码

解压后的图片存在 LSB 隐写,在 StegSolve 找一个比较好看出来的 Plane (比如 Green Plane 0)识图转文字即可

FLAG

text
hgame{bec0use_lilies_are_7he_b1st}

[REDACTED]

Challenge

兔兔说她对一份机密文件进行了“完美的”脱敏处理。还好你在发送之前检查了一下。

提交说明: 附件中包含四段敏感字符串,格式为 [1-4]:.+。用下划线字符 _ 连接去掉序号的四段字符串,包裹 hgame{} 后提交。例如,若四段敏感字符串分别为 1:Example2:Redacted3:Secret4:Strings_!,则提交的 flag 为 hgame{Example_Redacted_Secret_Strings_!}

Solution

1:PAR4D0X

HGAME2026-1

2:AllCl3arToPr0ceed

HGAME2026-2

HGAME2026-3

3:Sh4m1R

HGAME2026-4

至此浮于表面的答案都找到了,还没仔细研究过这个 PDF 文件本身

先使用 pdfid 初步扫描文件

bash
┌──(kali㉿kali)-[~/Desktop]└─$ pdfid manual.pdfPDFiD 0.2.10 manual.pdf PDF Header: %PDF-1.7 obj                  110 endobj               110 stream                23 endstream             23 xref                   2 trailer                2 startxref              2 /Page                  3          <---------- /Encrypt               0 /ObjStm                0 /JS                    0 /JavaScript            0 /AA                    0 /OpenAction            0 /AcroForm              0 /JBIG2Decode           0 /RichMedia             0 /Launch                0 /EmbeddedFile          0 /XFA                   0 /Colors > 2^24         0

PDF 就只有 2 页,但 pdfid 扫出来 3 页,这咋看都不对劲,可能是通过修改 PDF 目录结构隐藏了一页

用 pdf-parser 进一步分析

bash
┌──(kali㉿kali)-[~/Desktop]└─$ pdf-parser manual.pdfThis program has not been tested with this version of Python (3.13.3)Should you encounter problems, please use Python version 3.12.2PDF Comment '%PDF-1.7\n' PDF Comment '%\xc2\xb5\xc2\xb6\n\n' obj 1 0 Type: /Page Referencing: 59 0 R, 101 0 R, 2 0 R   <<    /Type /Page    /Parent 59 0 R    /Resources 101 0 R    /MediaBox [0 0 521.2913 737.2913]    /Tabs /S    /StructParents 0    /Contents 2 0 R  >> ... obj 59 0 Type: /Pages Referencing: 101 0 R, 1 0 R, 7 0 R, 34 0 R   <<    /Type /Pages    /Resources 101 0 R    /Kids [1 0 R 7 0 R 34 0 R]    /Count 3  >> ... obj 59 0 Type: /Pages Referencing: 101 0 R, 7 0 R, 34 0 R   <<    /Type /Pages    /Resources 101 0 R    /Kids [7 0 R 34 0 R]    /Count 2  >> ...

通过检查输出中的页树根节点(/Pages,即 Object 59),发现了文件被篡改的痕迹:

  1. 原始定义(Object 1, 7, 34):

    text
    obj 59 0Type: /PagesKids [1 0 R 7 0 R 34 0 R]          <----------Count 3
  2. 增量更新(Object 7, 34):

    text
    obj 59 0Type: /PagesKids [7 0 R 34 0 R]          <----------Count 2

Object 1 就是被隐藏的第一页,定位到隐藏页 Object 1

text
obj 1 0 Type: /Page Referencing: 59 0 R, 101 0 R, 2 0 R  <<    /Type /Page    /Parent 59 0 R    /Resources 101 0 R    /MediaBox [0 0 521.2913 737.2913]    /Tabs /S    /StructParents 0    /Contents 2 0 R          <----------  >>

它指向 Object 2 作为其内容流,提取并解压 Object 2 的数据:

bash
┌──(kali㉿kali)-[~/Desktop]└─$ pdf-parser -o 2 -f manual.pdfThis program has not been tested with this version of Python (3.13.3)Should you encounter problems, please use Python version 3.12.2obj 2 0 Type:  Referencing:  Contains stream   <<    /Length 145    /Filter /FlateDecode  >>  b'0.1 w\n/Artifact BMC\nq 0 0.028 521.263 737.263 re\nW* n\nEMC\n/P<</MCID 0>>BDC\nq 0 0 0 rg\nBT\n200.8 367.841 Td /F1 12 Tf<010203040506070809070A0B070C0D0E090B09>Tj\nET\nQ\nEMC\nQ '
  • -o 2: 指定对象 ID 2
  • -f: 自动处理过滤器

从输出得到了一段 PostScript 绘图指令,其中包含一段可疑的内容:/F1 12 Tf <010203040506070809070A0B070C0D0E090B09> Tj

这里的 <010203040506070809070A0B070C0D0E090B09> 是字体的 Character ID 索引,这段文字使用了自定义的字体映射

现在需要找到字体 F1 的映射表来还原真实文本

text
obj 1 0 Type: /Page Referencing: 59 0 R, 101 0 R, 2 0 R  <<    /Type /Page    /Parent 59 0 R    /Resources 101 0 R          <----------    /MediaBox [0 0 521.2913 737.2913]    /Tabs /S    /StructParents 0    /Contents 2 0 R  >>

先找到 Object 1 资源由 Object 101 定义,接着查看 Object 101 的定义

text
obj 101 0 Type:  Referencing: 100 0 R, 50 0 R  <<    /Font 100 0 R          <----------    /XObject      <<        /Im50 50 0 R      >>    /ProcSet [/PDF/Text/ImageC/ImageI/ImageB]  >>

找到字体映射关系存储在 Object 100 中,接着查看 Object 100 的定义

text
obj 100 0 Type:  Referencing: 64 0 R, 79 0 R, 84 0 R, 89 0 R, 74 0 R, 69 0 R, 94 0 R, 99 0 R  <<    /F1 64 0 R          <----------    /F2 79 0 R    /F3 84 0 R    /F4 89 0 R    /F5 74 0 R    /F6 69 0 R    /F7 94 0 R    /F8 99 0 R  >>

找到 /F1 指向 64 0 R,接着查看 Object 64 的定义:

text
obj 64 0 Type: /Font Referencing: 62 0 R, 63 0 R  <<    /Type /Font    /Subtype /TrueType    /BaseFont /BAAAAA+CMUTypewriter-Light    /FirstChar 0    /LastChar 18    /Widths [0 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525]    /FontDescriptor 62 0 R    /ToUnicode 63 0 R          <----------  >>

这表明 Object 63 存储了从 CID 到 Unicode 的映射表,提取映射表:

bash
┌──(kali㉿kali)-[~/Desktop]└─$ pdf-parser -o 63 -f manual.pdfThis program has not been tested with this version of Python (3.13.3)Should you encounter problems, please use Python version 3.12.2obj 63 0 Type:  Referencing:  Contains stream   <<    /Length 304    /Filter /FlateDecode  >>  b'/CIDInit/ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo<<\n/Registry (Adobe)\n/Ordering (UCS)\n/Supplement 0\n>> def\n/CMapName/Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<00> <FF>\nendcodespacerange\n18 beginbfchar\n<01> <0034>\n<02> <003A>\n<03> <0044>\n<04> <0030>\n<05> <0063>\n<06> <0052>\n<07> <0033>\n<08> <0071>\n<09> <0075>\n<0A> <0073>\n<0B> <0074>\n<0C> <0072>\n<0D> <005F>\n<0E> <0054>\n<0F> <0031>\n<10> <0050>\n<11> <0041>\n<12> <0058>\nendbfchar\nendcmap\nCMapName currentdict /CMap defineresource pop\nend\nend\n'

得到映射表内容 Object 63

text
<01> <0034><02> <003A><03> <0044><04> <0030><05> <0063><06> <0052><07> <0033><08> <0071><09> <0075><0A> <0073><0B> <0074><0C> <0072><0D> <005F><0E> <0054><0F> <0031><10> <0050><11> <0041><12> <0058>

最后将 Object 2 中的十六进制串逐字节对照 Object 63 的映射表进行替换即可得到 4:D0cR3qu3st3r_Tutu

也可以直接用 foremost 提取

HGAME2026-5

最后拼起来即可得到 flag

text
hgame{PAR4D0X_AllCl3arToPr0ceed_Sh4m1R_D0cR3qu3st3r_Tutu}