# Hacking Tube

## CSAW CTF 2015 -- FTP & FTP2

Category: Reversing (FTP) & Exploitable (FTP2)
Points: 300 (FTP) & 300 (FTP2)

## FTP

64 bit ELF. It's a FTP-like service, we can list all the acceptable command by sending the HELP command. Here are some important commands that we'll need to pass the challenges:

USER [username]: enter username to login
PASS [password]: enter password after sending the USER command to login as the [username]
PASV: open a port for passive mode
LIST: list the files in the directory
STOR: upload a file
RETR: download a file
RDF: read the reversing solution's flag

So after some static analysis with the help of IDA Pro, I figure out that in order to pass the reversing challenge, we'll need to login as the user blankwall. The password checking function's at 0x401540, let's take a look at it:

At first I was like "Ah, that's easy!", since we have the constraint system, we can just set it up and leave the rest to Z3. But after I have the solution and enter the password, the service respond it with a frustrating "Invalid login credentials". Knowing that Hex-Rays' decompiler might have the incorrect decompiling result, I re-check the password checking logic by reversing directly from the x64 assembly, not the pseudo code, and finally found the root of the problem:

What really matters is the assembly eax, [rbp+var_4] at line 4. Notice that when the program move v3 to the register eax, it doesn't clear the highest 32 bits of the register rax. So when it runs to the line ecx, [rdx+rax], rax isn't just simply v3 & 0xFFFFFFFF, it's actually ((v3 << 5) & 0xFFFFFFFF00000000) | (v3 & 0xFFFFFFFF), and that's where the Hex-Rays decompiler made the mistake.

So now we have the correct constraint system. Wrote a Z3 python script and retrieve the password:

Since I don't know the password length, I just brute force it from 1 ~ 10. We can found a solution at length 6:

Now we get the login password, time to capture the flag :)

The flag is: flag{n0_c0ok1e_ju\$t_a_f1ag_f0r_you}

## FTP2

So now we're logged in as a valid user, we can finally do some other stuff. After sending PASV and the LIST command, I found that there's a flag.txt in the directory. At first I try to download the file, but the service response "Invalid character specified". Well that's strange :/ so I went to the RETR function and start analyzing.

So...to sum it up, the program will detect whether if the filename has the character store in 0x604408, and if it does, it will refuse to let us download the file. Remeber the function that does the password checking?

So apparently we can't have 'f' in our filename, we'll need to find another way to bypass the filter. By checking other functions, I finally found a way to bypass it.

Here in the STOR function, if we upload a file that is big enough, we can overwrite the data at 0x604408. So it's quite simple: just create a file that is larger than 512 bytes, then upload it to the server. After that, we can download the flag.txt and get the flag.

The flag is: flag{exploiting_ftp_servers_in_2015}