<style> img[alt=chall-sc] { display: block; margin: 0 auto; width: 100em; } p { text-align: justify; } p::first-line { text-indent: 0; } </style> # Incognito 5.0 Reverse Engineering Writeup (Bahasa Indonesia) ## Vault > Can you get the access? Diberikan sebuah Executable and Linkable Format (ELF) 64-bit yang merupakan program `flag checker`. Langsung saja kita decompile. ### main ```c int __cdecl main(int argc, const char **argv, const char **envp) { const char *v3; // rsi const char *v4; // rax char s1[112]; // [rsp+0h] [rbp-70h] BYREF printf("Enter the secret code: "); __isoc99_scanf("%99s", s1); v3 = (const char *)flag(); if ( !strcmp(s1, v3) ) { puts("Access Granted!"); v4 = (const char *)flag(); puts(v4); } else { puts("Access Denied!"); } return 0; } ``` ### flag ```c _BYTE *flag() { int i; // [rsp+4h] [rbp-4h] for ( i = 0; i < 26; ++i ) flagArray_0[i] = ascii_values_1[i]; flagArray_0[26] = 0; return flagArray_0; } ``` Program ini sangatlah sederhana, input kita akan dibandingkan dengan variabel `flagArray` yang isinya sudah ditentukan. Jadi, kita cukup mengubah `flagArray` tersebut dari bentuk hex ke ascii, dilanjutkan dengan mengubah bentuk ascii tersebut ke string. ![chall-sc](https://hackmd.io/_uploads/SywXvNalC.png) ![chall-sc](https://hackmd.io/_uploads/B1WVDE6gR.png) #### POC ```c #include <stdio.h> int main() { int ascii[] = { 105, 99, 116, 102, 123, 119, 101, 108, 99, 48, 109, 101, 95, 116, 48, 95, 114, 101, 118, 51, 114, 115, 49, 110, 103, 125 }; int len = sizeof(ascii) / sizeof(ascii[0]); char str[len + 1]; for (int i = 0; i < len; i++) { str[i] = (char)ascii[i]; } str[len] = '\0'; printf("%s\n", str); return 0; } ``` ![chall-sc](https://hackmd.io/_uploads/BJhww4plC.png) ## Vault2 > Simply ask the flag ¯_(ツ)_/¯ Diberikan sebuah Executable and Linkable Format (ELF) 64-bit yang merupakan program `flag checker`. Langsung saja kita decompile. ### main ```c int __cdecl main(int argc, const char **argv, const char **envp) { char v4[128]; // [rsp+0h] [rbp-80h] BYREF puts("Enter the flag:"); if ( (unsigned int)__isoc99_scanf("%127s", v4) ) { if ( (unsigned int)checkFlag(v4) ) puts("Congratulations! You've solved the challenge."); else puts("Incorrect flag. Try again!"); } return 0; } ``` ### checkFlag ```c _BOOL8 __fastcall checkFlag(const char *a1) { char dest[128]; // [rsp+10h] [rbp-A0h] BYREF char s2[32]; // [rsp+90h] [rbp-20h] BYREF qmemcpy(s2, "hawb~w6q5dcn0[n2", 16); *(_QWORD *)&s2[15] = 0x7F73357C5C7B32LL; strncpy(dest, a1, 0x80uLL); mysteryFunction(dest); return strncmp(dest, s2, 0x17uLL) == 0; } ``` ### mysteryFunction ```c __int64 __fastcall mysteryFunction(__int64 a1) { __int64 result; // rax int i; // [rsp+14h] [rbp-4h] for ( i = 0; ; ++i ) { result = *(unsigned __int8 *)(i + a1); if ( !(_BYTE)result ) break; *(_BYTE *)(i + a1) ^= (unsigned __int8)(i % 5) + 1; } return result; } ``` Program ini akan mengecek apakah hasil xor antara `input` yang kita berikan dengan `input ke-((i ≡ 5) + 1)` sama dengan `hawbw6q5dcn0[n2{\|5s\x7F`. Jadi, kita cukup melakukan xor string `hawbw6q5dcn0[n2{\|5s\x7F` dengan algoritma tersebut untuk mendapatkan plaintextnya. #### POC ```c #include <stdio.h> #include <string.h> void xor(const char *enc, char *dec) { int len = strlen(enc); for (int i = 0; i < len; i++) { dec[i] = enc[i] ^ (i % 5 + 1); } dec[len] = '\0'; } int main() { const char enc[] = "hawb~w6q5dcn0[n2{\\|5s\x7F"; char dec[sizeof(enc)]; xor(enc, dec); printf("%s\n", dec); return 0; } ``` ![chall-sc](https://hackmd.io/_uploads/ByquvEpe0.png) ## Vault3 > Asking you last time for the flag. Diberikan sebuah Executable and Linkable Format (ELF) 64-bit yang merupakan program `flag checker`. Langsung saja kita decompile. ### main ```c int __cdecl main(int argc, const char **argv, const char **envp) { char v4[128]; // [rsp+0h] [rbp-80h] BYREF puts("Enter the flag:"); if ( (unsigned int)__isoc99_scanf("%127s", v4) ) { if ( (unsigned int)checkFlag(v4) ) puts("Congratulations! You've solved the challenge."); else puts("Incorrect flag. Try again!"); } return 0; } ``` ### checkFlag ```c _BOOL8 __fastcall checkFlag(const char *a1) { char dest[128]; // [rsp+10h] [rbp-A0h] BYREF char s2[16]; // [rsp+90h] [rbp-20h] BYREF __int64 v4; // [rsp+A0h] [rbp-10h] qmemcpy(s2, "leyh{V2z4x#3q^x\"", sizeof(s2)); v4 = 0x7F56305B5D6C77LL; strncpy(dest, a1, 0x80uLL); encrypt(dest); return strncmp(dest, s2, 0x18uLL) == 0; } ``` ### encrypt ```c __int64 __fastcall encrypt(__int64 a1) { __int64 result; // rax int i; // [rsp+14h] [rbp-Ch] for ( i = 0; ; ++i ) { result = *(unsigned __int8 *)(i + a1); if ( !(_BYTE)result ) break; *(_BYTE *)(i + a1) = rotateChar((unsigned int)(char)(*(_BYTE *)(i + a1) ^ (i % 4)), 3LL); } return result; } ``` ### rotateChar ```c __int64 __fastcall rotateChar(char a1, int a2) { if ( a1 > 96 && a1 <= 122 ) return (unsigned int)((a1 - 97 + a2) % 26 + 97); if ( a1 <= 64 || a1 > 90 ) return (unsigned __int8)a1; return (unsigned int)((a1 - 65 + a2) % 26 + 65); } ``` Program ini mirip seperti program sebelumnya, namun kali ini menggunakan algoritma yang lebih kompleks untuk melakukan pengecekan. #### POC ```c #include <stdio.h> int rotchr(char a1, int a2) { if ( a1 > 96 && a1 <= 122 ) return ((a1 - 97 + a2) % 26 + 97); if ( a1 <= 64 || a1 > 90 ) return a1; return ((a1 - 65 + a2) % 26 + 65); } int xor(char *a1) { int res; int i; for (i = 0; a1[i]; ++i) { a1[i] = rotchr(a1[i], -3); a1[i] ^= (i % 4); } a1[i] = 0; return res; } int main(){ char enc[] = "leyh{V2z4x#3q^x\"wl][0V\x7f"; xor(enc); printf("%s\n", enc); return 0; } ``` ![chall-sc](https://hackmd.io/_uploads/SkOKDVpx0.png)