Trojan Logo
Trojan
Trojan Logo
Trojan
Become a memberContactCTF Teams
CTF Teams
Resources & Topics
Topics

PicoCTF challenges:

Reverse engineering (Rev) is the art figuring out how a system 'works'. Often you have little to work with, sometimes only a binary file, datasheet or user interface. Rev is one of the most crucial steps when attacking a device/server/program. You can only craft a succesfull attack when you understand the system. In many CTF categories Rev is an implicit step in the challenge (Web & Binary exploitation, etc.). However it is also often a seperate categorie that focusses mostly on reverse engineering binary code.

PicoCTF challenges:

Exercises for practicing GDB:

Binary exploitation challenges introduces us to the wonderfull world of low level memory shenanigans and other forms of manipulation. Most exercises will revolve around attacks on insecure C code, however you may also encounter other langauges. For this training we will use challenges from PicoCTF.

PicoCTF challenges:

For this training we will use challenges from Sofia Santos and Cipherstick. Sofia Santos has a great repository of image based OSINT challenges on her website. Each exercise also has writeups (video and written) that explain how to solve the exercise. This site is a great starting point if you are new to OSINT, however they also offer exercises for more experienced people.

Sofia Santos challenges:

For the Cipherstick challenges we will need to find missing persons. Each challenge has many smaller sub challenges that incrementally lead to solving the mystery.

Cipherstick challenges:

For today's training session we will use PicoCTF. This platform provides a lot of interesting challenges on various different topics, for both beginners and experienced people. To view the exercises and submit flags you will need to create an account.

PicoCTF exercises:

Useful Tools

Reverse engineering binaries

In general you can follow these steps when analyzing binary files:

  1. Static analysis: use a decompiler and try to answer these questions:

    • What language was the software written in?
    • What libraries does it use?
    • Does it interact with any other systems?
  2. Dynamic analysis: use a debugger and try to answer these questions:

    • How does the system behave?
    • Which parts of the sytem can the user interact with?
    • Is there any strange behaviour on malformed or unexpected inputs?
  3. Platform specific analysis: use tools that are specifically designed to analyze software build for that platform (i.e. Java decompiler if our binary was written in Java).

Tools:

Youtube guides/tutorials:

Example Rev challenge walkthroughs

There are many usefull tools and techniques for solving binary exploitation challenges. In general you can follow the following steps to attack programs:

  1. What language was the program written in, what tools do I need?
  2. How does the program work? (try some inputs)
  3. How is it implemented? Does anything interesting show up? (Decompile binary)
  4. Does the program make any assumptions on the user input that I can exploit? Are there errors on weird input? (Use a debugger to investigate what it is doing)
  5. Exploit :)

Small list of tools:

Tutorials and guides:

Low level memory in C

Program memory layout:

Addr.
0000 +---------------+
     |               |
     |     .txt      |  executable code
     |               |
     +---------------+
     |     .data     |  initialized data
     +---------------+
     |     .bss      |  uninitialized data
     +---------------+
     |               |  |
     |      Heap     |  | grows to larger
     |               |  | addresses
     +---------------+  V
     | unused memory |
     +---------------+  A
     |               |  | grows to lower
     |     Stack     |  | addresses
     |               |  |
1024 +---------------+

Size known at compilation time:
- .txt, .data, .bss

Dynamically grows:
- Heap, unused memory, Stack

Stack layout:

#----------------
# PROGRAM
#----------------

void hello(int n) {
  // Do something cool
}

void greet() {
  hello(5); // say hello 5 times
}

int main() {
  greet();
  return 0;
}

#----------------
# Stack
#----------------

Addr.
XXXX +---------------+
     |               |
     | unused memory |
     |               |
     + - - - - - - - +  A
     |     Hello     |  |
     + - - - - - - - +  | Stack grows up
     |     Greet     |  | 
     + - - - - - - - +  | 
     |     Main      |  |
1024 +---------------+

The stack consists of frames "stacked" on top of eachother. Each frame corresponds to function call and contains all the necessary information to excute that function (arguments, local variables and control flow data). The frame on top of the stack corresponds to the function that is currently being executed. When a function returns its frame is removed from the stack. For example in the program shown above we have the following steps:

  1. Main is called, frame main added to stack.
  2. Main calls Greet, frame greet added to stack.
  3. Greet call Hello, frame hello added to stack.
  4. Hello returns, frame hello removed, greet frame is on top.
  5. Greet returns, frame greet is removed.

Frame layout:

Registers in the CPU:
- PC: Program Counter
- SP: Stack pointer
- BP: Base pointer

#----------------
# PROGRAM
#----------------

int test(int a, int b) {
  int c = 5;
  int d = 18;
  return a + b + c + d;
}

#----------------
# FRAME
#----------------

 Address    Test Frame
           +-----------+
[ebp - 8]  |     d     | <-- SP
           + - - - - - +
[ebp - 4]  |     c     | 1st local variable
           + - - - - - +
[  ebp  ]  |   oldBP   | <-- BP
           + - - - - - +
[ebp + 8]  |return addr|
           + - - - - - +
[ebp + 12] |     a     | 1st argument
           + - - - - - +
[ebp + 16] |     b     | 2nd argument
           +-----------+
  • The Program Counter points to the next instruction that we will execute (.txt section of memory).
  • The Stack Pointer points to the top of the stack.
  • The Base Pointer points to the center of the highest frame.

When Test returns SP, BP and PC will be updated:

  • SP --> Points to top of the frame below Test Frame
  • BP --> Set to oldBP (points to center of frame below Test Frame)
  • PC --> Set to the return address (instruction in function that called test).

Open Source Intelligence (OSINT) is a subset of "Intelligence", which only uses public sources to gather, evaluate and assess information about a target. In the context of CTFs this means that you need to use the internet itself to solve challenges. Typically tools like google maps and reverse image search prove to be very useful.

There are many guides and tools online on various web attacks. Below we have compiled a small list of youtube playlists related to this topic. Hexdumps playlist is more educational in nature, while CTF School & LiveOverflows playlists lean a bit more towards the "entertaining side".

We highly recommend that you have access to a Linux OS when solving CTF challenges. Many tools are only supported on Linux (and sometimes Mac). There are a lot of different distros (Linux versions) that you can choose from. Some come preinstalled with many useful tools for CTFs, like for example Kali or ParrotOS. However a more "general purpose" OS like Ubuntu also works perfectly fine.

Installation options: