Hgame_week_1_writeup

WEB

Bypass it

禁用js防止注册时弹窗即可
alt text
随后进行注册登陆即可获得flag
alt text
点击获取flag

1
hgame{e3983cd6c6de1c35e21e592d443965ac6c2eb93c}

ezHTTP

从vidar.club访问这个页面
将请求中的Referer值修改为vidar.club
alt text
请通过Mozilla/5.0 (Vidar; VidarOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36 Edg/121.0.0.0访问此页面
将请求中的User-Agent值修改为上述值
alt text
请从本地访问这个页面
在响应中有Hint:Not xff
尝试过许多姿势,将请求种X-real-ip值修改为127.0.0.1
alt text
可以看到响应中有一串jwt token,解码可得flag

1
hgame{HTTP_!s_1mP0rT4nt}

CRYPTO

奇怪的图片

题目将flag的每个字符按序draw在一张随机生成的图片中,并每张与随机生成的key image进行xor操作,save。但由于time.sleep(),无法确认每张image的生成顺序。
按顺序来说,每张image都会在前一张添加一个字符,而未改变的像素点,两张图片进行xor后仍然相同,那么就随意取一张image与另外所有的image进行比较,将相同的像素点draw在一张白底的image上,剩下的白色部分即draw在上面的字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from PIL import Image, ImageDraw
import os

def list_files_in_directory(directory):
name=[]
files = os.listdir(directory)
for file in files:
file_path = os.path.join(directory, file)
if os.path.isfile(file_path):
name.append(file)
return name

directory_path = "D:/crane/Desktop/attachment (3)/png_out"


def compare_images(image1, image2):
i=0
if image1.size != image2.size:
raise ValueError("Images must have the same dimensions.")

width, height = image1.size
result_image = Image.new("RGB", (width, height), "white")
result_draw = ImageDraw.Draw(result_image)

for x in range(width):
for y in range(height):
pixel1 = image1.getpixel((x, y))
pixel2 = image2.getpixel((x, y))

if pixel1 == pixel2:
i=i+1
result_draw.point((x, y), fill=pixel1)

return result_image,i

name=list_files_in_directory(directory_path)
rank=[]
result=[]
for i in range(len(name)):
image1_path = "D:/crane/Desktop/attachment (3)/png_out/4e8a536e.png"
image2_path = "D:/crane/Desktop/attachment (3)/png_out/"+name[i]
image1 = Image.open(image1_path, 'r')
image2 = Image.open(image2_path, 'r')
result_image,r = compare_images(image1, image2)
rank.append(r)
result.append(result_image)
result_image.save("{}.png".format(i))

for i in range(len(rank)):
index=i
max=rank[i]
for j in range(i+1,len(rank)):
if rank[index]<rank[j]:
max=rank[j]
index=j
if max!=rank[i]:
rank[index]=rank[i]
rank[i]=max
temp=result[i]
result[i]=result[index]
result[index]=temp

for i in range(len(result)):
result[i].save("{}.png".format(i))
print(rank[i])
print(name[i])
print("{}.png".format(i))
print("-------------------------------------------------")

由于是随机选择的image,需要将生成的image进行排序分类,以便分析。
alt text
alt text
一组是在选择的image后添加的字符,一组为image前添加的字符,分析添加的顺序,与flag格式hgame{}可得flag

1
hgame{1adf_17eb_803c}

ezMath

分析代码,采用AES将flag加密,key由以下语句生成

1
2
3
D = 114514
assert x**2 - D * y**2 == 1
key=pad(long_to_bytes(y))[:16]

可以发现这是佩尔方程,用连分数法解出y即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
from collections import deque
from Crypto.Util.number import *
from Crypto.Cipher import AES

d = 114514
m = int(np.sqrt(d))
dq = deque()
dq.append(m)
n0 = n1 = d - m * m
m1 = m
while 1:
q, m2 = divmod(m1 + m, n1)
dq.appendleft(q)
m1 = -m2+m
n1 = (d-m1*m1)//n1
if m1 == m and n1 == n0:
break

dq.popleft()
b = 1
c = 0
for i in dq:
b1 = c + b * i
c = b
b = b1


print(b)
print(c)

def pad(x):
return x+b'\x00'*(16-len(x)%16)

def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted

key=pad(long_to_bytes(c))[:16]
enc=b"\xce\xf1\x94\x84\xe9m\x88\x04\xcb\x9ad\x9e\x08b\xbf\x8b\xd3\r\xe2\x81\x17g\x9c\xd7\x10\x19\x1a\xa6\xc3\x9d\xde\xe7\xe0h\xed/\x00\x95tz)1\\\t8:\xb1,U\xfe\xdec\xf2h\xab`\xe5'\x93\xf8\xde\xb2\x9a\x9a"
print(decrypt(key))

解出flag

1
hgame{G0od!_Yo3_k1ow_C0ntinued_Fra3ti0ns!!!!!!!}

ezRSA

解出p,q即可

1
2
leak1=pow(p,q,n)
leak2=pow(q,p,n)

可以发现leak1*leak2与leak1,leak2的公因数即是p,q

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *

leak1=149127170073611271968182576751290331559018441805725310426095412837589227670757540743929865853650399839102838431507200744724939659463200158012469676979987696419050900842798225665861812331113632892438742724202916416060266581590169063867688299288985734104127632232175657352697898383441323477450658179727728908669
leak2=116122992714670915381309916967490436489020001172880644167179915467021794892927977272080596641785569119134259037522388335198043152206150259103485574558816424740204736215551933482583941959994625356581201054534529395781744338631021423703171146456663432955843598548122593308782245220792018716508538497402576709461
c=10529481867532520034258056773864074017027019578041866245400647840230251661652999709715919620810933437191661180003295923273655675729588558899592524235622728816065501918076120812236580344991140980991532347991252705288633014913479970610056845543523591324177567061948922552275235486615514913932125436543991642607028689762693617305246716492783116813070355512606971626645594961850567586340389705821314842096465631886812281289843132258131809773797777049358789182212570606252509790830994263132020094153646296793522975632191912463919898988349282284972919932761952603379733234575351624039162440021940592552768579639977713099971

p = GCD(leak1*leak2, leak2)
q = GCD(leak1*leak2, leak1)
phi=(p-1)*(q-1)
e=0x10001
d = inverse(e, phi)
n=p*q
m = pow(c, d, n)
plain=long_to_bytes(m)
print(plain)

解出flag

1
hgame{F3rmat_l1tt1e_the0rem_is_th3_bas1s}

ezPRNG

LFSR问题,可以发现生成的output每32位为一周期,将随机生成的uuid的去除‘-’,每8位进行加密。mask只有第1、4、8、11、15、20、25、28、32这几位为1,其余位均为0,反馈函数即每1位上的异或。最后再依次异或解出flag。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mask=0b10001001000010000100010010001001
input=['1111110110111011110000101011010001000111111001111110100101000011110111111100010000111110110111100001001000101101011110111100010010100000011111101101110101011010111000000011110000100011101111011011000100101100110100101110001010001101101110000010001000111100101010010110110111101110011011001011111011010101011000011011000111011011111001101010111100101100110001011010010101110011101001100111000011110111000001101110000001111100000100000101111100010110111001110011010000011011110110011000001101011111111010110011010111010101001000010011110110011110110101011110111010011010010110111111010011101000110101111101111000110011111110010110000100100100101101010101110010101001101010101011110111010011101110000100101111010110101111110001111111110010000000001110011100100001011111110100111011000101001101001110010010001100011000001101000111010010000101101111101011000000101000001110001011001010010001000011000000100010010010010111010011111111011100100100100101111111001110000111110110001111001111100101001001100010', '0010000000001010111100001100011101111101111000100100111010101110010110011001011110101100011101010000001100000110000000011000000110101111111011100100110111011010000100011111000111001000101001110010110010001000110010101011110011101000011111101101011000011110001101011111000110111000011000110011100100101100111100000100100101111001011101110001011011111111011010100010111011000010010101110110100000110100000100010101000010111101001000011000000000111010010101010111101101011111011001000101000100011001100101010110110001010010001010110111011011111101011100111001101111111111010011101111010010011110011111110100110011111110110001000111100010111000101111000011011011111101110101110100111000011100001010110111100011001011010011010111000110101100110100011101101011101000111011000100110110001100110101010110010011011110000111110100111101110000100010000111100010111000010000010001111110110100001000110110100100110110010110111010011111101011110000011101010100110101011110000110101110111011010110110000010000110001', '1110110110010001011100111110111110111001111101010011001111100100001000111001101011010100010111110101110101111010111100101100010011001001011101000101011000110111000010000101001000100111010110001010000111110110111000011001100010001101000010001111111100000101111000100101000000001001001001101110000100111001110001001011010111111010111101101101001110111010111110110011001000010001010100010010110110101011100000101111100100110011110001001001111100101111001111011011010111001001111010001100110001100001100000110000011111010100101111000000101011111010000111110000101111100010000010010111010110100101010101001111100101011100011001001011000101010101001101100010110000010001110011110011100111000110101010111010011010000001100001011000011101101000000011111000101111101011110011000011011000100100110111010011001111101100101100011000101001110101111001000010110010111101110110010101101000000101001011000000001110001110000100000001001111100011010011000000011011101111101001111110001011101100000010001001010011000001', '0001101010101010100001001001100010000101010100001010001000100011101100110001001100001001110000110100010101111010110111001101011011101110000011001000100100101000011011101000111001001010011100010001010110111011100100111110111001010010111010100000100111110101110010010110100001000010010001101111001110100010001011101100111011101011101100100101011010101000101001000101110011011111110110011111111100000000011100000010011000110001000110101010001011000010101000110000101001110101010111011010010111011001010011100010101001100110000110101100010000100110101110100001101001011011110011100110011001010110100101010111110110111100000111010001111101110000000000111011011101000011001010010111001110111000100111011110100101000100011011101100011111000101110110110111111001111000000011100011000010000101001011001101110101000010101001000100110010000101001111100101000001011011010011110001101000001101111010100101001100010100000111000011110101010100011011001110001011110111010111011010101101100000110000001010010101111011']
result=''
for i in range(4):
key1=input[i][0:32]
key2=key1
flag=[]
for i in range(32):
output='?'+key1[:31]
flag.append(str(int(key2[-1-i])^int(output[-1])^int(output[-4])^int(output[-8])^int(output[-11])^int(output[-15])^int(output[-20])^int(output[-25])^int(output[-28])))
key1=str(flag[i])+key1[:31]
result+=hex(int(''.join(flag[::-1]),2)).replace('0x','')
result=list(result)
result.insert(8,'-')
result.insert(13,'-')
result.insert(18,'-')
result.insert(23,'-')
result=''.join(result)
print("hgame{"+result+"}")

注意结果要根据uuid增加“-”。

1
hgame{fbbbee82-3f43-4f91-9337-907880e4191a}

MISC

SignIn

可以发现图片宽度上进行了压缩,将图片拉长即可
alt text
可以看到flag为

1
hgame{WOW_GREAT_YOU_SEE_IT_WONDERFUL}

simple_attack

是个zip加密,给了一张jpg与一个加密zip,查看zip内文件名,发现有与给出的jpg相同名称的文件。那么即是压缩包已知明文攻击,采用ARCHPR工具进行攻击。
初始攻击时,用winrar压缩图片,会报如图错误
alt text
试过了许多压缩方式都不行(,最后询问出题人,用的是bandzip压缩。
攻击完成后压缩包内有photo.txt文件,为图片base64编码,且为url链接,复制到游览器即可打开。
alt text
得到flag

1
hgame{s1mple_attack_for_zip}

Hgame_week_1_writeup
https://cr4ne.asia/2024/02/12/Hgame_week_1/
作者
crane
发布于
2024年2月12日
许可协议