HGAME 2024 WEEK1

1.SignIn

下载附件得到一张图片 网上搜图看见许多类似的,其中有一张有注释 将图片传到手机上从充电口看即可得到flag hgame{WOW_GREAT_YOU_SEE_IT_WONDERFUL}


2.来自星尘的问候

一个即将发售的游戏的主角薇^3带来了一条消息。这段消息隐藏在加密的图片里 但即使解开了图片的六位弱加密,看到的也是一张迷惑的图片。 也许游戏的官网上有这种文字的记录? 补充:flag格式为hgame\{[a-z0-9_]+\}

下载附件得到 secret.jpg 不认识但是可爱捏 网上搜图搜到这样的内容 直接搜索下面的文字内容 即将发售的游戏为 来自星尘 图片有6位弱加密,猜测为123456

steghide extract -sf secret.jpg -p 123456

得到secret.zip exa.png内容: 经过一番搜索才知道这是 异星文字(? 又经过一番搜索,最终在B站找到较为完整的文字解读 根据flag格式和一点推测(有两个异星文字没找到对应字母,c和0) hgame{welc0me!}


3.simple_attack

怎么解开这个压缩包呢?

下载附件压缩包 src.zip src.zip未加密 attchment.zip已加密 二者共含文件103223799_p0.jpg 基本确定为 明文攻击 ARCHPR 工具解得密钥 保存解开的压缩包并打开 photo.txt中含有DATA URL,浏览器url输入打开即可


4.希儿希儿希尔

Ch405是一名忠实的希儿厨,于是他出了一道这样的题,不过他似乎忘了这个加密的名字不是希儿了(x虽然经常有人叫错 补充: 图片打不开是正常现象,需要修复 最终得到的大写字母请用hgame{}包裹

下载得到secret.png,要进行图片修复,拉到winhex中查看 PNG文件头没问题,可能是宽高被修改过 进行CRC校验来判断 计算CRC校验码之前,需要了解相关内容: 头部数据块长度文件头数据块标识(IDCH), 13位数据块(IDHR) 剩余四字节为该png的CRC检验码 12 1B 80 4D 与我们计算的CRC校验码进行比较 显然不同 用python脚本修复: 得到正确宽高: 宽:00 00 05 72 高:00 00 07 cf 得到修复图片: 好看捏 既然是希尔加密,应该有密钥和密文 经过一些尝试,发现LSB隐写文件分离 stegsolve解决LSB隐写问题: binwalk或foremost解决文件分离问题: binwalk -e 图片名.png foremost 图片名.png 密文:CVOCRJGMKLDJGBQIUIVXHEYLPNWR 在线工具解希尔密码: 根据格式提交flag hgame{DISAPPEARINTHESEAOFBUTTERFLY}


5.签到

hgame{welc0me_t0_HGAME2024}


HGAME 2024 WEEK2

1.ek1ng_want_girlfriend

An introducation to Wireshark and also ek1ng. 提示1 尝试用Wireshark从HTTP流量中提取文件

流量分析,追踪http协议

截获上传的jpg图片内容

导出分组字节流,添加后缀为.jpg,flag在jpg图片底部


2.ezWord

通过破译图片的水印来解开文档里的秘密吧

压缩包解压缩获得 这是一个word文档.docx

打开就一张图片,根据题目描述和stegsolve下查看的结果,猜测是盲水印

既然是盲水印,可能要有原图和水印图才能解出水印内容

经过一些尝试,将.docx拖入winhex查看,发现藏了点东西,于是binwalk分离文件

在/word/media中发现关键信息

获取原图和水印图,进行盲水印的解 使用github上解盲水印的脚本

origin1.jpg和encode1.png是我改的文件名,得到flag.png,查看水印内容

T1hi3sI4sKey用来解secret.zip这个加密压缩包,得到secret.txt 一段垃圾邮件

ROT8000 解一下出flag


3.龙之舞

新年快要到了,来看看龙年的龙之舞吧(~ ̄▽ ̄)~请注意,拿到正确的二维码后解码就是flag 但是一开始未必正确

deepsound_of_dragon_dance.wav根据音频文件名猜测进行过deepsound隐写

先听了一遍,开头有点异常,关注开头内容,Audacity分析音频内容

频谱图中:

鉴定为反了:

得到KEY也验证了deepsound隐写的想法

解出个XXX.zip,里面一个龙之舞.gif

先看了一遍,右下角有二维码碎片,逐帧分析即可,写个脚本提取每帧图片

#coding=utf-8
from PIL import Image
import os

GIF_name = "dragon.gif"
GIF = Image.open(GIF_name)
GIF_dir = GIF_name[:-4] + "_BreakDown"  #[:-4]返回从开头到倒数第五个字符的内容

if not os.path.exists(GIF_dir):
    os.mkdir(GIF_dir)

try:
    while True:
        GIF_current = GIF.tell()  #开始为0帧 tell()返回当前帧数
        GIF.save(GIF_dir + "\\" + str(GIF_current) + ".png")  #python中两\\表示一\
        GIF.seek(GIF_current + 1)
except EOFError:  #EOFError是Python中的一个异常类型,表示在读取输入时已经到达了文件的末尾
    pass  #pass是空语句,用于保持结构的完整性,不做任何事

WPS拼一拼二维码碎片,合成一个大二维码,发现扫不出来

考虑到每个碎片有两边都是半个方块那么大,应该是两两捆绑的,不存在旋转拼接

正好前两天在复现NCTF 2022 MISC时也有二维码相关内容

当时就在下面网站里学了不少有关二维码的知识

https://www.wzhecnu.cn/2022/03/22/programming/gsoc/qr-code-01/

经过一些尝试,发现是二维码 格式信息 不正确(纠错等级和掩码模式)

多次尝试,原本的二维码格式信息应该是 L4,扫描得到flag

解题过程中,找到另一种二维码无法扫描类型的题目

第七届“湖湘杯” wear_a_mask

右图为mask pattern为2时进行的XOR变换

之后我又翻看了去年HGAME 2023 WEEK2 MISC的官方WP,正好对应上面两题

这一题的二维码的收获很多


HGAME 2024 WEEK3

1.简单的vmdk取证

先找到密码吧 flag 格式:hgame{nthash_password} 例如hgame{05D0AB2BB13711B31D5E251C128C889E_happy} 附件下载: 链接:https://pan.baidu.com/s/1IYeZ1oRjo2zO-Wf6mB2TVA 提取码:vics

.vmdk——虚拟机-虚拟磁盘文件,记录操作系统中所产生的全部数据

先在VMware中挂载试试,发现需要Administrator的密码

磁盘取证:打开 DiskGenius –> 磁盘 –> 打开虚拟磁盘文件

我们要找的是用户密码,一般储存在 WINDOWS\system32\config\SAM

将config目录下 SAMsystem 复制到指定文件夹

mimikatz 获取用户密码hash (注意要将SAM和system复制到mimikatz目录下)

在SAM和system文件后加上后缀 .hiv,即可使用mimikatz

.hiv扩展名:当你使用.hiv扩展名时,Mimikatz会将文件视为注册表文件备份,并使用特定的解析逻辑来读取其中的数据。这意味着在提取和查看密码哈希值时,你需要提供对应的SAM文件和系统文件的备份。

Mimikatz对应命令:lsadump::sam /sam:SAM.hiv /system:system.hiv

获得Administrator的Hash NTLM,在线工具爆一爆(注意提交flag时需要大写字母)


2.简单的取证,不过前十个有红包

找到veracrypt的文件,拿到flag吧 补充附件: 链接:https://pan.baidu.com/s/19pj-juLLE4BY0lVxFyO4iQ 提取码:ccyk

附件内容为 vera.hc

.hc 后缀通常与 VeraCrypt 加密软件相关联。VeraCrypt 是一个开源的磁盘加密工具,用于创建和管理加密的容器文件或整个磁盘分区。

当您使用 VeraCrypt 创建加密容器时,它会为容器文件分配一个特定的扩展名,通常是 .hc(即 VeraCrypt Hidden Container 的缩写)。

通过 VeraCrypt 软件,您可以挂载 .hc 容器文件作为一个虚拟磁盘,然后将其视为普通磁盘分区或存储设备。在挂载后,您可以通过输入正确的密码来解密和访问容器中的文件和文件夹。

于是现在就要获取加密密码,碰巧上一题磁盘中的目录RECYCLER

发现有一张jpg图片,上面还写着veracrypt_password,应该就是加密密码

968fJD17UBzZG6e3yjF6 ,打开veracrypt挂载并输入密码,可以得到原磁盘内容

在veracrypt中:选择文件 –> 选个盘符(我选了A) –> 加载 –> 输入密码 –> 确定


3.与ai聊天

跟他聊一聊吧,从他嘴里翘出flaghttps://udify.app/chat/oRajccxObXREMLlO 注意请不要过快提问

发现会反着说,想到hgame能不能反着说完,这样就可以得到flag


4.Blind SQL Injection

Blind SQL Injection but in Misc

附件是一段流量包,判断为流量分析SQL盲注,用wireshark分析

根据SQL盲注特性,过滤出http协议内容,再根据网页回显内容不同,获取所需

举流量里SQL盲注中一句为例

http://3c97f319-92cf-4ba5-a3f2-6bd644abe921.node5.buuoj.cn:81/search.php?id=1-(ascii(substr((Select(reverse(group_concat(password)))From(F1naI1y)),6,1))>31)

需要注意reverse将获取的password倒置了,写脚本时要再倒置一次

判断 F1naI1y表字段password 倒置后的第6个字符对应ASCII码是否大于31

经过多次判断查回显,最后可以获得一个 >x&&<=x+1 的范围,ASCII码即为x+1

这是当时做题时的分析,也包括了password对应ASCII码的内容(倒置的)

写个简单脚本,得到flag

c = [125,102,50,102,97,56,50,57,53,99,56,51,100,45,54,99,97,98,45,56,57,101,52,45,53,50,55,49,45,55,101,102,97,98,97,98,99,123,103,97,108,102,44][::-1]
flag = ''
for i in c:
    flag += chr(i)
print (flag)

运行结果:


HGAME 2024 WEEK4

1.ezKeyboard

本来是个签到题,但有时候往往事与愿违

  1. 流量不需要修复,出题人拿自己电脑现抓的一段流量,他本身就是这样的。
  2. 本题键盘流量的 HID Data 格式和常见的格式略有不同,但本质如一。
  3. 你需要辩证看待这些个脚本网络上的脚本。他们大多出自一家,没几十行的核心代码里,都毫不例外地保留了数个编程初学者常犯的致命失误。
  4. 相信自己的水平,从头写一个脚本往往比找别人的错误容易。

使用wireshark进行USB流量分析,把一些特殊的流量导出

我导出了可能有用的三段,但是有一段不会用,也可能没什么用(

第一段内容:

感觉开头的01没什么用,提取一下敲击内容:

normalkeys = {"04":"a", "05":"b", "06":"c", "07":"d", "08":"e", "09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j", "0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o", "13":"p", "14":"q", "15":"r", "16":"s", "17":"t", "18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y", "1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4", "22":"5", "23":"6","24":"7","25":"8","26":"9","27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\","32":"<NON>","33":";","34":"'","35":"`","36":",","37":".","38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
shiftkeys = {"04":"A", "05":"B", "06":"C", "07":"D", "08":"E", "09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J", "0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O", "13":"P", "14":"Q", "15":"R", "16":"S", "17":"T", "18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y", "1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$", "22":"%", "23":"^","24":"&","25":"*","26":"(","27":")","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>","2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"","34":":","35":"~","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
with open('hgame2.txt') as data:
    for line in data:
        information1=line[6:8]
        information2=line[8:10]
        if information1=='00':
            continue
        if line[3]=='2': #shiftkey
            print (shiftkeys[information1],end='') #end=''以空字符替换原默认换行符
            if information2!='00':
                print (shiftkeys[information2],end='')
        if line[3]=='0': #normalkey
            print (normalkeys[information1],end='')
            if information2!='00':
                print (normalkeys[information2],end='')

运行结果:

hgame{k_<DEL>e<CAP><CAP>y<CAP><CAP>b0a1d<CAP><CAP><CAP>_<CAP><CAP>gam0<CAP><CAP><CAP>_<CAP><CAP>_<CAP><CAP>15<CAP><CAP><CAP>_<CAP><CAP>s0<CAP><CAP><CAP>_<CAP><CAP><CAP>1nst<DEL><DEL><DEL><DEL>f0n__!!~~<CAP>~~<CAP>}

整理一下:

但是提交发现flag不对,感觉怪怪的

赛后看了官方wp找到问题了,这里也贴出能得到正确flag的脚本:

normalKeys = {"04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09":
"f", "0a": "g", "0b": "h", "0c": "i",
"0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12":
"o", "13": "p", "14": "q", "15": "r",
"16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b":
"x", "1c": "y", "1d": "z", "1e": "1",
"1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24":
"7", "25": "8", "26": "9", "27": "0",
"28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "-", "2e": "=", "2f": "[",
"30": "]", "31": "\\", "32": "<NON>", "33": ";", "34": "'",
"35": "<GA>", "36": ",", "37": ".", "38": "/",
"39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
"40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
shiftKeys = {"04": "A", "05": "B", "06": "C", "07": "D", "08": "E", "09": "F",
"0a": "G", "0b": "H", "0c": "I",
"0d": "J", "0e": "K", "0f": "L", "10": "M", "11": "N", "12": "O",
"13": "P", "14": "Q", "15": "R",
"16": "S", "17": "T", "18": "U", "19": "V", "1a": "W", "1b": "X",
"1c": "Y", "1d": "Z", "1e": "!",
"1f": "@", "20": "#", "21": "$", "22": "%", "23": "^", "24": "&",
"25": "*", "26": "(", "27": ")",
"28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "\t", "2c": "<SPACE>", "2d": "_", "2e": "+", "2f": "{",
"30": "}", "31": "|", "32": "<NON>", "33": "\"", "34": ":", "35":
"~", "36": "<", "37": ">", "38": "?",
"39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>",
"40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
output = []
last = []
new = []
keys = open('hgame2.txt')
press = ''
for line in keys:
    try:
        if line[2]!='0' or (line[3]!='0' and line[3]!='2'):
            continue
        offset = 6
        new = []
        while line[offset:offset+2] != '00':
            press = line[offset:offset+2]
            if press in normalKeys.keys():
                if line[3]=='0':
                    key = normalKeys[press]
                else:
                    key = shiftKeys[press]
            else:
                key = '[unknown]'
            if press not in last:
                output.append(key)
            new.append(press)
            offset += 2
    except:
        print(line)
    finally:
        last = new

keys.close()
flag=0

for i in range(len(output)):
    try:
        if output[i]=="<CAP>":
            flag = 1-flag
        if flag!=0:
            output[i]=output[i].upper()
    except:
        pass
output = [x for x in output if x != '<CAP>']

new_output = []

for i in range(len(output)):
    if output[i] == "<DEL>":
        new_output = new_output[:-1]
    else:
        new_output.append(output[i])

print ("".join(new_output))

运行结果:hgame{keYb0a1d_gam0__15_s0_f0n__!!~~~~}


2.maybezip

根据题目名,结合文件并非zip,想到需要对文件内容异或得到原zip文件 根据zip文件的固定文件头,504B0304,找到异或数字 0x27,可以直接在winhex里异或,也能写脚本

def xor_with_0x27(input_file, output_file):
    with open(input_file, 'rb') as f:
        data = f.read()
    xor_data = bytearray([b ^ 0x27 for b in data])
    with open(output_file, 'wb') as f:
        f.write(xor_data)

# 使用xor函数
xor_with_0x27('maybezip', 'output.zip')

output.zip里文件修改日期有明显的01特征,提取出来

import zipfile
import json
from datetime import datetime

def get_all_file_modification_time(zip_path):
    result = {}
    with zipfile.ZipFile(zip_path, 'r') as myzip:
        for file in myzip.namelist():
            info = myzip.getinfo(file)
            mod_time = datetime(*info.date_time)
            result[file] = str(mod_time)
    return result

# 使用函数并保存结果为json
result = get_all_file_modification_time('output.zip')
with open('output.json', 'w') as f:
    json.dump(result, f)

再对拿到的json数据操作一下

import json

# 读取json文件
with open('output.json', 'r') as f:
    data = json.load(f)
string_of_01 =''
# 遍历json数据
for file, time in data.items():
    # 检查文件名是否在指定范围内
    if 'out/' in file and 'png' in file:
        file_number = int(file.split('/')[1].split('.')[0])
        if file_number >= 1 and file_number <= 118:
            # 检查时间的最后一位是否为0
            if time[-1] == '0':
                print(f"{file_number} - 0")
                string_of_01 += '0'
            else:
                print(f"{file_number} - 1")
                string_of_01 += '1'

print(string_of_01)

# 二进制转ascii字符串

def binary_to_string(binary):
    result = ''
    for i in range(0, len(binary), 8):
        byte = binary[i:i+8]
        result += chr(int(byte,2))  #从二进制转为十进制
    # 忽略不可见字符
    result = ''.join([i if ord(i) > 31 and ord(i) < 127 else '' for i in result])
    return result

key_of_zip = binary_to_string(string_of_01)
print(key_of_zip)

得到压缩包密码 what_is_tupper 解压缩得到一段数字,结合压缩包密码的tupper,想到tupper自指,在线工具画一下图

这是micro qrcode,找个工具扫一下,可以用Scanbot SDK 扫描内容为:Matryo5hk4_d01l