7,easyRE1
ida打开,看到flag
mov edi, offset aFlagDb2f62a36a ; "FLAG:db2f62a36a018bce28e46d976e3f9864"
换壳
flag{db2f62a36a018bce28e46d976e3f9864}
8,Reversing-x64Elf-100
主逻辑
signed __int64 __fastcall main(__int64 a1, char **a2, char **a3) { signed __int64 result; // rax char s; // [rsp 0h] [rbp-110h] unsigned __int64 v5; // [rsp 108h] [rbp-8h] v5 = __readfsqword(0x28u); printf("Enter the password: ", a2, a3); if ( !fgets(&s, 255, stdin) ) return 0LL; if ( (unsigned int)sub_4006FD((__int64)&s) ) { puts("Incorrect password!"); result = 1LL; } else { puts("Nice!"); result = 0LL; } return result; } signed __int64 __fastcall sub_4006FD(__int64 a1) { signed int i; // [rsp 14h] [rbp-24h] const char *v3; // [rsp 18h] [rbp-20h] const char *v4; // [rsp 20h] [rbp-18h] const char *v5; // [rsp 28h] [rbp-10h] v3 = "Dufhbmf"; v4 = "pG`imos"; v5 = "ewUglpt"; for ( i = 0; i <= 11; i ) { if ( (&v3)[i % 3][2 * (i / 3)] - *(char *)(i a1) != 1 ) return 1LL; } return 0LL; }
垂直看,奇数列再减1
a=b'Dpef`Ubmlfst' for i in a: print(chr(i-1), end='') #Code_Talkers
9,su-ctf-quals-2014_Guess-the-Number
jar java的包,用jd打开原码是串异或两上串异
a = 0x4b64ca12ace755516c178f72d05d7061; b = 0xecd44646cfe5994ebeb35bf922e25dba; c = a^b print(hex(c)) # a7b08c546302cc1fd2a4d48bf2bf2ddb
10,XCTF 4th-WHCTF-2017_babyre
主程序首先解密函数(即异)
int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [rsp 0h] [rbp-20h] int v5; // [rsp 18h] [rbp-8h] int i; // [rsp 1Ch] [rbp-4h] for ( i = 0; i <= 181; i ) { envp = (const char **)(*((unsigned __int8 *)judge i) ^ 0xCu); *((_BYTE *)judge i) ^= 0xCu; } printf("Please input flag:", argv, envp); __isoc99_scanf(" s", &s); v5 = strlen(&s); if ( v5 == 14 && (unsigned int)judge(&s) ) puts("Right!"); else puts("Wrong!"); else puts("Wrong!"); return 0; }
先把原程序patch(第一次使用此功能)
from pwn import * e = ELF('babyre') start_addr = 0x600b00 old = e.read(start_addr, 0xb6) print(old) new_file = bytes([i^0xc for i in old]) print(new_file) e.write(start_addr, new_file) e.save('babyre2') #print(e.read(start_addr, 0xb6))
然后是个简单的解密
a =[102、109、99、100、127、107、55、100、59、86、96、110、112] print(''.join([chr(i^v) for i,v in enumerate(a)])) #flag{n1c3_j0b}
11,XCTF 4th-WHCTF-2017_easyhook
首先将文件写入主程序,然后与假程序一起使用flag比较,名字叫hook也就是说,钩子里有逻辑
int __cdecl main(int argc, const char **argv, const char **envp) { int result; // eax HANDLE v4; // eax DWORD NumberOfBytesWritten; // [esp 4h] [ebp-24h] char Buffer; // [esp 8h] [ebp-20h] puts((int)aPleaseInputFla); scanf(a31s, &Buffer); if ( strlen(&Buffer) == 19 ) { sub_401220(); // 调用钩子 v4 = CreateFileA(FileName, 0x40000000u, 0, 0, 2u, 0x80u, 0); WriteFile(v4, &Buffer, 0x13u, &NumberOfBytesWritten, 0); sub_401240(&Buffer, &NumberOfBytesWritten); if ( NumberOfBytesWritten == 1 ) puts((int)aRightFlagIsYou); else puts((int)aWrong); system(aPause); result = 0; } else { puts((int)aWrong); system(aPause); result = 0; } return result; } int sub_401220() { HMODULE v0; // eax DWORD v2; // eax v2 = GetCurrentProcessId(); hProcess = OpenProcess(0x1F0FFFu, 0, v2); v0 = LoadLibraryA(LibFileName); dword_40C9C4 = (int)GetProcAddress(v0, ProcName); lpAddress = (LPVOID)dword_40C9C4; if ( !dword_40C9C4 ) return puts((int)aApi); unk_40C9B4 = *(_DWORD *)lpAddress; *((_BYTE *)&unk_40C9B4 4) = *((_BYTE *)lpAddress 4); byte_40C9BC = -23; dword_40C9BD = (char *)sub_401080 - (char *)lpAddress - 5; return sub_4010D0(); } int __stdcall sub_401080(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { signed int v5; // ebx v5 = sub_401000((int)lpBuffer, nNumberOfBytesToWrite); sub_401140(); WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); if ( v5 ) *lpNumberOfBytesWritten = 1; return 0; } signed int __cdecl sub_401000(int a1, signed int a2) { char v2; // al char v3; // bl char v4; // cl int v5; // eax v2 = 0; if ( a2 > 0 ) { do { if ( v2 == 18 ) { *(_BYTE *)(a1 18) = 0x13u;
}
else
{
if ( v2 % 2 )
v3 = *(_BYTE *)(v2 + a1) - v2;
else
v3 = *(_BYTE *)(v2 + a1 + 2);
*(_BYTE *)(v2 + a1) = v2 ^ v3;
}
++v2;
}
while ( v2 < a2 );
}
v4 = 0;
if ( a2 <= 0 )
return 1;
v5 = 0;
while ( byte_40A030[v5] == *(_BYTE *)(v5 + a1) )
{
v5 = ++v4;
if ( v4 >= a2 )
return 1;
}
return 0;
}
逆向401000编码部分
#hook,sub_401000将数据加密后与0x40A030比较检查
a = bytes.fromhex('616A79676B466D2E7F5F7E2D53567B386D4C6E')
b = [0]*len(a)
for i,v in enumerate(a):
if i==18:
b[i]=v^0x13
else:
c = v^i
if i%2 == 1:
b[i]= c+i
else:
b[i+2]= c
print(bytes(b))
#b'\x00lag{Ho0k_w1th_Fun}'
#flag{Ho0k_w1th_Fun}
12,easyre
主要处理在sub_401080,加1再异或6
int sub_401080()
{
unsigned int v0; // kr00_4
signed int v1; // edx
char *v2; // esi
char v3; // al
unsigned int v4; // edx
int v5; // eax
__int128 v7; // [esp+2h] [ebp-24h]
__int64 v8; // [esp+12h] [ebp-14h]
int v9; // [esp+1Ah] [ebp-Ch]
__int16 v10; // [esp+1Eh] [ebp-8h]
sub_401020((int)&unk_402150);
v9 = 0;
v10 = 0;
v7 = 0i64;
v8 = 0i64;
sub_401050((const char *)&unk_402158, &v7);
v0 = strlen((const char *)&v7);
if ( v0 >= 0x10 && v0 == 24 )
{
v1 = 0;
v2 = (char *)&v8 + 7;
do
{
v3 = *v2--;
byte_40336C[v1++] = v3;
}
while ( v1 < 24 );
v4 = 0;
do
{
byte_40336C[v4] = (byte_40336C[v4] + 1) ^ 6;
++v4;
}
while ( v4 < 0x18 );
v5 = strcmp(byte_40336C, (const char *)&unk_402124);
if ( v5 )
v5 = -(v5 < 0) | 1;
if ( !v5 )
{
sub_401020((int)"right\n");
system("pause");
}
}
return 0;
}
逆向
unlink_402142 = bytes.fromhex('784972436A7E3C727C3274577376335074497F7A6E646B61')
a = [0]*0x18
for i in range(0x18):
a[i]=(unlink_402142[i]^6)-1
print(bytes(a)[::-1])
#flag{xNqU4otPq3ys9wkDsN}