.. visibility


                                                                                                
                           @((%/(%%.#..&@&(****@(****//*,,                                      
                           @((%/(%%.#//((((#(@.@((**%(%@**                                      
                           @((%##((((((((((((((@((%.(((%&(                                      
                     ****#%#((((((((((((((((((((((%%((((%&                                      
                     ....((((((((((((#.    ,,,#((((%(((%%*                                      
                     **(((((((((((((          .,%((((((%%%.......%.%                            
                     *(((((((((((((     #@@     ,((((((%%%%%((#,#%.%                            
                     @(((((((((((((&            /((((((((((%%%@,#%.%                            
                     @(@*,,,*@((((((@          @((((((((((((((%%%@.%                            
                    /,        ,&((((((((@@@@(((((((((((((((((((((%%%%....                       
                    @    @@    ,@(@*,/@%@((((((((((((((((((((((((((%%%...                       
                    *          ,((@% @@@(%((((((((((((((((((((((((((%%%@,                       
                    ..%.      #((((((((((((((((((((((((((((((((((((((%%%/                       
                        \$$&%((((((((((((((((((((((((((((((((((((((((%%%@                       
                           &%.@&*@(((((((((((((((((((((((((((((((((((%%%*                       
                           &%.@&*#/*((((((((((((((((((((((((((((((((%%%@(                       
                           #########((((((((((((((((((((((((((((((#%%%@,,                       
                           *********(((%@((((((((((((((((((((((((((%&....                       
                           .........#*.*,,@((((((((((((((((((%&(((%&(((((                       
                           .........#*.*,,%.&@(((((((((((%%%%@@((%@......                       
                           .........#*.*,,%.&#..@#/@@@@#%@                                      
                                                    @((%@                                       

This was a reversing challenge rated with 500 points in NACTF. Despite of the hint (about using ghidra with the gotools) I actually used Cutter (thank you guys, awesome work with this tool!) for the challenge.

The instructions said:

C is so boring, why not Go give this a try?

This binary doesn’t come from C code but Go code so things look a little bit different from standard binaries.


There are probably tons of better ways to do this but this is how I solved. I’m just starting with reversing so if you have any tips I would love to hear them!


Let’s begin by taking a look at the binary. Even though this is a small binary, we have tons of functions:

But let’s start from the beginning. When we try to find the main function we get 4 hits. The one we are looking for is the one named sys.main.main

The first blocks make the encryption part. They took 2 strings in memory and decoded from hex.

After that, the program constructs a NewCipher object that later is used in the NewCTR, constructing the final key to which our string is going to be compared.

I’m skipping this part mainly because this is not where we want to look for our solution. This is just how the program creates the final key for comparison.

Now, let’s go for the interesting part. The program asks for input:

After that, a call is performed to rsi. If we follow it (in runtime) we can see that the function is the XORKeyStream from the crypto library.

After that, the result is compared with the key the cypher generated before reading our input in the function ConstantTimeCompare

Enough static analysis. Let’s run the code.

The program prints Got a flag for me? and we have to enter some data. I’m going to enter a bunch of ‘A’ and put a breakpoint in the compare function.

We can see that the first thing the function does is to check if the length is equal. Checking the registers we can see that the target length is 0x39 because I entered 0x9 ‘A’s. Nice, now we have the length.

After that, we just have to start from the end and ask how the solution would work. We know that our input is read from STDIN, that it has a length of 0x39 and that it’s XOR with some data and compared with the key. If they match, we got it.

So, we have to reverse that proceeding. We just have to grab that final key that is compared with our xor input. With that, the solution is the xor operation of the data that it’s xor with our input and the final key from before.

First, let’s grab that target key. Put a breakpoint before the call of the ConstantTimeCompare.

By seeing the ConstantTimeCompare we can check that the destination data (our key) is in arg_20h which is rsp+0x20 (first small block in the left)

If we check the stack we can get that address and look at the content with the hexdump view.

(Cool trick, I always have the hexdump unsynced so i can move around without messing with the code. Right click in the window and press the sync/unsync offset)

We know the length is 0x39 so with that information we can get the full key:

The key:

6b17d46be8a1a5ef781dea7af734f73e77caf41c354c9aaddd5d1f40d900001c20e36f1392904f1da2fb7cd3613531c9a177a880996af010b2

Now we have to get the xor data. The right way to do it probably would be to put a breakpoint in the call rsi instruction so we can step into the function and take a look but…this is a CTF so time always matter. We can get the key by xor the result of the function with our input. After the call, we get the result in the stack, in the second position.

So go ahead, start the debugging and send 0x39 chars, whatever you want. I sent ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA’ and set a breakpoint right after the call rsi instruction. After that we check the stack, get the address (in my case 0xc0000c60c0) and take a look at the data:

We can see the XOR output and above, our input. So, the input was 414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141

the result was 4437f65ecf9b93c64003cf0bd306e91806e781331352e89aaf720174eb721e2909935d0db2b3670396f30fc1720d12ff8b5bb390e840eb1c8e

and if we xor them, we get:

576b71f8edad28701428e4a9247a85947a6c0725213a9dbee334035aa335f6848d21c4cf3f22642d7b24e80334c53beca1af2d1a901aa5dcf

We have everything ready, now we xor this result with the key we get before and the result is:

6e616374667b7768795f643065735f67306c346e675f3376336e5f7573335f746831735f6162695f75493253527962776b6d5a51306b5a4d7d

This is hex so we have to convert it to text and the flag shows up:

nactf{why_d0es_g0l4ng_3v3n_us3_th1s_abi_uI2SRybwkmZQ0kZM}