目录
033_[MRCTF2020]Xor
034_[GWCTF 2019]xxor
035_[MRCTF2020]hello_world_go
036_[WUSTCTF2020]level3
037_[FlareOn4]IgniteMe
038_[WUSTCTF2020]Cr0ssfun
039_[FlareOn6]Overlong
040_[FlareOn3]Challenge1
041_[BJDCTF2020]BJD hamburger competition
042_[UTCTF2020]basic-re
043_[ACTF新生赛2020]Oruga
044_[Zer0pts2020]easy strcmp
045_[ACTF新生赛2020]Universe_final_answer
046_特殊的 BASE64
047_[WUSTCTF2020]level4
048_crackMe
049_[网鼎杯 2020 青龙组]singal
050_[GUET-CTF2019]number_game
033_[MRCTF2020]Xor
名字叫xor,但进去后没法F5
.text:00401090 push offset aGiveMeYourFlag ; "Give Me Your Flag String:\n"
.text:00401095 call sub_401020
.text:0040109A push 64h ; 'd'
.text:0040109C push offset byte_4212C0
.text:004010A1 push offset aS ; "%s"
.text:004010A6 call sub_401050
.text:004010AB mov edx, offset byte_4212C0
.text:004010B0 add esp, 10h
.text:004010B3 lea ecx, [edx+1]
.text:004010B6
.text:004010B6 loc_4010B6: ; CODE XREF: _main+2B↓j
.text:004010B6 mov al, [edx]
.text:004010B8 inc edx
.text:004010B9 test al, al
.text:004010BB jnz short loc_4010B6
.text:004010BD sub edx, ecx
.text:004010BF cmp edx, 1Bh
.text:004010C2 jnz short loc_4010FF
.text:004010C4 xor eax, eax
.text:004010C6 db 66h, 66h
.text:004010C6 nop word ptr [eax+eax+00000000h]
.text:004010D0
.text:004010D0 loc_4010D0: ; CODE XREF: _main+53↓j
.text:004010D0 mov cl, byte_4212C0[eax]
.text:004010D6 xor cl, al
.text:004010D8 cmp cl, ds:byte_41EA08[eax]
.text:004010DE jnz short loc_4010FF
.text:004010E0 inc eax
.text:004010E1 cmp eax, edx
.text:004010E3 jb short loc_4010D0
.text:004010E5 push offset aRight ; "Right!\n"
.text:004010EA call sub_401020
.text:004010EF push offset aPause ; "pause"
.text:004010F4 call sub_404B7E
从4010C6这块就不清楚了,于是把这些不理它直接跳过,从汇编上看前边是scanf读入,后边就是个xor然后for结束就出right了。
在4010D0 读入一字节到cl,然后和al异或,al存的是位置偏移——序号,就是跟序号异或。
a = b'MSAWB~FXZ:J:`tQJ"N@ bpdd}8g'
print(bytes([i^v for i,v in enumerate(a)]))
#MRCTF{@_R3@1ly_E2_R3verse!}
#flag{@_R3@1ly_E2_R3verse!}
034_[GWCTF 2019]xxor
又一个xor但这个能F5,可以看到它每两上字节作个加密。这个似曾相识,叫RC4吧。就是前一半和后一半用对方加密,这样从后向前进行N轮就能解密
......
for ( j = 0; j <= 2; ++j )
{
dword_601078 = v6[j];
dword_60107C = HIDWORD(v6[j]);
a2 = (char **)dword_601060;
sub_400686((unsigned int *)&dword_601078, dword_601060);// RC4加密
LODWORD(v7[j]) = dword_601078;
HIDWORD(v7[j]) = dword_60107C;
}
}
//加密
__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{
__int64 result; // rax
unsigned int v3; // [rsp+1Ch] [rbp-24h]
unsigned int v4; // [rsp+20h] [rbp-20h]
int v5; // [rsp+24h] [rbp-1Ch]
unsigned int i; // [rsp+28h] [rbp-18h]
v3 = *a1;
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 0x3F; ++i )
{
v5 += 0x458BCD42;
v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}
//结果,加密后对比
__int64 __fastcall sub_400770(_DWORD *a1)
{
__int64 result; // rax
if ( a1[2] - a1[3] == 0x84A236FFLL
&& a1[3] + a1[4] == 0xFA6CB703LL
&& a1[2] - a1[4] == 0x42D731A8LL
&& *a1 == 0xDF48EF7E
&& a1[5] == 0x84F30420
&& a1[1] == 0x20CAACF4 )
{
puts("good!");
result = 1LL;
}
else
{
puts("Wrong!");
result = 0LL;
}
return result;
}
解密
v7 = [0xDF48EF7E, 0x20CAACF4, 0,0,0,0]
v7[2] = ((0x84A236FF+0x42D731A8+0xFA6CB703)//2)& 0xffffffff
v7[3] = (v7[2] - 0x84A236FF) & 0xffffffff
v7[4] = (v7[2] - 0x42D731A8) & 0xffffffff
v7[5] = 0x84F30420
a2 = [2,2,3,4]
tab = [0]*0x40
v5 = 0
for i in range(0x40):
v5 += 0x458BCD42
v5 = v5 & 0xffffffff
tab[i] = v5
#[print(hex(i)) for i in tab]
from libnum import n2s
# v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
# v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
def rc4(v3,v4):
global flag
for i in range(0x3f,-1,-1):
v4 -= (v3 + tab[i] + 20)^((v3 << 6)+ a2[2]) ^ ((v3>>9) + a2[3]) ^ 0x10
v4 = v4 & 0xffffffff
v3 -= (v4 + tab[i] + 11)^((v4 << 6)+ a2[0]) ^ ((v4>>9) + a2[1]) ^ 0x20
v3 = v3 & 0xffffffff
#print(n2s(v3), n2s(v4), hex(v3), hex(v4))
flag +=n2s(v3) + n2s(v4)
flag = b''
for i in range(0,6,2):
rc4(v7[i], v7[i+1])
print(flag)
#flag{re_is_great!}
035_[MRCTF2020]hello_world_go
这个啥也不用
.rodata:00000000004D3C58 aFlagHelloWorld db 'flag{hello_world_gogogo}function not implementedgcDrainN phase in'
036_[WUSTCTF2020]level3
一个变表的base64
__int64 O_OLookAtYou()
{
__int64 result; // rax
char v1; // [rsp+1h] [rbp-5h]
int i; // [rsp+2h] [rbp-4h]
for ( i = 0; i <= 9; ++i )
{
v1 = base64_table[i];
base64_table[i] = base64_table[19 - i];
result = 19 - i;
base64_table[result] = v1;
}
return result;
}
直接转加再base64
code = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
ncode = list(code)
for i in range(10):
ncode[i],ncode[19-i] = ncode[19-i],ncode[i]
ncode = bytes(ncode)
print(ncode)
c = b"d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD=="
c = bytes([code[ncode.index(i)] for i in c])
print(c)
from base64 import b64decode
print(b64decode(c))
#wctf2020{Base64_is_the_start_of_reverse}
#flag{Base64_is_the_start_of_reverse}
037_[FlareOn4]IgniteMe
程序很短,有点像AES,先用初始值异或,然后存回,再用加密后的值异或下一个
int check()
{
int v1; // [esp+0h] [ebp-Ch]
int i; // [esp+4h] [ebp-8h]
unsigned int j; // [esp+4h] [ebp-8h]
char v4; // [esp+Bh] [ebp-1h]
v1 = strlen((int)byte_403078);
v4 = ret_4(); // 4
for ( i = v1 - 1; i >= 0; --i )
{
byte_403180[i] = v4 ^ byte_403078[i];
v4 = byte_403078[i];
}
for ( j = 0; j < 0x27; ++j )
{
if ( byte_403180[j] != (unsigned __int8)byte_403000[j] )
return 0;
}
return 1;
}
从前向后再来一遍
a = [0x0D,0x26,0x49,0x45,0x2A,0x17,0x78,0x44,0x2B,0x6C,
0x5D,0x5E,0x45,0x12,0x2F,0x17,0x2B,0x44,0x6F,0x6E,
0x56,0x09,0x5F,0x45,0x47,0x73,0x26,0x0A,0x0D,0x13,
0x17,0x48,0x42,0x01,0x40,0x4D,0x0C,0x02,0x69]
v4 = 4
b = [0]*0x27
for i in range(0x26,-1,-1):
a[i] = v4^a[i]
v4 = a[i]
print(bytes(a))
#R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com
#flag{R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com}
038_[WUSTCTF2020]Cr0ssfun
这个有很多下边这样的函数,每个对比3字节
_BOOL8 __fastcall finally_fun(_BYTE *a1)
{
return a1[1] == 99 && a1[25] == 64 && a1[27] == 101;
}
都写一起就是
a = [0]*33
a[10]=112
a[13]=64
......
a[27]=101
print(bytes(a))
#wctf2020{cpp_@nd_r3verse_@re_fun}
#flag{cpp_@nd_r3verse_@re_fun}
039_[FlareOn6]Overlong
除了不运行都有了
int __cdecl sub_401000(_BYTE *a1, char *a2)
{
int v3; // [esp+0h] [ebp-8h]
char v4; // [esp+4h] [ebp-4h]
if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
{
v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
v3 = 4;
}
else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
{
v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
v3 = 3;
}
else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
{
v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
v3 = 2;
}
else
{
v4 = *a2;
v3 = 1;
}
*a1 = v4;
return v3;
}
照这个写一下再运行
a = [0xE0,0x81,0x89,0xC0,0xA0,0xC1,0xAE,0xE0,0x81,0xA5,0xC1,0xB6,0xF0,0x80,0x81,0xA5,0xE0,0x81,0xB2,0xF0,0x80,0x80,0xA0,0xE0,0x81,0xA2,0x72,0x6F,0xC1,0xAB,0x65,0xE0,0x80,0xA0,0xE0,0x81,0xB4,0xE0,0x81,0xA8,0xC1,0xA5,0x20,0xC1,0xA5,0xE0,0x81,0xAE,0x63,0xC1,0xAF,0xE0,0x81,0xA4,0xF0,0x80,0x81,0xA9,0x6E,0xC1,0xA7,0xC0,0xBA,0x20,0x49,0xF0,0x80,0x81,0x9F,0xC1,0xA1,0xC1,0x9F,0xC1,0x8D,0xE0,0x81,0x9F,0xC1,0xB4,0xF0,0x80,0x81,0x9F,0xF0,0x80,0x81,0xA8,0xC1,0x9F,0xF0,0x80,0x81,0xA5,0xE0,0x81,0x9F,0xC1,0xA5,0xE0,0x81,0x9F,0xF0,0x80,0x81,0xAE,0xC1,0x9F,0xF0,0x80,0x81,0x83,0xC1,0x9F,0xE0,0x81,0xAF,0xE0,0x81,0x9F,0xC1,0x84,0x5F,0xE0,0x81,0xA9,0xF0,0x80,0x81,0x9F,0x6E,0xE0,0x81,0x9F,0xE0,0x81,0xA7,0xE0,0x81,0x80,0xF0,0x80,0x81,0xA6,0xF0,0x80,0x81,0xAC,0xE0,0x81,0xA1,0xC1,0xB2,0xC1,0xA5,0xF0,0x80,0x80,0xAD,0xF0,0x80,0x81,0xAF,0x6E,0xC0,0xAE,0xF0,0x80,0x81,0xA3,0x6F,0xF0,0x80,0x81,0xAD,0]
def sub_401000(p):
global b
if a[p]>>3 == 30: #f0
v4 = ((a[p+3]&0x3f) | ((a[p+2]&0x3f)<<6)) &0xff
v3 = 4
elif a[p]>>4 == 14: #e0
v4 = ((a[p+2]&0x3f)|((a[p+1]&0x3f)<<6))&0xff
v3 = 3
elif a[p]>>5 == 6: #c0
v4 = ((a[p+1]&0x3f)|((a[p]&0x1f)<<6))& 0xff
v3 = 2
else:
v4 = a[p]
v3 = 1
b.append(v4)
return v3
p = 0
b = []
while True:
p += sub_401000(p)
if b[-1]==0:
print(bytes(b))
break
#b'I never broke the encoding: I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com\x00'
#flag{I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com}
040_[FlareOn3]Challenge1
变表的base64
v7 = v3 + (v5 << 16) + (v4 << 8);
v8[v9] = aZyxabcdefghijk[(v7 >> 18) & 0x3F];// 前6位
v10 = v9 + 1;
v8[v10] = aZyxabcdefghijk[(v7 >> 12) & 0x3F];
v8[++v10] = aZyxabcdefghijk[(v7 >> 6) & 0x3F];
v8[++v10] = aZyxabcdefghijk[v3 & 0x3F];
v9 = v10 + 1;
code = 'ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/='
ncode= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"
m = ''.join([ncode[code.index(i)] for i in c])
from base64 import *
print(b64decode(m))
#sh00ting_phish_in_a_barrel@flare-on.com
#flag{sh00ting_phish_in_a_barrel@flare-on.com}
041_[BJDCTF2020]BJD hamburger competition
这题做过了,Unity的游戏找Assembly-CSharp.dll文件用dnSpy打开,给sha1求md5转大写前20位,由于输入是数字而且不大,直接爆破
from hashlib import *
s_sha1 = 'DD01903921EA24941C26A48F2CEC24E0BB0E8CC7'.lower()
for i in range(999999):
if sha1(str(i).encode()).hexdigest() == s_sha1:
print('flag{'+md5(str(i).encode()).hexdigest().upper()[:20]+'}')
break
#flag{B8C37E33DEFDE51CF91E}
042_[UTCTF2020]basic-re
打开以后汇编里有flag
.text:00000000000012FA lea rax, aUtflagStr1ngs1 ; "utflag{str1ngs_1s_y0ur_fr13nd}"
043_[ACTF新生赛2020]Oruga
ida打开发现主要逻辑是4个字母应该分别表示的是上下左右,应该是迷宫,找到迷宫串
while ( byte_201020[v2] != 33 )
{
v2 -= v4;
if ( *(_BYTE *)(v3 + a1) != 87 || v4 == -16 )// W
{
if ( *(_BYTE *)(v3 + a1) != 69 || v4 == 1 )// E
{
if ( *(_BYTE *)(v3 + a1) != 77 || v4 == 16 )// M
{
if ( *(_BYTE *)(v3 + a1) != 74 || v4 == -1 )// J
return 0LL;
v4 = -1;
}
else
{
v4 = 16;
}
}
else
{
v4 = 1;
}
}
else
{
v4 = -16;
}
++v3;
while ( !byte_201020[v2] )
{
if ( v4 == -1 && (v2 & 0xF) == 0 ) // 边界 滑行不能出边界
return 0LL;
if ( v4 == 1 && v2 % 16 == 15 )
return 0LL;
if ( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF )
return 0LL;
if ( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E )
return 0LL;
v2 += v4;
}
.data:0000000000201020 byte_201020 db 4 dup(0), 23h, 7 dup(0), 4 dup(23h), 3 dup(0), 2 dup(23h)
.data:0000000000201020 ; DATA XREF: sub_78A+23↑o
.data:0000000000201020 ; sub_78A+DC↑o
.data:0000000000201020 db 3 dup(0), 2 dup(4Fh), 0Eh dup(0), 2 dup(4Fh), 0, 2 dup(50h)
.data:0000000000201020 db 6 dup(0), 4Ch, 0, 2 dup(4Fh), 0, 2 dup(4Fh), 0, 2 dup(50h)
.data:0000000000201020 db 6 dup(0), 4Ch, 0, 2 dup(4Fh), 0, 2 dup(4Fh), 0, 50h
.data:0000000000201020 db 6 dup(0), 2 dup(4Ch), 0, 2 dup(4Fh), 4 dup(0), 50h
.data:0000000000201020 db 9 dup(0), 2 dup(4Fh), 4 dup(0), 50h, 4 dup(0), 23h
.data:0000000000201020 db 1Bh dup(0), 23h, 9 dup(0), 3 dup(4Dh), 3 dup(0), 23h
.data:0000000000201020 db 0Ah dup(0), 3 dup(4Dh), 4 dup(0), 2 dup(45h), 3 dup(0)
.data:0000000000201020 db 30h, 0, 4Dh, 0, 4Dh, 0, 4Dh, 4 dup(0), 45h, 0Fh dup(0)
.data:0000000000201020 db 2 dup(45h), 3 dup(54h), 49h, 0, 4Dh, 0, 4Dh, 0, 4Dh
.data:0000000000201020 db 4 dup(0), 45h, 2 dup(0), 54h, 0, 49h, 0, 4Dh, 0, 4Dh
.data:0000000000201020 db 0, 4Dh, 4 dup(0), 45h, 2 dup(0), 54h, 0, 49h, 0, 4Dh
.data:0000000000201020 db 0, 4Dh, 0, 4Dh, 21h, 3 dup(0), 2 dup(45h)
.data:0000000000201020 _data ends
只处理0和非0要结束
data = open('oruga', 'rb').read()[0x1020: 0x1020+0x100]
print('*'*16)
for i in range(16):
for j in range(16):
if data[i*16+j] == 0:
print(' ', end='')
elif data[i*16+j] == 33:
print('O', end='')
else:
print('#', end='')
print('*')
print('*'*16)
'''
****************
# ####*
## ## *
## ## *
# ## ## ## *
# ## ## # *
## ## # *
## # *
# *
# *
### # *
### ##*
# # # # # *
##*
#### # # # # *
# # # # # # *
# # # # #O ##*
****************
'''
用手走出迷宫
#MEWEMEWJMEWJM
#flag{MEWEMEWJMEWJM}
044_[Zer0pts2020]easy strcmp
这是个加法操作,这个少见
__int64 __fastcall sub_6EA(__int64 a1, __int64 a2)
{
int i; // [rsp+18h] [rbp-8h]
int v4; // [rsp+18h] [rbp-8h]
int j; // [rsp+1Ch] [rbp-4h]
for ( i = 0; *(_BYTE *)(i + a1); ++i )
;
v4 = (i >> 3) + 1;
for ( j = 0; j < v4; ++j )
*(_QWORD *)(8 * j + a1) -= qword_201060[j];
return qword_201090(a1, a2);
}
还有一个特殊的串
.rodata:00000000000008C8 ; const char format[]
.rodata:00000000000008C8 format db 'Usage: %s <FLAG>',0Ah,0
.rodata:00000000000008C8 ; DATA XREF: main+1F↑o
.rodata:00000000000008DA align 20h
.rodata:00000000000008E0 ; const char s2[]
.rodata:00000000000008E0 s2 db 'zer0pts{********CENSORED********}',0
.rodata:00000000000008E0 ; DATA XREF: main+3D↑o
.rodata:0000000000000902 ; const char s[]
.rodata:0000000000000902 s db 'Correct!',0 ; DATA XREF: main+50↑o
.rodata:000000000000090B ; const char aWrong[]
.rodata:000000000000090B aWrong db 'Wrong!',0 ; DATA XREF: main:loc_825↑o
.rodata:000000000000090B _rodata ends
加法操作的第1个数是0,就是没处理,所以头是原头,这个串就是
key = [0,0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B]
a = b'zer0pts{********CENSORED********'
from libnum import s2n,n2s
flag = b''
for i in range(4):
j = s2n(a[i*8: i*8+8][::-1]) + key[i] #大端存储
flag += n2s(j)[::-1]
print(flag)
#b'zer0pts{l3ts_m4k3_4_DETOUR_t0d4y'
#flag{l3ts_m4k3_4_DETOUR_t0d4y}
045_[ACTF新生赛2020]Universe_final_answer
看上去是个很复杂的操作
bool __fastcall sub_860(char *a1)
{
int v2; // ecx
int v1; // esi
int v3; // edx
int v4; // er9
int v5; // er11
int v7; // ebp
int v6; // ebx
int v8; // er8
int v9; // er10
bool result; // al
int v11; // [rsp+0h] [rbp-38h]
v2 = a1[1];
v1 = *a1;
v3 = a1[2];
v4 = a1[3];
v5 = a1[4];
v7 = a1[6];
v6 = a1[5];
v8 = a1[7];
v9 = a1[8];
result = 0;
if ( -85 * v9 + 58 * v8 + 97 * v7 + v6 + -45 * v5 + 84 * v4 + 95 * v1 - 20 * v2 + 12 * v3 == 12613 )
{
v11 = a1[9];
if ( 30 * v11 + -70 * v9 + -122 * v7 + -81 * v6 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v2 - 15 * v1 - 30 * v8 == -54400
&& -103 * v11 + 120 * v8 + 108 * v6 + 48 * v4 + -89 * v3 + 78 * v2 - 41 * v1 + 31 * v5 - (v7 << 6) - 120 * v9 == -10283
&& 71 * v7 + (v6 << 7) + 99 * v5 + -111 * v3 + 85 * v2 + 79 * v1 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855
&& 5 * v11 + 23 * v9 + 122 * v8 + -19 * v7 + 99 * v6 + -117 * v5 + -69 * v3 + 22 * v2 - 98 * v1 + 10 * v4 == -2944
&& -54 * v11 + -23 * v8 + -82 * v3 + -85 * v1 + 124 * v2 - 11 * v4 - 8 * v5 - 60 * v6 + 95 * v7 + 100 * v9 == -2222
&& -83 * v11 + -111 * v6 + -57 * v1 + 41 * v2 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v7 + 77 * v8 - 63 * v9 == -13258
&& 81 * v11 + -48 * v9 + 66 * v8 + -104 * v7 + -121 * v6 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v1 + 80 * v2 == -1559
&& 101 * v11 + -85 * v9 + 7 * v7 + 117 * v6 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v2 + 18 * v1 - v8 == 6308 )
{
result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v7 + -18 * v6 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v2 + 58 * v1 == -1697;
}
}
return result;
}
其实就是个行列比,直接用numpy.linalg求解
'''
if ( -85 * v9 + 58 * v8 + 97 * v7 + v6 + -45 * v5 + 84 * v4 + 95 * v1 - 20 * v2 + 12 * v3 == 12613 )
{
v11 = a1[9];
if ( 30 * v11 + -70 * v9 + -122 * v7 + -81 * v6 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v2 - 15 * v1 - 30 * v8 == -54400
&& -103 * v11 + 120 * v8 + 108 * v6 + 48 * v4 + -89 * v3 + 78 * v2 - 41 * v1 + 31 * v5 - (v7 << 6) - 120 * v9 == -10283
&& 71 * v7 + (v6 << 7) + 99 * v5 + -111 * v3 + 85 * v2 + 79 * v1 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855
&& 5 * v11 + 23 * v9 + 122 * v8 + -19 * v7 + 99 * v6 + -117 * v5 + -69 * v3 + 22 * v2 - 98 * v1 + 10 * v4 == -2944
&& -54 * v11 + -23 * v8 + -82 * v3 + -85 * v1 + 124 * v2 - 11 * v4 - 8 * v5 - 60 * v6 + 95 * v7 + 100 * v9 == -2222
&& -83 * v11 + -111 * v6 + -57 * v1 + 41 * v2 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v7 + 77 * v8 - 63 * v9 == -13258
&& 81 * v11 + -48 * v9 + 66 * v8 + -104 * v7 + -121 * v6 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v1 + 80 * v2 == -1559
&& 101 * v11 + -85 * v9 + 7 * v7 + 117 * v6 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v2 + 18 * v1 - v8 == 6308 )
{
result = 99 * v11 + -28 * v9 + 5 * v8 + 93 * v7 + -18 * v6 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v2 + 58 * v1 == -1697;
}
'''
tab_a = [
[95,-20,12,84,-45,1,97,58,-85,0],
[-15,-86,-41,-115,-66,-81,-122,-30,-70,30],
[-41,78,-89,48,31,108,-64,120,-120,-103],
[79,85,-111,-30,99,128,71,-119,48,-16],
[-98,22,-69,10,-117,99,-19,122,23,5],
[-85,124,-82,-11,-8,-60,95,-23,100,-54],
[-57,41,73,-18,26,-111,16,77,-63,-83],
[-85,80,60,85,95,-121,-104,66,-48,81],
[18,-28,90,-101,-83,117,7,-1,-85,101],
[58,-93,-9,6,-127,-18,93,5,-28,99]
]
tab_b = [12613,-54400,-10283,22855,-2944,-2222,-13258,-1559,6308,-1697]
import numpy as np
an = np.array(tab_a)
bn = np.array(tab_b)
x = np.linalg.solve(an,bn)
print(x)
print(bytes([round(i) for i in x]))
#F0uRTy_7w@
#actf{F0uRTy_7w@_42}
#flag{F0uRTy_7w@_42}
046_特殊的 BASE64
同上,一个变列的base64
code ="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0987654321/+="
ncode = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
c = "mTyqm7wjODkrNLcWl0eqO8K8gc1BPk1GNLgUpI=="
m = ''.join([ncode[code.index(i)] for i in c])
from base64 import *
print(b64decode(m))
#flag{Special_Base64_By_Lich}
047_[WUSTCTF2020]level4
给了二叉树的中序和后序遍历,求先序,手工处理了
v2 = "I{_}Af2700ih_secTS2Et_wr"
#Traversal type 1:2f0t02T{hcsiI_SwA__r7Ee} 中序
#Traversal type 2:20f0Th{2tsIS_icArE}e7__w 后序
#先序
#wctf2020{This_IS_A_7reE}
#flag{This_IS_A_7reE}
048_crackMe
加了一堆反调试语句,大至就是与user,pass异或
} // 16进制转数字
while ( v6 < 8 )
{
v11 += byte_416050[++v12];
v13 = byte_416050[v12];
v8 = byte_416050[v11];
byte_416050[v11] = v13;
byte_416050[v12] = v8;
if ( ((int)NtCurrentPeb()->UnicodeCaseTableData & 0x70) != 0 )
v13 = v11 + v12;
*(&v17 + v6) = byte_416050[(unsigned __int8)(v8 + v13)] ^ *(&v15 + v5);// ^pass
if ( (unsigned __int8)*(_DWORD *)&NtCurrentPeb()->BeingDebugged )
{
v11 = -83;
v12 = 43;
}
sub_401710((int)&v17, (const char *)user, v6++);// ^user
v5 = v6;
if ( v6 >= (unsigned int)(&v15 + strlen(&v15) + 1 - v16) )
v5 = 0;
}
v14 = 0;
sub_401470(a1, &v17, &v14);
return v14 == 0xAB94;
然后再异或回来
user = (b"welcomebeijing"*20)[:256]
byte_416050 = [i for i in range(256)]
v9 = 0
for i in range(256):
v9 += byte_416050[i] + user[i]
v9 = v9 & 0xff
byte_416050[i],byte_416050[v9] = byte_416050[v9],byte_416050[i]
v10 = 0
v5 = 0
v11 = 0
out = [0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63] #结果 = byte_416050 ^ user ^ pass
v16 = [0]*8
for v5 in range(8):
v11 +=1
v11 = v11 & 0xff
v10 += byte_416050[v11]
v10 = v10&0xff
v12 = byte_416050[v11]
v7 = byte_416050[v10]
byte_416050[v10] = v12
byte_416050[v11] = v7
v16[v5] = byte_416050[(v7 + v12)&0xff] ^ user[v5] ^ out[v5] #sub_401710 #^ pass[v5]
print(v16)
password = ''
for i in v16:
password +=hex(i)[2:]
print(password)
from hashlib import md5
print('flag{'+ md5(password.encode()).hexdigest()+'}')
#39d09ffa4cfcc4cc
结果不对,网上说是(没有异或user)
#4eb5f3992391a1ae
print('flag{'+ md5(b'4eb5f3992391a1ae').hexdigest()+'}')
#flag{d2be2981b84f2a905669995873d6a36c}
049_[网鼎杯 2020 青龙组]singal
像VM的题,不过数据都给出来了,只是按样子写个东西运行就行
data = open('signal.exe', 'rb').read()[0x1e40:0x1e40+114*4]
from pwn import u32
data = [ u32(data[i*4: i*4+4]) for i in range(114) ][1:]
print(data)
idx = 0
v5,v6,v7,v8,v9 = 0,0,0,0,0
s = [f"str[{i}]" for i in range(15)]
t,v = [],[]
while v9< len(data):
if data[v9] == 2:
v4 = f"({s[v8]}) + {data[v9+1]} "
v9+=2
elif data[v9] == 3:
v4 = f"({s[v8]}) - {data[v9+1]}"
v9+=2
elif data[v9] == 4:
v4 = f"({s[v8]}) ^ {data[v9+1]}"
v9+=2
elif data[v9] == 5:
v4 = f"({s[v8]}) * {data[v9+1]}"
v9+=2
elif data[v9] == 11:
v4 = f"({s[v8]}) -1 "
v9+=1
elif data[v9] == 12:
v4 = f"({s[v8]}) +1"
v9+=1
elif data[v9] == 6:
v9+=1
elif data[v9] == 1:
v.append(v4)
v9+=1
v6+=1
v8+=1
elif data[v9] == 8:
#s.append(f"str[{v5}] = "+ v4)
s[v5] = v4
v9+=1
v5+=1
elif data[v9] == 7:
if data[v9+1] > 0x80000000:
data[v9+1] = data[v9+1] - 0x100000000
t.append(f' == {data[v9+1]}')
v9+=2
v7+=1
print(s)
print(v)
print(t)
for i in range(15):
print(v[i] + t[i])
str = [0]*15
for i in range(15):
for j in range(0x20,0x7f):
str[i] = j
if eval(v[i] + t[i]+ "&0xff"):
print(chr(j), end='')
break
#757515121f3d478
#flag{757515121f3d478}
050_[GUET-CTF2019]number_game
二叉树遍历,再查重(5*5行列不重复,类似数独,但相当简单)这块手工算,再二叉权遍历手工算
if ( (unsigned int)sub_4006D6((const char *)&v5) )// 01234组成的10位串
{
v4 = sub_400758(&v5, 0LL, 10LL); // 按层二叉树填充
sub_400807(v4, &v7); // 中序遍历取回 7381940526
v9 = 0;
sub_400881(&v7);
if ( (unsigned int)sub_400917() )
{
puts("TQL!");
printf("flag{");
printf("%s", (const char *)&v5);
puts("}");
}
else
{
puts("your are cxk!!");
}
}
__int64 __fastcall sub_400807(__int64 a1, __int64 a2)
{
__int64 result; // rax
result = a1;
if ( a1 )
{
sub_400807(*(_QWORD *)(a1 + 8), a2); //中序遍历
*(_BYTE *)(a2 + dword_601080++) = *(_BYTE *)a1;
result = sub_400807(*(_QWORD *)(a1 + 16), a2);
}
return result;
}
__int64 sub_400917()
{
unsigned int v1; // [rsp+0h] [rbp-10h]
int i; // [rsp+4h] [rbp-Ch]
int j; // [rsp+8h] [rbp-8h]
int k; // [rsp+Ch] [rbp-4h]
v1 = 1;
for ( i = 0; i <= 4; ++i )
{
for ( j = 0; j <= 4; ++j )
{
for ( k = j + 1; k <= 4; ++k )
{
if ( *((_BYTE *)&unk_601060 + 5 * i + j) == *((_BYTE *)&unk_601060 + 5 * i + k) )
v1 = 0;
if ( *((_BYTE *)&unk_601060 + 5 * j + i) == *((_BYTE *)&unk_601060 + 5 * k + i) )
v1 = 0;
}
}
}
return v1;
}
手工
#0421421430 中序排列后的结果,中序的顺序7381940526
#1134240024 按中中序顺序取回
#flag{1134240024}
|