IDA informs us that the binary is corrupt. We begin to fix the ELF header and reset the SHT. GDB cannot load a
ELF binary if the SHT is corrupts. To fix it, we can just set the SHT (Start of section headers) to 0.

After this little fix, you can run and debug the binary with GDB. When we disassembles the binary with IDA,
we can see that the binary contains some little obfuscations - Break Basic Bloc and Junk codes. As you can
see below, all basic blocks are broken. We can see that the binary do some push ; ret to break the IDA basic
bloc - That's classic.

When we see in detail what happens, we can see everywhere in the binary a push rax + lea ; push ; ret + pop rax
sequence. Every sequences of the lea ; push ; ret is equals to a jump rip+1.

We can also find lot of sequences which is a simple junk codes. The binary contains only two differents sequences of
junk codes. As you can see below the first sequence is :

And the second sequence of junk codes is :

We can also find some calls which breaking the basic blocks.

Before starting the reverse with IDA and GDB, we will withdraw all sequences of junk codes and break basic block.
After that, it will be easier to understand the operations of the binary. For that, we replace all sequences by the opcode
nop.

Now, we can starting the reverse :). In sub_401D52 function we can find the string license.db and a call to libc.open, when
we following the execution flow, we can see that the fd is read - on my screenshot the buffer is called ciphered_license. Then, a second buffer
is allcated for the plaintext license. Just after that, we can find two interesting basic blocks which decrypts the license buffer.

The first basic block is taken if the offset is 0, that means when it's the first character. It xor the first character with the value 0x12
and put it into the plaintext buffer. Otherwise the second basic block is taken and it xor the current character with the previus character
and put it into the plaintext buffer. Now we know and we can uncrypts the license.db file.

Now, we need to know how to communicate with the server. Continuing the analysis, we can find a function - sub_401A3F - which
do a RC4 encryption. If you follow the execution flow, you can see that this function takes in argument the TCP request,
the key and a empty buffer. Looking the call graph, we can find the key of RC4 encryption at 402062 as you can see below.

Just after the call of RC4 uncrypts routine, the function checks a magic number on the first 3 bytes of the uncrypted TCP request.
The magic number need to be set at NDH. Below, each basic block compares each character of the magic number.

After this check, we have a second check which compares if the 4th and 7th character is :. Then we have a call to the function libc.atoi
at the offset request+5 and saves it on [rbp+var_4]. A second pointer is set at the offset request+8. In bref, the request need to be as
follows :

NDH:[0-9]{2}:[0-9a-zA-Z]

Ok, now we can communicate with the server. Below, a simple test which sending the NDH:01:test request.

The server replie False. If we send a good key like 01:cd30e4ce436b08e63683bef2e9f35603 the server replie True.

Reverse file format of license.db [OK]

Reverse TCP protocol [OK]

Communicate with server [OK]

Now, we need to find the vulnerability to get the license.db file of any other teams. The vulnerability is in the sub_401D52
function - 40200A. We can see a call to the libc.sprintf function without checking the size of the [rbp+var_60] argument.
This argument is the license pointer. In bref, this call puts 01:cd30e4ce436b08e63683bef2e9f35603 without checking the size of the
license in a buffer allocated on the stack - The vulnerability is a classical stack overflow.

To trigger it, we can just sent this following request encrypted in RC4:

Maybe you may ask you why the crash is not on the ret instruction, beacause juste after the libc.scanf we have a
call to the libc.strstr function, and this function takes a pointer overwritten by our payload. That why we gets
a SIGSEGV on the movzx edx,BYTE PTR [rdi] instruction. To control the RIP register, we need to fix the RDI register,
for that we need to set a 64 bits mapped address, but in 64 bits the CODE, DATA, STACK section is mapped between 24 and 48 bits and we
cannot set a 48 bits address because we cannot set a NULL bytes on our payload. OK, but where I can find a 64 bits mapped
address ? In the vsyscall area !

This exploit is tricky because we have a little space to put our shellcode. Below, you can see
two possible scenarios.

I managed to create a shellcode which returns me the license file with only 37 bytes.
That why I have chosen the scenario 1. When the SIGSEGV occurs, in the current and
previus stack frame we can find the client fd, and the plaintext pointer. Below, you
can see my shellcode which do a simple write(fd, plaintext, 4095).