Pwn

Jailer

jailbreak challenge where the flag is hidden in an unusual file descriptor rather than a standard location.

A slice of lemon PIE

A simple pwn challenge with a format string vulnerability.

Reverse Engineering

Virtual Girlfriend

A reverse Engineering challenge involving assembly.

Phantom Resolver

A simple challenge involving decryption of a encrypted string.

A Slice Of Lemon Pie

Let’s run checksec on the binary and see what protections it has.

quix@quixel:~$ checksec --file=format_pie
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified       Fortifiable     FILE
Partial RELRO   Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   48 Symbols        No    0               2               format_pie
  • PIE,NX and canary are all enabled.
  • Partial RELRO means that we can overwrite a GOT entry.

We can also see that the binary contains a win function that spawns a shell for us:

[Read more]

Jailer

Let’s decompile the binary and see what it does

   sub_1280(a1, a2, a3);
    if ( !(unsigned int)sub_13A0() )
      return system(a2[1]);

It seems to expect a command line argument, if provided it calls sub_13A0() to ‘check’ the input and calls system on our input.

Now you can just run cat flag.txt and it will print the flag locally. But let’s dig a bit deeper.

__int64 sub_13A0()
{
  int v0; // ebp
  int v1; // ebx
  v0 = sub_12E0();
  v1 = open("flag.txt", 0);
  if ( v1 < 0 )
  {
    v1 = open("/flag.txt", 0);
    if ( v1 < 0 )
      return 0xFFFFFFFFLL;
  }
  dup2(v1, v0);
  close(v1);
  return 0;
}

This seems to open the flag, v0 is calculated in sub_12E0. The file descriptor for the flag is in v1 which then gets closed after a dup2 call. dup2 is used to duplicate the file descriptor.

[Read more]

Virtual girlfriend

We have been given a main.s file, written in AT&T syntax… (or as I like to call it, the wrong syntax). Our goal is to find out the return value of the program.

The main concept of this challenge is that it has some infinite loops and dead code that prevents you from executing it normally.

 label1:
    push rbp
    mov rbp, rsp
    call label2
    call label3
    jmp label4
    pop rbp
    ret
...
 label4:
    jmp label4 
  • After calling label2 and label3, there is a jmp label4
  • label4 calls jmp label4, creating an infinite loop.
  • The solution is to remove lavel4 completely.

Inside label3,

[Read more]

Phantom Resolver

The challenge provides us with 2 binary files:

  • server_daemon
  • libmonitor.so

Looking at the server daemon decompilation:

int __fastcall main(int argc, const char **argv, const char **envp)
{
  const char **v3; // rbx

  print_banner(argc, argv, envp);
  printf("\n[*] Starting daemon in ");
  if ( argc <= 1 )
  {
LABEL_7:
    puts("INTERACTIVE mode");
    puts("[!] Warning: daemon mode not enabled");
    puts("[!] Use --daemon flag for production deployment");
  }
  else
  {
    v3 = argv + 1;
    while ( strcmp(*v3, "--daemon") )
    {
      if ( ++v3 == &argv[(unsigned int)(argc - 2) + 2] )
        goto LABEL_7;
    }
    puts("DAEMON mode");
  }
  putchar(10);
  initialize_subsystems();
  puts("\n[*] Running system integrity check...");
  system_check();
  puts("\n[*] Daemon initialization complete");
  return 0;
}

We can see that it prints some lines and then calls system_check(), looking at system check:

[Read more]