pwnfreemedium

Evil Corp

hackthebox

64-bit ELF PIE binary, dynamically linked, not stripped. Compiled with GCC 10.2.1 (Debian). Uses wide character API (`fgetws`, `wcscmp`, `wcstol`, `wprintf`) with `en_US.UTF-8` locale. Bilingual interface (English + Chinese).

$ ls tags/ techniques/
mmap_overflow_to_rwxwchar_type_confusionstack_bof_ret2fixedshellcode_encoding_via_wcharnull_byte_via_fgetws

$ cat /etc/rate-limit

Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.

Evil Corp -- HackTheBox

Description

"We turned our assembly tester off because a big mistake from our new C developer. Do you think there are other mistakes he made?"

64-bit ELF PIE binary, dynamically linked, not stripped. Compiled with GCC 10.2.1 (Debian). Uses wide character API (fgetws, wcscmp, wcstol, wprintf) with en_US.UTF-8 locale. Bilingual interface (English + Chinese).

Remote target: 154.57.164.71:31387.

Protections

ProtectionStatus
PIEEnabled (but target is MAP_FIXED address, PIE not relevant)
NXEnabled (but 0x11000 is RWX via mmap)
CanaryNone
RELROPartial

Analysis

Key Functions

Setup()

Sets locale to en_US.UTF-8 and creates two adjacent mmap regions with fixed addresses:

0x10000 (SupportMsg)       — RW,  0x4b0 (1200) bytes — MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS
0x11000 (AssemblyTestPage) — RWX, 0x800 (2048) bytes — MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS (PROT_READ|PROT_WRITE|PROT_EXEC)

Critical point: AssemblyTestPage has execute permissions, and MAP_FIXED means addresses are independent of ASLR.

Login()

  • Hardcoded credentials: eliot / 4007
  • fgetws(username_buf, 30, stdin) -- 30 wchar_t into 32-wchar_t buffer (safe)
  • fgetws(password_buf, 0x12c, stdin) -- 300 wchar_t into 32-wchar_t buffer (OVERFLOW!)
  • password_buf at RSP+0x00, username_buf at RSP+0x80
  • Return address at RSP+0x158 = 86 wchar_t from start of password_buf
  • Stack frame: push rbx; sub rsp, 0x150 (no RBP frame, no canary)

wcharToChar16(src, dst, count)

"Big mistake from the C developer": truncates wchar_t (4 bytes on Linux x86-64) to char16_t (2 bytes), keeping only the lower 16 bits. No bounds checking on destination buffer.

ContactSupport()

...

$ grep --similar

Similar writeups