Impossible Conditions

Writeup by hgarrereyn

  • Reverse Engineering
  • 30 points
  • Let’s make the impossible possible! Let’s make 1=5. impossible.out

Solution

Running this binary produces no output and exits immediately. Let's take a look at the disassembly.

First we notice a bunch of suspicious mov operations that appear to be swapping some char codes around.

Then we see some get_time methods right before a je (line 0x401420) that skips a large chunk of code:

                    main:
0000000000400e06         push       rbp                                         ; DATA XREF=_start+29
0000000000400e07         mov        rbp, rsp
0000000000400e0a         push       r15
0000000000400e0c         push       r14
0000000000400e0e         push       r13
0000000000400e10         push       r12
0000000000400e12         push       rbx
0000000000400e13         sub        rsp, 0x1e8
0000000000400e1a         mov        rax, qword [fs:0x28]
0000000000400e23         mov        qword [rbp+var_38], rax
0000000000400e27         xor        eax, eax
0000000000400e29         mov        byte [m], 0x6d
0000000000400e30         mov        byte [n], 0x6e
0000000000400e37         mov        byte [z], 0x7a
                    <many lines omitted>
0000000000401362         mov        byte [z], 0x21
0000000000401369         mov        byte [n], 0x6e
0000000000401370         mov        byte [x], 0x78
0000000000401377         lea        rax, qword [rbp+var_1F0]
000000000040137e         mov        esi, 0x0                                    ; argument "tzp" for method j_gettimeofday
0000000000401383         mov        rdi, rax                                    ; argument "tp" for method j_gettimeofday
0000000000401386         call       j_gettimeofday
000000000040138b         mov        rax, qword [rbp+var_1F0]
0000000000401392         mov        qword [rbp+var_1F8], rax
0000000000401399         lea        rax, qword [rbp+var_1F8]
00000000004013a0         mov        rdi, rax                                    ; argument "clock" for method j_localtime
00000000004013a3         call       j_localtime
00000000004013a8         mov        rdx, rax
00000000004013ab         lea        rax, qword [rbp+var_60]
00000000004013af         mov        rcx, rdx                                    ; argument "timeptr" for method j_strftime
00000000004013b2         mov        edx, 0x401a54                               ; "%m-%d-%Y\\t%T.", argument "format" for method j_strftime
00000000004013b7         mov        esi, 0x1e                                   ; argument "maxsize" for method j_strftime
00000000004013bc         mov        rdi, rax                                    ; argument "s" for method j_strftime
00000000004013bf         call       j_strftime
00000000004013c4         lea        rax, qword [rbp+var_1FE]
00000000004013cb         mov        rdi, rax
00000000004013ce         call       j__ZNSaIcEC1Ev
00000000004013d3         lea        rdx, qword [rbp+var_1FE]
00000000004013da         lea        rcx, qword [rbp+var_60]
00000000004013de         lea        rax, qword [rbp+var_80]
00000000004013e2         mov        rsi, rcx
00000000004013e5         mov        rdi, rax
00000000004013e8         call       j__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_
00000000004013ed         lea        rax, qword [rbp+var_80]
00000000004013f1         mov        esi, 0x401a61
00000000004013f6         mov        rdi, rax
00000000004013f9         call       j__ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEPKc
00000000004013fe         test       eax, eax
0000000000401400         sete       bl
0000000000401403         lea        rax, qword [rbp+var_80]
0000000000401407         mov        rdi, rax
000000000040140a         call       j__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
000000000040140f         lea        rax, qword [rbp+var_1FE]
0000000000401416         mov        rdi, rax
0000000000401419         call       j__ZNSaIcED1Ev
000000000040141e         test       bl, bl
0000000000401420         je         loc_4017be
0000000000401426         lea        rax, qword [rbp+var_1FE]
000000000040142d         mov        rdi, rax
0000000000401430         call       j__ZNSaIcEC1Ev
...

Using gdb we can break at the jump and see if we take it:

$ gdb -q impossible
Reading symbols from impossible...(no debugging symbols found)...done.
(gdb) b *0x401420
Breakpoint 1 at 0x401420
(gdb) r
Starting program: /home/ubuntu/pactf/impossible

Breakpoint 1, 0x0000000000401420 in main ()
(gdb) ni
0x00000000004017be in main ()

Notice that the instruction pointer did indeed jump to 0x4017be.

Now, let's use gdb to skip over that je and continue execution right after it.

Note: be sure to set $rip not $eip since this is a 64 bit binary

$ gdb -q impossible
Reading symbols from impossible...(no debugging symbols found)...done.
(gdb) b *0x401420
Breakpoint 1 at 0x401420
(gdb) r
Starting program: /home/ubuntu/pactf/impossible

Breakpoint 1, 0x0000000000401420 in main ()
(gdb) set $rip=0x401426
(gdb) c
Continuing.
abcx!ilgdn
[Inferior 1 (process 1329) exited normally]

Oh look! It printed out something before exiting this time.

That's our flag!

Flag: abcx!ilgdn

results matching ""

    No results matching ""