Skip to content

Reverse

Pedro Adão edited this page Nov 5, 2018 · 2 revisions

Reverse Engineering Lab

For this lab we propose a series of simple reverse engineering exercises 1_basic to 6_problem.

The goal of this session is to analyse a few challenges and make you confortable with using reverse engineering tools, in particular disassemblers.

Setup

  • Download and install Cutter. Go to the folder you want to have it and run

      wget https://github.com/radareorg/cutter/releases/download/v1.7.2/Cutter-v1.7.2-x86_64.Linux.AppImage
      chmod +x Cutter-v1.7.2-x86_64.Linux.AppImage
    
  • Run for the filename you want to analyse

      ./Cutter-v1.7.2-x86_64.Linux.AppImage <filename>
    

Problem 0x1 - Basic comparison

Goal: Basic introduction to a disassembler

  • Understand how a basic binary looks like in assembly using a graph view of a disassembler.

Method:

  1. Run and interact with the binary

    • If you're sure it's not malware of course ;)
    • Can you get any information?
    • How can you determine what's the key? Let's open the binary in a disassembler.
  2. Open the binary in a disassembler and try to understand the assembly (gdb is NOT a disassembler; try Cutter).

    • Go to the main function and press <SPACE> to open the graph view.
    • Can you understand what is happening? Focus on the calls, and for now try to ignore the assembly between them.
    • Find out how the key is being compared with your input.
    • Easy, right?
    • Was there other ways to do this outside of Cutter?

Problem 0x2 - Not so basic anymore

Goal: Practice what you learned in the first challenge.

Method:

  1. Interact (as before)

    • Can you get any information?
    • Can you do your magic again? It doesn't work?
    • You might have to learn new tricks ;-)
  2. Try again with a dissassembler

    • Does something jump to your attention?
    • Go on. Follow your path.

Problem 0x3 - It is just there

Goals: Keep practicing. Learn a bit more how assembly and function calls work.

  • Understand that functions return on the rax register (specifically for atoi in this binary).
  • Understand the cmp instruction.

Method:

  1. Interact (as before) to get some information.

  2. Open it in a dissassembler

    • Determine what is being compared now.
    • Is it still a string like in he previous challenge? or is it something else?
    • Do not reverse the gen_flag function. It misses the point of the challenge.

Problem 0x4 - Dynamic Analysis

Goals: Basic introduction to dynamic analysis

  • Matching strings are generated at runtime.
  • Using a debugger to see values after they have been computed.

Method:

  1. Interact (as before) to get some information.

  2. Open it in a dissassembler

    • What is difference now?
    • Sometimes you can use a more dynamic approach instead of a static one as before.
    • Try to use gdb to better understand what is happening at the crutial moment.
    • You can reverse the gen_flag function but it misses again the point of the challenge.

Problem 0x5 - Bypassing anti-debugging techniques

Goal: Learn how to patch binaries and bypass anti-debugging techniques.

Method:

  1. Interact (as before) to get some information.

  2. Open it in a dissassembler.

    • Is everything equal to the previous challenge? What happens when you try to use gdb to debug the binary?
    • Have you tried ltrace?
    • Well, Google search ptrace anti-debugging.
    • You have to remove the anti-debugging technique.
      • Make a copy of the orginal binary before patching it!
      • If you right click over an instruction in Cutter you can convert it to nops under Edit. If you don't know what a nop is, google x86 instruction nop.

@NOTE

  • Open the binary in write mode to ensure the patches you want are applied. If debugging is still not working afterwards, reopen the file and ensure that you indeed wrote what you intended. Cutter can be a bit buggy sometimes.

Problem 0x6 - Everything changes at runtime

Goal: Statically reverse a more 'complex' function

Method:

  1. Interact (as before) to get some information.

  2. Open it in a dissassembler.

    • How is the flag being checked?
    • This time a dynamic approach would be harder as the check function returns as soon as a single character is wrong. If you want to try it this way look at how to script the radare2 debugger with r2pipe.
    • An easier solution is to reverse the check_flag function.
  3. Reversing the check_flag function statically:

    • Understand the function in general. Where is the loop?
    • Understand what is happening before the loop..
    • Now to the fun part! The loop...
      • understand the typical loop variables;
      • identify the i and the stop condition(s);
      • in Cutter you can rename the variables by clicking Shift+n over a variable.
    • When you understand what is happening you can write a C or python script that implements the inverse function of check_flag.