# IWCTF 2016 - Reversing - File Checker - 60 pts
> Description: My friend sent me this file. He told that if I manage to reverse it, I'll have access to all his devices. My misfortune that I don't know anything about reversing :/>> Attachment: [rev60.zip](rev60.zip)
# Write-up
```shell$ file filechecker filechecker: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=564c7e61a18251b57f8c2c3dc205ed3a5b35cca6, stripped```
Executing the binary reveals, that it fails on opening '.password'
```shell$ ltrace ./filechecker __libc_start_main(0x400666, 1, 0x7ffc12dfa718, 0x400850 <unfinished ...>fopen(".password", "r")                                                     = 0printf("Fatal error: File does not exist"...)                               = 32Fatal error: File does not exist+++ exited (status 1) +++```
Creating the file and input some testing flag like "IW{abcdefg}" makes it run, but it just tells us, that we have the wrong chars.
Time to have a look at the disassembly. It shows, that it opens and read the file and then calls a test function for every character.
```000000000040079d         mov        rbp, rsp00000000004007a0         mov        dword [ss:rbp+var_44], edi00000000004007a3         mov        qword [ss:rbp+var_50], rsi00000000004007a7         mov        dword [ss:rbp+var_40], 0x12ee00000000004007ae         mov        dword [ss:rbp+var_3C], 0x12e000000000004007b5         mov        dword [ss:rbp+var_38], 0x12bc00000000004007bc         mov        dword [ss:rbp+var_34], 0x12f100000000004007c3         mov        dword [ss:rbp+var_30], 0x12ee00000000004007ca         mov        dword [ss:rbp+var_2C], 0x12eb00000000004007d1         mov        dword [ss:rbp+var_28], 0x12f200000000004007d8         mov        dword [ss:rbp+var_24], 0x12d800000000004007df         mov        dword [ss:rbp+var_20], 0x12f400000000004007e6         mov        dword [ss:rbp+var_1C], 0x12ef00000000004007ed         mov        dword [ss:rbp+var_18], 0x12d200000000004007f4         mov        dword [ss:rbp+var_14], 0x12f400000000004007fb         mov        dword [ss:rbp+var_10], 0x12ec0000000000400802         mov        dword [ss:rbp+var_C], 0x12d60000000000400809         mov        dword [ss:rbp+var_8], 0x12ba0000000000400810         mov        eax, dword [ss:rbp+var_44]0000000000400813         cdqe       0000000000400815         mov        edx, dword [ss:rbp+rax*4+var_40]0000000000400819         mov        rax, qword [ss:rbp+var_50]000000000040081d         mov        eax, dword [ds:rax]000000000040081f         lea        ecx, dword [ds:rdx+rax]0000000000400822         mov        edx, 0x354ac9330000000000400827         mov        eax, ecx0000000000400829         imul       edx000000000040082b         sar        edx, 0xa000000000040082e         mov        eax, ecx0000000000400830         sar        eax, 0x1f0000000000400833         sub        edx, eax0000000000400835         mov        eax, edx0000000000400837         imul       eax, eax, 0x1337000000000040083d         sub        ecx, eax000000000040083f         mov        eax, ecx0000000000400841         mov        rdx, qword [ss:rbp+var_50]0000000000400845         mov        dword [ds:rdx], eax0000000000400847         nop        0000000000400848         pop        rbp0000000000400849         ret        ```
Hopper gives the following pseudo code for this:
```function sub_40079c {    rcx = *(int32_t *)(rbp + sign_extend_32(arg0) * 0x4 + 0xffffffffffffffc0) + *(int32_t *)arg1;    rax = rcx - ((SAR(rcx * 0x354ac933, 0xa)) - (SAR(rcx, 0x1f))) * 0x1337;    *(int32_t *)arg1 = rax;    return rax;}```
Though quite some shifting and calculations there, this boils down to:
`result = 0x1337 - (0x12ee + curchar)`
So in the end, every character gets summed with the value at the same index in the array `[0x12ee, 0x12e0, 0x12bc, 0x12f1, 0x12ee, 0x12eb, 0x12f2, 0x12d8, 0x12f4, 0x12ef, 0x12d2, 0x12f4, 0x12ec, 0x12d6, 0x12ba]`, which should result in `0x1337` to pass the validation.
```python#!/usr/bin/python
coll = [ 0x12ee, 0x12e0, 0x12bc, 0x12f1, 0x12ee, 0x12eb, 0x12f2, 0x12d8, 0x12f4, 0x12ef, 0x12d2, 0x12f4, 0x12ec, 0x12d6, 0x12ba ]
result = ""
for val in coll:	res = 0x1337 - val	result += chr(res)
print result```
This will calculate the password:
```shell$ python solver.py IW{FILE_CHeCKa}```