Introduction to Cutter

Introduction to Cutter

Cutter is a Graphical User Interface (GUI) built around the long-lived radare2 disassembler. The largest problem with radare2 is it’s usability. Whilst radare is efficient to use once mastered, it has many problems for first time users. Running pdf to ‘print disassembled function’ or aaa to analyze and auto-name all functions might seem intuitive to long time users but the tools overall lack of user-friendly guides has seen stunted usage growth.

Cutter has succeeded in porting radare’s fantastic capability into a graphical interface that can compete with the likes of Hopper, IDA, BinaryNinja and Ghidra all while remaining completely free. It also has the added benefit of being multi-platform.

The General Interface

Opening a Binary

When Cutter first launches up you are presented with the below menu that provides a short history of previously opened files, as well as a way to select files from disk.

cyber security companies | it security services | penetration testing | managed security service provider

Analysis level

In radare2, there are different analysis levels that can be appropriate for different circumstances. Since most CTF binaries are usually relatively small, the default option works fine.

Getting a graph view

Once inside the Cutter project view, the differing panes allow you to see quickly the different parts of the code, and all panes can be resized, moved or closed at will. One of these views in particular, the graph view, is very reminiscent of BinaryNinja and contains the logical flow of the program. When clicking through the different functions in the functions panel the hexdump, dissassembly, decompiler and graph view will all be updated in real time. My personal favourite when trying to figure out different sections of the code is to have the functions on the left, graph view in the middle and Decompiler on the right.

cyber security companies | it security services | penetration testing | managed security service provider

Completing a basic PicoCTF Challenge

To show the basic functionality and usage of the tool I will quickly run through a picoCTF reversing challenge from 2018 titled “be quick or be dead 1”.

Executing the binary

The first step is to investigate the binary to see what file type it is, and then execute it.

cyber security companies | it security services | penetration testing | managed security service provider

Since this is an ELF binary I can run it in my linux environment after giving it the executable flag with chmod +x be-quick-or-be-dead.

cyber security companies | it security services | penetration testing | managed security service provider

Opening it with Cutter

Now that we know the binary has some sort of check preventing us from receiving the flag, we can open it up with cutter.

When opening it I use the default analysis level.

cyber security companies | it security services | penetration testing | managed security service provider

Once cutter is open we are greeted with a lot of information. From this default view we can quickly see some functionality that would be useful. On the left side of the screen we can see all the defined functions in the binary, such as main and print_flag. In the center we can see some useful information about the binary, such that it is an ELF binary. At the bottom we can see the different tab views available to use for analysing the binary.

cyber security companies | it security services | penetration testing | managed security service provider

Analysing the function calls

The first thing we want to is analyse the main function. We can access the main function in the graph view simply by double clicking the main function in the function listing panel. This reveals the graph view of the main function, normally the graph view would show different branches but the main function simply calls four different functions then exits.

cyber security companies | it security services | penetration testing | managed security service provider

We can see the four different functions, and we can jump to each of their definitions by double clicking them.

cyber security companies | it security services | penetration testing | managed security service provider

In this case I clicked the print flag function since it seems like the obvious choice.

cyber security companies | it security services | penetration testing | managed security service provider

Unfortunately we notice that there is a decrypt_flag function that is run, which probably relates to the main functions invocation of get_key. Since this function has no checks that would cause the binary to fail I decide to take a different approach. When the binary initially ran it printed a message saying that a faster machine was needed, so I decided to look at the strings and see if I could locate the message.

cyber security companies | it security services | penetration testing | managed security service provider

This turned out to be a good choice as we can located the string and it’s address very easily.

By pressing x while highlighting this string, or right-clicking and choosing show X-refs (cross-references) we can see were this string is used in the code. In this case, it is used in a mov instruction in the alarm_handler function.

cyber security companies | it security services | penetration testing | managed security service provider

cyber security companies | it security services | penetration testing | managed security service provider

cyber security companies | it security services | penetration testing | managed security service provider

Looking at this function we can see that it calls puts on our string, and then immediately exits. We can find where this function is referenced by going to the functions panel on the left and pressing x again, or right-clicking and choosing show X-refs. This will lead us closer to our culprit. In this case we can see that the function is only referenced in the set_timer function.

