ETA?

Writeup by hgarrereyn

  • Reverse Engineering
  • 60 points
  • Description: If this script were to finish, what would it output? MacOS Linux

Solution

After running the script and watching the prompt hang for 30 seconds, it is pretty clear that the script would either hang forever or take an inordinate amount of time to finish. Rather than solve the halting problem, I opted to do some dynamic analysis.

I viewed the disassembly in Hopper and tried to find the part of the code that was causing the program to hang.

Early on in main, I found the following function call:

0000000000400dac         lea        rax, qword [rbp+var_40]
0000000000400db0         mov        esi, 0x7ffffffc
0000000000400db5         mov        rdi, rax                                    ; argument #1 for method _Z10get_primesm
0000000000400db8         call       _Z10get_primesm

Hmm, maybe this could be the problem. Let's find out. I'll set a breakpoint after the function call and see if we hit it.

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

Breakpoint 1, 0x0000000000400dbd in main ()

We hit the breakpoint after about a minute so this isn't the problem.

Side note: I actually found this out on accident by running the program assuming it would hang on the get_primes function. I switched windows and started googling something and when I switched back in a few minutes, it had reached the breakpoint.

Next we see some sort of loop followed by an ostream call to print something to the console.

0000000000400ddc         mov        qword [rbp+var_70], 0x0
0000000000400de4         mov        dword [rbp+var_14], 0x0
0000000000400deb         mov        dword [rbp+var_18], 0x0

                     loc_400df2:
0000000000400df2         cmp        dword [rbp+var_18], 0xf423f                 ; CODE XREF=main+196
0000000000400df9         jg         loc_400e5d

0000000000400dfb         lea        rax, qword [rbp+var_60]
0000000000400dff         mov        rdi, rax
0000000000400e02         call       _ZNSt6vectorImSaImEE5beginEv                ; std::vector<unsigned long, std::allocator<unsigned long> >::begin()
0000000000400e07         mov        qword [rbp+var_70], rax

                     loc_400e0b:
0000000000400e0b         lea        rax, qword [rbp+var_60]                     ; CODE XREF=main+190
0000000000400e0f         mov        rdi, rax
0000000000400e12         call       _ZNSt6vectorImSaImEE3endEv                  ; std::vector<unsigned long, std::allocator<unsigned long> >::end()
0000000000400e17         mov        qword [rbp+var_20], rax
0000000000400e1b         lea        rdx, qword [rbp+var_20]
0000000000400e1f         lea        rax, qword [rbp+var_70]
0000000000400e23         mov        rsi, rdx                                    ; argument #2 for method _ZN9__gnu_cxxltIPmSt6vectorImSaImEEEEbRKNS_17__normal_iteratorIT_T0_EESA_
0000000000400e26         mov        rdi, rax                                    ; argument #1 for method _ZN9__gnu_cxxltIPmSt6vectorImSaImEEEEbRKNS_17__normal_iteratorIT_T0_EESA_
0000000000400e29         call       _ZN9__gnu_cxxltIPmSt6vectorImSaImEEEEbRKNS_17__normal_iteratorIT_T0_EESA_ ; bool __gnu_cxx::operator< <unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >(__gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > > const&, __gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > > const&)
0000000000400e2e         test       al, al
0000000000400e30         je         loc_400e57

0000000000400e32         lea        rax, qword [rbp+var_70]
0000000000400e36         mov        rdi, rax
0000000000400e39         call       _ZNK9__gnu_cxx17__normal_iteratorIPmSt6vectorImSaImEEEdeEv ; __gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >::operator*() const
0000000000400e3e         mov        rax, qword [rax]
0000000000400e41         mov        dword [rbp+var_14], eax
0000000000400e44         lea        rax, qword [rbp+var_70]
0000000000400e48         mov        esi, 0x0
0000000000400e4d         mov        rdi, rax                                    ; argument #1 for method _ZN9__gnu_cxx17__normal_iteratorIPmSt6vectorImSaImEEEppEi
0000000000400e50         call       _ZN9__gnu_cxx17__normal_iteratorIPmSt6vectorImSaImEEEppEi ; __gnu_cxx::__normal_iterator<unsigned long*, std::vector<unsigned long, std::allocator<unsigned long> > >::operator++(int)
0000000000400e55         jmp        loc_400e0b

                     loc_400e57:
0000000000400e57         add        dword [rbp+var_18], 0x1                     ; CODE XREF=main+153
0000000000400e5b         jmp        loc_400df2

The loop counter (var_18) is initialized to zero and incremented each loop. The loop will terminate once it reaches 0xf423f or 999999. We also see a bunch of vector initializations going on in the loop. So this must be where we are hanging.

The print is performed by the following (outside of the loop):

                    loc_400e5d:
0000000000400e5d         mov        eax, dword [rbp+var_14]                     ; CODE XREF=main+98
0000000000400e60         mov        esi, eax
0000000000400e62         mov        edi, 0x602ea0
0000000000400e67         call       j__ZNSolsEi
0000000000400e6c         mov        esi, 0x400b00
0000000000400e71         mov        rdi, rax
0000000000400e74         call       j__ZNSolsEPFRSoS_E

So we see that var_14 gets printed ($rbp-20). Also, we notice that the same variable is written to inside the loop. Let's examine a few iterations to see if we can find out what it is set to.

$ gdb -q eta
Reading symbols from eta...(no debugging symbols found)...done.
(gdb) b *0x400df2
Breakpoint 1 at 0x400df2
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>x/x $rbp-20
>end
(gdb) r
Starting program: /home/ubuntu/pactf/eta
0x7fffffffe51c:    0x00000000

Breakpoint 1, 0x0000000000400df2 in main ()
(gdb) c
Continuing.
0x7fffffffe51c:    0x7fffffed

Breakpoint 1, 0x0000000000400df2 in main ()
(gdb) c
Continuing.
0x7fffffffe51c:    0x7fffffed

Breakpoint 1, 0x0000000000400df2 in main ()
(gdb) c
Continuing.
0x7fffffffe51c:    0x7fffffed

Breakpoint 1, 0x0000000000400df2 in main ()

Hmm, it doesn't seem to change. Every loop, it is set to 0x7fffffed or 2147483629.

So the flag must be 2147483629.

results matching ""

    No results matching ""