re1_西北望乡
主程序很容易看明白,格式是flag{....}长45,然后把3,6,13,36拿出来作为系数,这些字符每5个一组分别乘系数后的和给定了。然后就是怎么解了。
if ( strlen(flag) == 45 )
{
v21[0] = flag[3];
v21[1] = flag[6];
v21[2] = flag[13];
v21[3] = flag[36];
v21[4] = 13;
for ( i = 0; i < 5; ++i )
{
v19 = 1LL;
for ( j = 0; j < 5 - i; ++j )
v19 *= v21[4 - i];
v9 = (_QWORD *)i;
*((_QWORD *)b + i) = v19;
}
for ( k = 0; k < 9; ++k )
{
v16 = 0LL;
for ( l = 0; l < 5; ++l )
v16 += flag[5 * k + l] * *((_QWORD *)b + l);
v9 = arr;
if ( v16 != arr[k] )
{
v11 = std::operator<<<std::char_traits<char>>(&std::cout, "哎呀,错了呢~~", arr);
std::ostream::operator<<(v11, std::endl<char,std::char_traits<char>>);
return 0;
}
}
v12 = std::operator<<<std::char_traits<char>>(&std::cout, "哎呦,不错呦,去提交下试试吧。", v9);
std::ostream::operator<<(v12, std::endl<char,std::char_traits<char>>);
}
else
{
v14 = std::operator<<<std::char_traits<char>>(&std::cout, "flag长度为49字符。", v9);
v10 = strlen(flag);
std::ostream::operator<<(v14, v10);
}
因为第1组5个flag{已经知道了,可以先爆破出这3个值,然后再解。坑点是它说是小写字母和_但里边出了数字。
from z3 import *
arr = [0x2A6274623, 0x2A1032DAD, 0x27BD29EFD, 0x2D186CDC5, 0x2CB93A140, 0x286EB174E, 0x2CB9611A2, 0x27AE20336, 0x141D07333, 0x0ACEEBB]
#先求系数
i, j, k = Ints("i j k")
s = Solver()
s.add(arr[0] == ord('f')*13**5 + ord('l')*i**4 + ord('a')*j**3 + ord('g')*k**2 + ord('{')*ord('g'))
s.add(And(i>=95, i<=122))
s.add(And(j>=95, j<=122))
s.add(And(k>=95, k<=122))
if s.check():
m= s.model()
b1 = int(f'{m[i]}')**4
b2 = int(f'{m[j]}')**3
b3 = int(f'{m[k]}')**2
b0 = 13**5
b4 = ord('g')
print(b0,b1,b2,b3,b4)
#再爆破
flag = [Int(f'f[{i}]') for i in range(45)]
s=Solver()
#已知部分
for i,v in enumerate(b'flag{'):
s.add(flag[i] == v)
s.add(flag[44] == ord('}'))
for i in range(45):
s.add(And(flag[i]>=0x20, flag[i]<0x7f))
for i in range(9):
data = f"flag[{i*5}]*{b0} + flag[{i*5+1}]*{b1} + flag[{i*5+2}]*{b2} + flag[{i*5+3}]*{b3} + flag[{i*5+4}]*{b4} == {arr[i]}"
print(data)
s.add(eval(data))
if s.check() == sat:
m = s.model()
print(m)
for i in range(45):
print(chr(int("%s" % (m[flag[i]]))), end='')
#flag{okok_here_is_your_flag_where_are_my_36d}
re2_归心
提示是说用啥打的包,用ida打开看是java的应该是jar文件,搜了下是exe4j运行一下,在临时目录里找到释放出来的jar文件,打开就看到flag
C:\Users\XXXXXXXX\AppData\Local\Temp\e4jCA19.tmp_dir1650439000\readme.jar
flag{You_Win_0nce_You_C_Me}
re3_若无月
有提示是RC4,先把一个序列作64轮轮换,然后每再按序号每轮换一次与明文作异或。如果提前生成足够多的码表,然后依次与密文异或就能得到明文。
windows程序里,事件1进行初始化密钥
case 1u:
w = GetSystemMetrics(0);
cy = GetSystemMetrics(1);
SetTimer(hWnd, 1u, 0xAu, 0);
v8 = FindResourceA(0, (LPCSTR)0x78, (LPCSTR)8);
v9 = SizeofResource(0, v8);
v10 = LoadResource(0, v8);
v11 = LockResource(v10);
pNumFonts = 0;
AddFontMemResourceEx(v11, v9, 0, &pNumFonts);
v12 = 0;
v13 = strlen(aTriglavian);
do
{
byte_405418[v12] = v12;
v14 = 0;
while ( aTriglavian[v12 % v13] != byte_403370[v14] )// base64 A-a-0-+/
{
if ( ++v14 >= 64 )
{
LOBYTE(v14) = -1;
break;
}
}
byte_4053D8[v12++] = v14;
}
while ( v12 < 64 );
v15 = 0;
for ( i = 0; i < 64; ++i )
{
v17 = byte_405418[i];
v15 = (v17 + byte_4053D8[i] + v15) % 64;
byte_405418[i] = byte_405418[v15];
byte_405418[v15] = v17;
}
v18 = time64(0);
srand(v18);
v19 = GetDC(hWnd);
hdcSrc = CreateCompatibleDC(v19);
ho = CreateCompatibleBitmap(v19, w, cy);
SelectObject(hdcSrc, ho);
ReleaseDC(hWnd, v19);
v20 = CreateFontA(32, 27, 0, 0, 700, 0, 0, 0, 1u, 0, 0, 1u, 0x21u, "Triglavian - Complete");
SelectObject(hdcSrc, v20);
DeleteObject(v20);
SetBkMode(hdcSrc, 1);
dword_405474 = w / 48;
v21 = 0;
Block = calloc(w / 48, 0x20u);
if ( dword_405474 > 0 )
{
v22 = 0;
v23 = 0;
do
{
sub_401270(v23);
++v21;
v22 += 32;
v23 += 48;
}
while ( v21 < dword_405474 );
}
return 0;
然后加密,每运行1次加密1字符。
char sub_401160()
{
char v0; // bl
int v1; // edi
char v2; // dl
int v3; // ecx
char v4; // al
int v5; // eax
if ( dword_40545C > *(_DWORD *)(*(_DWORD *)NtCurrentTeb()->ThreadLocalStoragePointer + 4) )
{
_Init_thread_header(&dword_40545C);
if ( dword_40545C == -1 )
{
dword_405460 = rand();
_Init_thread_footer(&dword_40545C);
}
}
dword_405460 = (dword_405460 + 1) % 192;
v0 = byte_4032A8[dword_405460];
v1 = (dword_4053D4 + 1) % 64;
v2 = byte_405418[v1];
dword_4053D4 = v1;
v3 = (v2 + dword_4053D0) % 64;
v4 = byte_405418[v3];
dword_4053D0 = v3;
byte_405418[v1] = v4;
byte_405418[v3] = v2;
v5 = 0;
while ( v0 != byte_403370[v5] )
{
if ( ++v5 >= 64 )
{
LOBYTE(v5) = -1;
return byte_403370[(char)v5 ^ byte_405418[(v2 + byte_405418[v1]) % 64]];
}
}
return byte_403370[(char)v5 ^ byte_405418[(v2 + byte_405418[v1]) % 64]];
}
前边已经有好几个RC4的题了,思路都一样
code = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
key = (b'Triglavian'*10)[:64]
key = [code.index(i) for i in key]
#生成key
S = list(range(64))
j = 0
for i in range(64):
j = (j + S[i] + key[i])%64
S[i],S[j] = S[j],S[i]
#生成足够长的码表
i,j = 0,0
tab = [0]*200
for k in range(200):
i = (i + 1)%64
j = (j + S[i])%64
S[i],S[j] = S[j],S[i]
tab[k] = S[(S[i]+S[j])%64]
print(tab, len(tab))
c = b'20c1LOP2FnBOCMhPbCdtXTHmpgoK7g1sPN0KCcaBs3sWx/5Bob1t6IJaahW6SUGpTW11DmhJGeTj3UCSPCOZYaLw9qmg80kN56XF+dNhBYlfKbWqwSKJl+zTBvH0yBLDy7nwJ1W/SeBW+LaUV1Dq4FRnogzD5FOHNknyfyMerA3o5lgRq03f2M5C7ixuJ6WK'
print( bytes( [code[code.index(v) ^ tab[i]] for i,v in enumerate(c) ] ) )
#b'flag/SECRETTriglavianModifiyM1n1RC4StreamCipher/flag/SECRETTriglavianModifiyM1n1RC4StreamCipher/flag/SECRETTriglavianModifiyM1n1RC4StreamCipher/flag/SECRETTriglavianModifiyM1n1RC4StreamCipher/'
#flag/SECRETTriglavianModifiyM1n1RC4StreamCipher/