We can now try to understand the functionality of the set timer function to figure out why our program ends abruptly. We can also see cutters branching come into play in this function as it uses a jne (Jump if not equal) instruction to see if an error code is raised after calling __sysv_signal.

cyber security companies | it security services | penetration testing | managed security service provider

cyber security companies | it security services | penetration testing | managed security service provider

Now that we have found our culprit function, we can look into how exactly it works. A useful tool when trying to figure out the functionality of some machine code is a decompiler. Cutter actually comes with a C++ rewrite of the Ghidra decompiler, as well as it’s own retdec. We can enable this decompiler view by going to the top bar and clicking Windows -> Decompiler.

cyber security companies | it security services | penetration testing | managed security service provider

cyber security companies | it security services | penetration testing | managed security service provider

This decompiler view allows us to more readily understand the set_timer function.

We cab see that the function has two significant system calls, one to __sysv_signal and the other to alarm. To understand these functions I like to use man pages.

The two pages I used for this analysis are:

From this I was able to infer three important pieces of information.

__sysv_signal is used to set a function to be called when a specific signal is sent inside the binary.

0xe, or 14, refers to SIGALRM.

alarm will send SIGALRM after a given number of seconds.

So in this case the function will:

  • Set alarm_handler to run when the binary sends SIGALRM
  • Set the binary to send SIGALRM after 1 second.

So by removing the call to alarm from the binary, alarm_handler should never be hit and the binary should finish running as expected.

Patching the binary with NOPs

When patching the binary it is important to remember that you are changing the binary on disk, and that it is wise to create copies of the binary in it’s original state. What we want to do in this case is change the call to alarm to a NOP (No Operation) instruction so that the binary will not terminate prematurely. We can do this by right clicking the call to alarm in either the disassembly, graph or decompiler view and choosing Edit -> Nop Instruction. I personally recommend doing this through the graph or disassembly view to ensure the correct instruction is NOP’d.

cyber security companies | it security services | penetration testing | managed security service provider

Getting the flag

Now that alarm is never being called, we can shut down cutter and run the binary and we should get the flag.

There are definitely a couple other ways we could have done solved this challenge and some unanswered questions.

  • Why was the binary taking so long to run?
  • What happens if we NOP the call to set_alarm?
  • Can we use a debugger to ignore SIGALRM? (GDB will do this by default).

All in all Cutter is a solid tool that is built on a well maintained project and it should see continual improvements into the future.

More Blogs

May 31, 2021

Upgrading from AppLocker to Windows Defender Application Control (WDAC)

Windows Defender Application Control (WDAC), formerly known as Device Guard, is a Microsoft Windows secure feature that restricts executable code, including scripts run by enlightened Windows script hosts, to those that conform to the device code integrity policy. WDAC prevents the execution, loading and running of unwanted or malicious code, drivers and scripts. WDAC also… Continue reading Upgrading from AppLocker to Windows Defender Application Control (WDAC)

Read More
cyber security companies | penetration testing | managed security service provider | cyber security consultant
June 22, 2021

Bypassing LSA Protection (aka Protected Process Light) without Mimikatz on Windows 10

Starting with Windows 8.1 (and Server 2012 R2) Microsoft introduced a feature termed LSA Protection. This feature is based on the Protected Process Light (PPL) technology which is a defense-in-depth security feature that is designed to “prevent non-administrative non-PPL processes from accessing or tampering with code and data in a PPL process via open process… Continue reading Bypassing LSA Protection (aka Protected Process Light) without Mimikatz on Windows 10

Read More
cyber security companies | penetration testing | managed security service provider | cyber security consultant
June 7, 2020

Using Zeek to detect exploitation of Citrix CVE-2019-19781

Using the tool Zeek, formally known as bro, is a high-level packet analysis program. It originally began development in the 1990s and has a long history. It does not directly intercept or modify traffic, rather it passively observes it and creates high-level network logs. It can be used in conjunction with a SIEM to allow… Continue reading Using Zeek to detect exploitation of Citrix CVE-2019-19781

Read More