White Hat Play 11
Table of Contents
re01-WhiteHatPlay11v1 - 128pts #
Check file bằng DiE và mở bằng IDA32:
Input của mình sau khi nhập vào Buffer thì sẽ được đưa vào hàm sub_4010A0()
xử lí:
Trong hàm này, mình đã đổi 0x55 thành 85 cho dễ nhìn, tới đây mình thấy nghi nghi, thử bấm vào byte_40EFB0
xem nó là gì:
Rồi luôn, tới đây thì mình khá chắc là chương trình này dùng base85
, mình thử kiếm cipher
trong string và xref, mình thấy 2 đoạn này khá phù hợp:
Thử trên cyber chef và bùm:
Flag: WhiteHat{Whit3H4t11H4v34N1C3D4yR3VeRs31!}
re02-WhiteHatPlay11v2 - 256pts #
Lần này đề cho mình file dll, tiếp tục check và mở bằng IDA32 lên xem:
Trong IDA mình thấy 1 hàm tên là WhiteHat khá là khả nghi:
char WhiteHat()
{
int v0; // edi
int v1; // esi
int v2; // kr04_4
char *v3; // eax
char *v4; // ecx
void *v5; // eax
void **v6; // eax
int v7; // eax
int i; // ecx
int v10; // [esp+0h] [ebp-4B4h]
int v11; // [esp+10h] [ebp-4A4h]
int v12[14]; // [esp+14h] [ebp-4A0h]
void *v13[4]; // [esp+4Ch] [ebp-468h] BYREF
int v14; // [esp+5Ch] [ebp-458h]
unsigned int v15; // [esp+60h] [ebp-454h]
void *v16; // [esp+64h] [ebp-450h]
int v17; // [esp+74h] [ebp-440h]
unsigned int v18; // [esp+78h] [ebp-43Ch]
char Str[264]; // [esp+7Ch] [ebp-438h] BYREF
char v20; // [esp+184h] [ebp-330h] BYREF
char v21[263]; // [esp+185h] [ebp-32Fh] BYREF
char Destination[264]; // [esp+28Ch] [ebp-228h] BYREF
char v23[268]; // [esp+394h] [ebp-120h] BYREF
int v24; // [esp+4B0h] [ebp-4h]
v11 = 1887667281;
v12[0] = 1882219565;
v12[1] = 743254827;
v12[2] = 762456936;
v12[3] = -2105317328;
v12[4] = 1865175935;
v12[5] = -2004341935;
v12[6] = 2139565390;
v12[7] = 1848467079;
v20 = 0;
memset(v21, 0, 0x103u);
memset(Str, 0, 260);
memset(Destination, 0, 260);
memset(v23, 0, 260);
v0 = 0;
v18 = 15;
v17 = 0;
LOBYTE(v16) = 0;
v24 = 1;
v15 = 15;
v14 = 0;
LOBYTE(v13[0]) = 0;
sub_10003997("___________________________________________________________________________\n");
sub_10003997(" __ \n");
sub_10003997(" _ _ _ _ _ _ _____ _ _____ _ | | ___ ___ \n");
sub_10003997("| | | | |_|_| |_ ___| | |___| |_ | _ | |___ _ _ | | |_ | |_ | \n");
sub_10003997("| | | | | | _| -_| | .'| _| | __| | .'| | | |__| _| |_ _| |_ \n");
sub_10003997("|_____|_|_|_|_| |___|__|__|__,|_| |__| |_|__,|_ | |__| |_____|_____|\n");
sub_10003997(" |___| \n");
sub_10003997("___________________________________________________________________________\n");
sub_10003997("\n********Let's Play!********\n");
sub_10003997("Try to guess the flag: ");
gets_s(Str, 0x104u);
v1 = strlen(Str);
if ( v1 < 40 )
{
while ( 1 )
{
sub_10003997("\nHmm, enter something more interesting: ");
gets_s(Str, 0x104u);
v2 = strlen(Str);
v1 = v2;
if ( v2 > 41 )
break;
if ( v2 >= 40 )
goto LABEL_6;
}
sub_10003997("Great! It may be the right flag :)\n");
}
LABEL_6:
sub_10003997("Checking...\n");
Sleep(0x3E8u);
strncpy_s(Destination, 0x104u, Str, 0x24u);
if ( !strstr(Str, "@") )
goto LABEL_41;
v3 = strrchr(Str, 64);
strncpy_s(v23, 0x104u, v3, 5u);
v4 = Str;
if ( dword_10018FD4 != 1 )
v4 = Destination;
sub_10001EC0(v4, &v20);
sub_100017A0("QDIwMjI=", 8u);
v5 = (void *)sub_10001430(v10);
sub_100023E0(v13, v5);
if ( v12[13] >= 0x10u )
j__free((void *)v12[8]);
v6 = v13;
if ( v15 >= 0x10 )
v6 = (void **)v13[0];
v7 = strcmp(v23, (const char *)v6);
if ( v7 )
v7 = v7 < 0 ? -1 : 1;
if ( v7 )
{
LABEL_41:
sub_10003997("Oh no! That is a wrong flag! Try again!!1\n");
}
else
{
sub_10003997("Great! Keep moving...\n");
Sleep(0x3E8u);
if ( FindWindowA("OllyDbg", 0) )
ExitProcess(0);
if ( FindWindowA("x32dbg", 0) || sub_10001DA0(L"OllyDbg.exe") || sub_10001DA0(L"x32dbg.exe") )
ExitProcess(0);
if ( dword_10018FD4 == 1 || v1 != 41 )
{
sub_10003997("\nOops! Did you forget anything?\n");
sub_10003997("That is a wrong flag! Try again!!1\n");
}
else
{
for ( i = 0; i < 36; i += 6 )
{
if ( v21[i - 1] == *((_BYTE *)&v12[-1] + i) )
++v0;
if ( v21[i] == *((_BYTE *)&v11 + i + 1) )
++v0;
if ( v21[i + 1] == *((_BYTE *)&v11 + i + 2) )
++v0;
if ( v21[i + 2] == *((_BYTE *)&v11 + i + 3) )
++v0;
if ( v21[i + 3] == *((_BYTE *)v12 + i) )
++v0;
if ( v21[i + 4] == *((_BYTE *)v12 + i + 1) )
++v0;
}
if ( v0 == 36 )
{
sub_10003997("\nGreat Flag!\n");
sub_10003997("Congratulations!\n");
}
}
}
sub_10003997("\n");
system("pause");
if ( v15 >= 0x10 )
j__free(v13[0]);
v15 = 15;
v14 = 0;
LOBYTE(v13[0]) = 0;
if ( v18 >= 0x10 )
j__free(v16);
return 1;
}
Đoạn này sẽ check len của input
LABEL_6:
print("Checking...\n");
Sleep(0x3E8u);
strncpy_s(Destination, 0x104u, Str, 0x24u);
if ( !strstr(Str, "@") )
goto FAIl;
v3 = strrchr(Str, 64);
strncpy_s(v22, 0x104u, v3, 5u);
v4 = Str;
if ( dword_10018FD4 != 1 )
v4 = Destination;
sub_10001EC0(v4, &v19);
sub_100017A0(v16, "QDIwMjI=", 8u);
v5 = sub_10001430(v10);
sub_100023E0(v13, v5);
if ( v12[13] >= 0x10u )
j__free(v12[8]);
v6 = v13;
if ( v15 >= 0x10 )
v6 = v13[0];
v7 = strcmp(v22, v6);
if ( v7 )
v7 = v7 < 0 ? -1 : 1;
if ( v7 )
{
FAIl:
print("Oh no! That is a wrong flag! Try again!!1\n");
Đoạn check này chương trình sẽ lấy 36 kí tự đầu và lưu vào v4, còn 5 kí tự cuối, 5 kí tự cuối sẽ được cmp
với b64decode của QDIwMjI=
:
36 kí tự đầu sẽ được xử lí qua hàm sub_10001EC0
:
int __fastcall sub_10001EC0(const char *a1, _BYTE *a2)
{
unsigned int v4; // eax
_BYTE *v5; // edx
int v6; // esi
unsigned int v7; // ebx
v4 = strlen(a1);
if ( v4 )
{
v5 = a2;
v6 = a1 - a2;
v7 = v4;
do
{
*v5 = (v5[v6] ^ 0x11) + 11;
++v5;
--v4;
}
while ( v4 );
a2[v7] = 0;
return 1;
}
else
{
*a2 = 0;
return 1;
}
}
Cụ thể thì hàm này chỉ là xor
từng kí tự input với lại 0x11 và cộng thêm 11
Tại dòng 119, ta sẽ thấy đoạn check 36 kí tự đầu:
for ( i = 0; i < 36; i += 6 )
{
if ( v20[i - 1] == *(&v12[-1] + i) )
++v0;
if ( v20[i] == *(&v11 + i + 1) )
++v0;
if ( v20[i + 1] == *(&v11 + i + 2) )
++v0;
if ( v20[i + 2] == *(&v11 + i + 3) )
++v0;
if ( v20[i + 3] == *(v12 + i) )
++v0;
if ( v20[i + 4] == *(v12 + i + 1) )
++v0;
}
Sau khi mình xem trên stack thì mình v11
nằm ngay trước v12
nên là khi viết script mình sẽ gộp 2 bytes này chung:
x= [0x70,0x83,0x84,0x51,0x70,0x30,0x64,0x2D,0x2C,0x4D,0x2B,0x2B,0x2D,0x72,0x2B,0x68,0x82,0x83,0x68,0x30,0x6F,0x2C,0x53,0x7F,0x88,0x88,0x2B,0x51,0x7F,0x87,0x2D,0x4E,0x6E,0x2D,0x5E,0x87]
for i in range(0,len(x),4):
t = x[i:i+4][::-1]
for c in t:
print(chr((c-11)^0x11),end = "") #Whit3H4t11S0L1v34LifeY0uW1llR3memB3r
Flag: WhiteHat{Whit3H4t11S0L1v34LifeY0uW1llR3memB3r@2022}
re03-startr3 - 32pts #
Bài này thì là bài free flag nên là, mở bằng ida64 thấy luôn flag:
Flag: WhiteHat{start_r3_ez_game}
re04-Baby RE - 128pts #
Đề cho mình 1 file exe như này:
Nhìn icon nên mìn chắc chắn là ông ra đề dùng pyinstaller luôn:)), ngay lập tức mình đi tìm tools để decompile ra:
Đầu tiên mình dùng Pyinstxtractor để extract file này ra, sau khi extract nó sẽ trông như này:
Tiếp tục mình dùng Uncompyle6 để uncompyle file quewridg.pyc
ra thành code python:
import base64, os, time
str1 = []
str2 = []
k = None
h = None
def re():
global h
global k
s = 'VOhEdHV0YIRVVLF0S9'
x = '92Mp5GXI5XV79DMO1F'
for i in range(len(s)):
if i % 2 != 0:
str1.append(s[i])
str2.append(x[i])
else:
str1.append(x[i])
str2.append(s[i])
k = ''.join(str1)
h = ''.join(str2)
def write_1():
with open(os.environ['USERPROFILE'] + str(base64.b64decode('XEFwcERhdGFcTG9jYWxcVGVtcFw='), 'utf-8') + k + str(base64.b64decode('LnR4dA=='), 'utf-8'), 'w') as (f):
f.write('YmFuIGNvIHRoYXkgY29uIGJhY2ggdHVvYyBrZXUga2hvbmc=')
with open(os.environ['USERPROFILE'] + str(base64.b64decode('XEFwcERhdGFcUm9hbWluZ1w='), 'utf-8') + h + str(base64.b64decode('LnR4dA=='), 'utf-8'), 'w') as (f):
f.write('dGltIHRodSB4ZW0=')
def content():
banner = ".__ __. __ ______ ___ .___________.____ _ _ .___ ___. \n| \\ | | /_ | / | / _ \\ | |___ \\ | || | | \\/ | \n| \\| | | | | ,----'| | | | `---| |----` __) | | || |_ | \\ / | \n| . ` | | | | | | | | | | | |__ < |__ _| | |\\/| | \n| |\\ | | | | `----.| |_| | | | ___) | | | | | | | \n|__| \\__| |_| \\______| \\___/ |__| |____/ |_| |__| |__|"
print(banner)
print('=======================================================================================')
print(' https://www.youtube.com/shorts/t1u-h4rlNSY ')
print('=======================================================================================')
time.sleep(5)
if __name__ == '__main__':
content()
re()
write_1()
Sau khi chuyển base64 thành ascii, mình thấy là khi chạy file lên, nó sẽ tạo ra 2 tệp với nội 2 nội dung:
ban co thay con bach tuoc keu khong
tim thu xem
Và mình để ý là tên của 2 cái file kia cũng là base64:
def re():
global h
global k
s = 'VOhEdHV0YIRVVLF0S9'
x = '92Mp5GXI5XV79DMO1F'
for i in range(len(s)):
if i % 2 != 0:
str1.append(s[i])
str2.append(x[i])
else:
str1.append(x[i])
str2.append(s[i])
k = ''.join(str1)
h = ''.join(str2)
print(base64.b64decode(h+k+"=").decode())
re() #WhiteHat{T1NH_N0NG_NHU_K3M}
Flag: WhiteHat{T1NH_N0NG_NHU_K3M}
Trong lúc làm bài này nóng thiệt=)), vì rating bài này 1* nên mình cũng không nói gì thêm, next thôi=))
re05-Lucky Ticket - 64pts #
Find the password of the mystery box
nc 164.92.81.231 9012
Sau khi mình chạy file thì nó dừng luôn, thử đưa vào IDA:
Ý của bài này là mình có 2 lựa chọn 1: Lucky Ticket
,2: Mystery Box 600$
, Sau khi kiếm đủ 600$ bằng việc đoán chữ số thì mình sẽ được mở Mystery Box
:
Đặt breakpoint tại đây và setup debug thôi:)
Tại đây sẽ có lệnh nhảy có điều kiện jnz
(jump if not zero)
Mình muốn nhảy vào thì chỉnh lại ZeroFlag = 0
:
Tới đây các bạn chọn option 2 luôn:
Còn đây sẽ là đoạn so sánh số tiền hiện tại với 599, nếu lớn hơn thì sẽ nhảy vào chổ mở box, muốn pass qua lệnh này, mình cần chỉnh OF = SF
:
__int64 __fastcall open(int a1)
{
__int64 result; // rax
_BOOL4 v2; // [rsp+14h] [rbp-9Ch]
int v3; // [rsp+18h] [rbp-98h]
int v4; // [rsp+1Ch] [rbp-94h]
int v5[34]; // [rsp+20h] [rbp-90h] BYREF
unsigned __int64 v6; // [rsp+A8h] [rbp-8h]
v6 = __readfsqword(0x28u);
v3 = 3 * a + 5;
for ( i = 0; i <= 9; ++i )
{
v5[i] = (int)(a * keypublic[i] + a1) % v3;
printf("%d\n", keypublic[i]);
}
puts("-----------------------------");
puts("\nYour key : ");
for ( i = 0; i <= 9; ++i )
{
__isoc99_scanf("%2d", &v5[i + 12]);
putchar(10);
}
v4 = module_reverse((unsigned int)a);
v2 = 0;
for ( i = 0; i <= 9; ++i )
v5[i + 24] = v4 * (v5[i + 12] - a1) % v3;
for ( i = 0; i <= 9; ++i )
v2 = v5[i + 24] == keypublic[i];
if ( v2 )
{
printf("\tCongratulate!!!!");
printf("\nYour password : ");
for ( i = 0; ; ++i )
{
result = (unsigned int)i;
if ( i > 9 )
break;
printf("%d", (unsigned int)v5[i]);
}
}
else
{
printf("Key not true");
return 0LL;
}
return result;
}
Hàm này trước khi in ra password thì cần bạn nhập key vào, phân tích 1 chút hàm này sẽ hoạt đông như sau:
9 kí tự đầu của v5
sẽ lưu 1 dãy số gì đó:
v5[i] = (int)(a * keypublic[i] + a1) % v3;
9 kí tự ở giữa sẽ lưu key các bạn nhập vào:
for ( i = 0; i <= 9; ++i )
{
__isoc99_scanf("%2d", &v5[i + 12]);
putchar(10);
}
9 kí tự ở cuối sẽ là nơi chứa key sau khi mã hóa, và được so sánh với public key có sẵn:
for ( i = 0; i <= 9; ++i )
v5[i + 24] = v4 * (v5[i + 12] - a1) % v3;
for ( i = 0; i <= 9; ++i )
v2 = v5[i + 24] == keypublic[i];
Nếu đúng hết thì nó sẽ in password ra, mà password lại là 9 kí tự đầu của v5 =)))
Nên là khúc này mình chỉ cần chạy hết đoạn này, xong lấy pass ra thôi:))
for ( i = 0; i <= 9; ++i )
{
v5[i] = (int)(a * keypublic[i] + a1) % v3;
printf("%d\n", keypublic[i]);
}
Lấy 9 số đầu chuyển thành decimal và nối lại thì mình được password: 76725167175623
Lúc đầu mình nhập vào thì không đc, sau khi ib hỏi admin và thảo luận 1 hồi lâu thì admin mới sửa lại và có đc flag, rồi tới đây mìnht thấy cái netcat nó cứ sao sao, không biết nó giúp gì trong trường hợp này =))
Nhập pass và get flag:
Flag: Whitehat{I_n33d_v1t4m1n_s34}
re07-flagcheck - 64pts #
Sau khi mình enter thì nó mất tiêu luôn
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *v3; // rax
char Buffer[48]; // [rsp+20h] [rbp-60h] BYREF
char cipher[44]; // [rsp+50h] [rbp-30h] BYREF
unsigned int i; // [rsp+7Ch] [rbp-4h]
_main();
qmemcpy(cipher, "Vjjp`Nf|roqSua}Ow}aKg%H{q{wpxpxE~mLTX", 37);
printf("Input flag: ");
v3 = __iob_func();
fgets(Buffer, 38, v3);
for ( i = 0; i <= 0x24; ++i )
Buffer[i] ^= (_BYTE)i + 1;
for ( i = 0; i <= 0x24; ++i )
{
if ( Buffer[i] != cipher[i] )
{
puts("Incorrect flag!");
return 0;
}
}
puts("\nCongratulation! You have flag.");
return 1;
}
Bài này khá cơ bản, sau khi nhập input thì nó sẽ lấy input của mình xor
với lại index của kí tự đó + 1, tới đây thì không nói nhiều nữa viết script luôn:
t = "Vjjp`Nf|roqSua}Ow}aKg%H{q{wpxpxE~mLTX"
for i in range(len(t)):
print(chr((i+1)^ord(t[i])),end = "") #WhiteHat{ez_xor_for_r3_challenge_Oop}
Flag: WhiteHat{ez_xor_for_r3_challenge_Oop}