Выбрать главу

So, its a dynamically linked, stripped, 64bit Linux executable - nothing fancy here. Let's try to run it:

[0x00 avatao]$ ./reverse4

?

Size of data: 2623

pamparam

Wrong!

[0x00 avatao]$ "\x01\x00\x00\x00" | ./reverse4

Size of data: 1

OK, so it reads a number as a size from the standard input first, than reads further, probably "size" bytes/characters, processes this input, and outputs either "Wrong!", nothing or something else, presumably our flag. But do not waste any more time monkeyfuzzing the executable, let's fire up r2, because in asm we trust!

[0x00 avatao]$ r2 -A reverse4

-- Heisenbug: A bug that disappears or alters its behavior when one attempts to probe or isolate it.

[0x00400720]>

r2 tip: The -A switch runs aaa command at start to analyze all referenced code, so we will have functions, strings, XREFS, etc. right at the beginning. As usual, you can get help with ?.

It is a good practice to create a project, so we can save our progress, and we can come back at a later time:

[0x00400720]> Ps avatao_reverse4

avatao_reverse4

[0x00400720]>

r2 tip: You can save a project using Ps [file], and load one using Po [file]. With the -p option, you can load a project when starting r2.

We can list all the strings r2 found:

[0x00400720]> fs strings

[0x00400720]> f

0x00400e98 7 str.Wrong_

0x00400e9f 27 str.We_are_in_the_outer_space_

0x00400f80 18 str.Size_of_data:__u_n

0x00400f92 23 str.Such_VM__MuCH_reV3rse_

0x00400fa9 16 str.Use_everything_

0x00400fbb 9 str.flag.txt

0x00400fc7 26 str.You_won__The_flag_is:__s_n

0x00400fe1 21 str.Your_getting_closer_

[0x00400720]>

r2 tip: r2 puts so called flags on important/interesting offsets, and organizes these flags into flagspaces (strings, functions, symbols, etc.) You can list all flagspaces using fs, and switch the current one using fs [flagspace] (the default is *, which means all the flagspaces). The command f prints all flags from the currently selected flagspace(s).

OK, the strings looks interesting, especially the one at 0x00400f92. It seems to hint that this crackme is based on a virtual machine. Keep that in mind!

These strings could be a good starting point if we were talking about a real-life application with many-many features. But we are talking about a crackme, and they tend to be small and simple, and focused around the problem to be solved. So I usually just take a look at the entry point(s) and see if I can figure out something from there. Nevertheless, I'll show you how to find where these strings are used:

[0x00400720]> axt @@=`f~[0]`

d 0x400cb5 mov edi, str.Size_of_data:__u_n

d 0x400d1d mov esi, str.Such_VM__MuCH_reV3rse_

d 0x400d4d mov edi, str.Use_everything_

d 0x400d85 mov edi, str.flag.txt

d 0x400db4 mov edi, str.You_won__The_flag_is:__s_n

d 0x400dd2 mov edi, str.Your_getting_closer_

r2 tip: We can list crossreferences to addresses using the axt [addr] command (similarly, we can use axf to list references from the address). The @@ is an iterator, it just runs the command once for every arguments listed.

The argument list in this case comes from the command f~[0]. It lists the strings from the executable with f, and uses the internal grep command ~ to select only the first column ([0]) that contains the strings' addresses.

As I was saying, I usually take a look at the entry point, so let's just do that:

[0x00400720]> s main

[0x00400c63]>

r2 tip: You can go to any offset, flag, expression, etc. in the executable using the s command (seek). You can use references, like $$ (current offset), you can undo (s-) or redo (s+) seeks, search strings (s/ [string]) or hex values (s/x 4142), and a lot of other useful stuff. Make sure to check out s?!

Now that we are at the beginning of the main function, we could use p to show a disassembly (pd, pdf), but r2 can do something much cooler: it has a visual mode, and it can display graphs similar to IDA, but way cooler, since they are ASCII-art graphs :)

r2 tip: The command family p is used to print stuff. For example it can show disassembly (pd), disassembly of the current function (pdf), print strings (ps), hexdump (px), base64 encode/decode data (p6e, p6d), or print raw bytes (pr) so you can for example dump parts of the binary to other files. There are many more functionalities, check ?!

R2 also has a minimap view which is incredibly useful for getting an overall look at a function:

r2 tip: With command V you can enter the so-called visual mode, which has several views. You can switch between them using p and P. The graph view can be displayed by hitting V in visual mode (or using VV at the prompt).

Hitting p in graph view will bring up the minimap. It displays the basic blocks and the connections between them in the current function, and it also shows the disassembly of the currently selected block (marked with @@@@@ on the minimap). You can select the next or the previous block using the *<TAB>* and the *<SHIFT><TAB>* keys respectively. You can also select the true or the false branches using the t and the f keys.

It is possible to bring up the prompt in visual mode using the : key, and you can use o to seek.

Lets read main node-by-node! The first block looks like this:

We can see that the program reads a word (2 bytes) into the local variable named local_10_6, and than compares it to 0xbb8. Thats 3000 in decimaclass="underline"

[0x00400c63]> ? 0xbb8

3000 0xbb8 05670 2.9K 0000:0bb8 3000 10111000 3000.0 0.000000f 0.000000

r2 tip: yep, ? will evaluate expressions, and print the result in various formats.

If the value is greater than 3000, then it will be forced to be 3000:

There are a few things happening in the next block:

First, the "Size of data: " message we saw when we run the program is printed. So now we know that the local variable local_10_6 is the size of the input data - so lets name it accordingly (remember, you can open the r2 shell from visual mode using the : key!):

:> afvn local_10_6 input_size

r2 tip: The af command family is used to analyze functions. This includes manipulating arguments and local variables too, which is accessible via the afv commands. You can list function arguments (afa), local variables (afv), or you can even rename them (afan, afvn). Of course there are lots of other features too - as usuaclass="underline" use the "?", Luke!