Skip to content

Back to the catalog

0xv1n.github.iowriteup

Reversing ELFs on TryHackMe: Part 2

Part 2 of a TryHackMe ELF reversing series that solves two crackme challenges: Crackme5 uses ltrace to observe strcmp/strlen library calls and leak the plaintext password directly from traced output, while Crackme6 uses Binary Ninja's graph and pseudo-C views to trace a compare_pwd/my_secure_test function, reconstruct byte-by-byte hex comparisons, and convert them to ASCII to recover the password. It's a beginner-oriented walkthrough demonstrating basic static/dynamic binary analysis workflow and tooling (ltrace, Binary Ninja, mov/test/je instruction reading).

TL;DR Beginner TryHackMe crackme writeup using ltrace and Binary Ninja to extract hardcoded passwords from ELF binaries.
Document

What it is

A TryHackMe writeup solving two ELF crackme challenges (Crackme5 and Crackme6) using library-call tracing and static analysis in a GUI decompiler. It demonstrates two concrete techniques the summary doesn't name: recovering a password via ltrace, and reconstructing a password byte-by-byte from a decompiler's pseudo-C output. Screenshots use Binary Ninja, but the author notes Ghidra and IDA Pro offer equivalent graph/pseudo-C views.

How it works

Crackme5 (ltrace): Running the binary under ltrace exposes its library calls, including the strcmp that reveals the plaintext password directly. As a side observation, strlen(<input>) is called input.length() + 1 times — a behavioral tell useful for inferring program logic, though not needed to solve this one.

Crackme6 (static analysis): The main function branches into a usage message or a compare_pwd call depending on argument passing. compare_pwd calls my_secure_test, which validates the input string one character at a time against hardcoded byte values. The author traces mov/movzx/test al, al to confirm var_10 holds the user input, then switches to the Pseudo-C view to read off each comparison constant per index. Failing a character comparison loads 0xffffffff into eax and returns nonzero.

What to do

For Crackme5, the fast path is:

ltrace ./<binary> test

Read the password out of the strcmp argument.

For Crackme6, the required password bytes extracted from the per-character comparisons are:

0x31 0x33 0x33 0x37 0x5f 0x70 0x77 0x64 0x00

That is the 9-byte string (8 chars + null terminator) 1337_pwd. Feed it as the program argument.

Preconditions

  • The binaries must be run/analyzed in a segmented environment. The author explicitly warns never to execute unknown ELF/PE files on your workstation, even from trusted sources like THM or HTB; they used a disposable Kali VM.
  • ltrace only helps here because the check routes through a traceable library call (strcmp); a binary using inlined or custom comparison logic (as Crackme6 does with my_secure_test) would not leak the answer this way — hence the pivot to static analysis.

Caveats

The ltrace approach works only against binaries that compare via observable library functions. Crackme6's character-by-character custom check is exactly the case ltrace won't shortcut, which is why the writeup switches tools. The post appears truncated mid-sentence at the final byte-string derivation.

Technologies named here

Techniques named here

  • Dynamic analysis via library call tracing
  • Static analysis via control-flow graph review
  • Function drilldown
  • Assembly-level instruction analysis
  • Pseudo-C decompilation review
  • Hex-to-ASCII conversion