<< All Posts
Cracking binary files using PHP and some Linux tools


Hi there.

Today I was asking myself if I still remember some low level programming like assembly and some nice stuff I played when I was a 16 years old kid. I don’t remember that much but I decided to do a quick test to see if I’m able to pick up something from the middle of my brain. Actually some minutes on google helped a bit to refresh my memory.

I wrote this simple post to teach you how to edit a binary file (or create a very very simple crack).

We’re gonna do this using PHP and some tools that you can find on your linux box.

1) First let’s compile our example using C. Create a file hello-world.c with the following content:

#include <stdio.h>

void main() {
    int password = 9;

    if (password == 8) {
        printf("Congratulations \n");
    } else {
        printf("Try again \n");
    }
}

2) To compile try this:

gcc -o hello-world hello-world.c

Now that we have a binary file on our folder, we can run it using this: ./hello-world

Try again

Our goal is change the binary file in order to show the word “Congratulations”. First, let’s take a look on the binary file.

3) Poke around inside the binary file using the following command:

objdump -d hello-world > dump.txt

Your dump.txt must look like this:


hello-world:     file format elf64-x86-64


Disassembly of section .init:

00000000004003e0 <_init>:
  4003e0:   48 83 ec 08             sub    $0x8,%rsp
  4003e4:   48 8b 05 0d 0c 20 00    mov    0x200c0d(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
  4003eb:   48 85 c0                test   %rax,%rax
  4003ee:   74 05                   je     4003f5 <_init+0x15>
  4003f0:   e8 3b 00 00 00          callq  400430 <__gmon_start__@plt>
  4003f5:   48 83 c4 08             add    $0x8,%rsp
  4003f9:   c3                      retq

Disassembly of section .plt:

0000000000400400 <puts@plt-0x10>:
  400400:   ff 35 02 0c 20 00       pushq  0x200c02(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
  400406:   ff 25 04 0c 20 00       jmpq   *0x200c04(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
  40040c:   0f 1f 40 00             nopl   0x0(%rax)

0000000000400410 <puts@plt>:
  400410:   ff 25 02 0c 20 00       jmpq   *0x200c02(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
  400416:   68 00 00 00 00          pushq  $0x0
  40041b:   e9 e0 ff ff ff          jmpq   400400 <_init+0x20>

0000000000400420 <__libc_start_main@plt>:
  400420:   ff 25 fa 0b 20 00       jmpq   *0x200bfa(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
  400426:   68 01 00 00 00          pushq  $0x1
  40042b:   e9 d0 ff ff ff          jmpq   400400 <_init+0x20>

0000000000400430 <__gmon_start__@plt>:
  400430:   ff 25 f2 0b 20 00       jmpq   *0x200bf2(%rip)        # 601028 <_GLOBAL_OFFSET_TABLE_+0x28>
  400436:   68 02 00 00 00          pushq  $0x2
  40043b:   e9 c0 ff ff ff          jmpq   400400 <_init+0x20>

Disassembly of section .text:

0000000000400440 <_start>:
  400440:   31 ed                   xor    %ebp,%ebp
  400442:   49 89 d1                mov    %rdx,%r9
  400445:   5e                      pop    %rsi
  400446:   48 89 e2                mov    %rsp,%rdx
  400449:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  40044d:   50                      push   %rax
  40044e:   54                      push   %rsp
  40044f:   49 c7 c0 d0 05 40 00    mov    $0x4005d0,%r8
  400456:   48 c7 c1 60 05 40 00    mov    $0x400560,%rcx
  40045d:   48 c7 c7 2d 05 40 00    mov    $0x40052d,%rdi
  400464:   e8 b7 ff ff ff          callq  400420 <__libc_start_main@plt>
  400469:   f4                      hlt
  40046a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

0000000000400470 <deregister_tm_clones>:
  400470:   b8 47 10 60 00          mov    $0x601047,%eax
  400475:   55                      push   %rbp
  400476:   48 2d 40 10 60 00       sub    $0x601040,%rax
  40047c:   48 83 f8 0e             cmp    $0xe,%rax
  400480:   48 89 e5                mov    %rsp,%rbp
  400483:   77 02                   ja     400487 <deregister_tm_clones+0x17>
  400485:   5d                      pop    %rbp
  400486:   c3                      retq
  400487:   b8 00 00 00 00          mov    $0x0,%eax
  40048c:   48 85 c0                test   %rax,%rax
  40048f:   74 f4                   je     400485 <deregister_tm_clones+0x15>
  400491:   5d                      pop    %rbp
  400492:   bf 40 10 60 00          mov    $0x601040,%edi
  400497:   ff e0                   jmpq   *%rax
  400499:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004004a0 <register_tm_clones>:
  4004a0:   b8 40 10 60 00          mov    $0x601040,%eax
  4004a5:   55                      push   %rbp
  4004a6:   48 2d 40 10 60 00       sub    $0x601040,%rax
  4004ac:   48 c1 f8 03             sar    $0x3,%rax
  4004b0:   48 89 e5                mov    %rsp,%rbp
  4004b3:   48 89 c2                mov    %rax,%rdx
  4004b6:   48 c1 ea 3f             shr    $0x3f,%rdx
  4004ba:   48 01 d0                add    %rdx,%rax
  4004bd:   48 d1 f8                sar    %rax
  4004c0:   75 02                   jne    4004c4 <register_tm_clones+0x24>
  4004c2:   5d                      pop    %rbp
  4004c3:   c3                      retq
  4004c4:   ba 00 00 00 00          mov    $0x0,%edx
  4004c9:   48 85 d2                test   %rdx,%rdx
  4004cc:   74 f4                   je     4004c2 <register_tm_clones+0x22>
  4004ce:   5d                      pop    %rbp
  4004cf:   48 89 c6                mov    %rax,%rsi
  4004d2:   bf 40 10 60 00          mov    $0x601040,%edi
  4004d7:   ff e2                   jmpq   *%rdx
  4004d9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004004e0 <__do_global_dtors_aux>:
  4004e0:   80 3d 59 0b 20 00 00    cmpb   $0x0,0x200b59(%rip)        # 601040 <__TMC_END__>
  4004e7:   75 11                   jne    4004fa <__do_global_dtors_aux+0x1a>
  4004e9:   55                      push   %rbp
  4004ea:   48 89 e5                mov    %rsp,%rbp
  4004ed:   e8 7e ff ff ff          callq  400470 <deregister_tm_clones>
  4004f2:   5d                      pop    %rbp
  4004f3:   c6 05 46 0b 20 00 01    movb   $0x1,0x200b46(%rip)        # 601040 <__TMC_END__>
  4004fa:   f3 c3                   repz retq
  4004fc:   0f 1f 40 00             nopl   0x0(%rax)

0000000000400500 <frame_dummy>:
  400500:   48 83 3d 18 09 20 00    cmpq   $0x0,0x200918(%rip)        # 600e20 <__JCR_END__>
  400507:   00
  400508:   74 1e                   je     400528 <frame_dummy+0x28>
  40050a:   b8 00 00 00 00          mov    $0x0,%eax
  40050f:   48 85 c0                test   %rax,%rax
  400512:   74 14                   je     400528 <frame_dummy+0x28>
  400514:   55                      push   %rbp
  400515:   bf 20 0e 60 00          mov    $0x600e20,%edi
  40051a:   48 89 e5                mov    %rsp,%rbp
  40051d:   ff d0                   callq  *%rax
  40051f:   5d                      pop    %rbp
  400520:   e9 7b ff ff ff          jmpq   4004a0 <register_tm_clones>
  400525:   0f 1f 00                nopl   (%rax)
  400528:   e9 73 ff ff ff          jmpq   4004a0 <register_tm_clones>

000000000040052d <main>:
  40052d:   55                      push   %rbp
  40052e:   48 89 e5                mov    %rsp,%rbp
  400531:   48 83 ec 10             sub    $0x10,%rsp
  400535:   c7 45 fc 09 00 00 00    movl   $0x9,-0x4(%rbp)
  40053c:   83 7d fc 08             cmpl   $0x8,-0x4(%rbp)
  400540:   75 0c                   jne    40054e <main+0x21>
  400542:   bf e4 05 40 00          mov    $0x4005e4,%edi
  400547:   e8 c4 fe ff ff          callq  400410 <puts@plt>
  40054c:   eb 0a                   jmp    400558 <main+0x2b>
  40054e:   bf f5 05 40 00          mov    $0x4005f5,%edi
  400553:   e8 b8 fe ff ff          callq  400410 <puts@plt>
  400558:   c9                      leaveq
  400559:   c3                      retq
  40055a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

0000000000400560 <__libc_csu_init>:
  400560:   41 57                   push   %r15
  400562:   41 89 ff                mov    %edi,%r15d
  400565:   41 56                   push   %r14
  400567:   49 89 f6                mov    %rsi,%r14
  40056a:   41 55                   push   %r13
  40056c:   49 89 d5                mov    %rdx,%r13
  40056f:   41 54                   push   %r12
  400571:   4c 8d 25 98 08 20 00    lea    0x200898(%rip),%r12        # 600e10 <__frame_dummy_init_array_entry>
  400578:   55                      push   %rbp
  400579:   48 8d 2d 98 08 20 00    lea    0x200898(%rip),%rbp        # 600e18 <__init_array_end>
  400580:   53                      push   %rbx
  400581:   4c 29 e5                sub    %r12,%rbp
  400584:   31 db                   xor    %ebx,%ebx
  400586:   48 c1 fd 03             sar    $0x3,%rbp
  40058a:   48 83 ec 08             sub    $0x8,%rsp
  40058e:   e8 4d fe ff ff          callq  4003e0 <_init>
  400593:   48 85 ed                test   %rbp,%rbp
  400596:   74 1e                   je     4005b6 <__libc_csu_init+0x56>
  400598:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  40059f:   00
  4005a0:   4c 89 ea                mov    %r13,%rdx
  4005a3:   4c 89 f6                mov    %r14,%rsi
  4005a6:   44 89 ff                mov    %r15d,%edi
  4005a9:   41 ff 14 dc             callq  *(%r12,%rbx,8)
  4005ad:   48 83 c3 01             add    $0x1,%rbx
  4005b1:   48 39 eb                cmp    %rbp,%rbx
  4005b4:   75 ea                   jne    4005a0 <__libc_csu_init+0x40>
  4005b6:   48 83 c4 08             add    $0x8,%rsp
  4005ba:   5b                      pop    %rbx
  4005bb:   5d                      pop    %rbp
  4005bc:   41 5c                   pop    %r12
  4005be:   41 5d                   pop    %r13
  4005c0:   41 5e                   pop    %r14
  4005c2:   41 5f                   pop    %r15
  4005c4:   c3                      retq
  4005c5:   66 66 2e 0f 1f 84 00    data32 nopw %cs:0x0(%rax,%rax,1)
  4005cc:   00 00 00 00

00000000004005d0 <__libc_csu_fini>:
  4005d0:   f3 c3                   repz retq

Disassembly of section .fini:

00000000004005d4 <_fini>:
  4005d4:   48 83 ec 08             sub    $0x8,%rsp
  4005d8:   48 83 c4 08             add    $0x8,%rsp
  4005dc:   c3                      retq

5) Let’s take a look on the block that is really important to us:

000000000040052d <main>:
  40052d:    55                       push   %rbp
  40052e:    48 89 e5                 mov    %rsp,%rbp
  400531:    48 83 ec 10              sub    $0x10,%rsp
  400535:    c7 45 fc 09 00 00 00     movl   $0x9,-0x4(%rbp)
  40053c:    83 7d fc 08              cmpl   $0x8,-0x4(%rbp)
  400540:    75 0c                    jne    40054e <main+0x21>
  400542:    bf e4 05 40 00           mov    $0x4005e4,%edi
  400547:    e8 c4 fe ff ff           callq  400410 <puts@plt>
  40054c:    eb 0a                    jmp    400558 <main+0x2b>
  40054e:    bf f5 05 40 00           mov    $0x4005f5,%edi
  400553:    e8 b8 fe ff ff           callq  400410 <puts@plt>
  400558:    c9                       leaveq
  400559:    c3                       retq
  40055a:    66 0f 1f 44 00 00        nopw   0x0(%rax,%rax,1)

Now, let’s zoom in at the line that defines the value 9 to our password variable:

  400535:    c7 45 fc 09 00 00 00     movl   $0x9,-0x4(%rbp)

Since we know the source code, if we change the number 9 to 8 we’re gonna crack the binary. So, let’s find it opening using xxd to see our binary on hexadecimal format:

cat hello-world | xxd | grep 'fc 09'

0000530: e548 83ec 10c7 45fc 0900 0000 837d fc08  .H....E......}..**

There we go! We found the sequence of the hexadecimal bytes responsable to define the number 9.

So, since we know the memory address (0x530) let’s use PHP to change the value of those bytes. But first let’s explain something:

As you can see, the hexadecimal 0x530 is the address that contains 32 bytes, but which byte do we have to set our pointer to write the new password? To figure out which address, let’s split the 32 bytes in groups:

0000530: e548 83ec 10c7 45fc 0900 0000 837d fc08

Byte 00 is: e5
Byte 01 is: 48
Byte 02 is: 83
Byte 03 is: ec

Byte 04 is: 10
Byte 05 is: c7
Byte 06 is: 45
Byte 07 is: fc

Byte 08 is: 09 --> There we go! 0x530 + 0x08 = 0x538
Byte 09 is: 00 -> wait.. why is this byte zero?
Byte 10 is: 00 -> what?
Byte 11 is: 00 -> wtf???

Did you notice the sequence of zeros after 09? Do you have an idea why? Oh well, remember that one integer in PHP have 4 bytes? of “memory space”? There we go my friend, let’s change 4 bytes then.

<?php

$fp = fopen("hello-world", "r+");
fseek($fp, 0x538);
$content = fread($fp, 4);
// echo $content;

$unpack = unpack("N*", $content);
foreach($unpack as $byte) {
    // echo dechex($byte). " \n";
}

fseek($fp, 0x538);
$pack = pack("N*", 0x8000000);
fwrite($fp, $pack);

$unpack = unpack("N*", $pack);
foreach($unpack as $byte) {
    // echo dechex($byte). " \n";
}

fclose($fp);

I added some extra code here because I was learning how to edit the file. Basically fseek sets the pointer to the address we want to change. After that, fwrite does the trick and as you can see our before and after binary must look like this:

Before: cat hello-world | xxd | grep 'fc 09'

0000530: e548 83ec 10c7 45fc 0900 0000 837d fc08  .H....E......}..**

After: cat hello-world | xxd | grep 'fc 08'

0000530: e548 83ec 10c7 45fc 0800 0000 837d fc08  .H....E......}..

The final test:

./hello-world

Congratulations

That’s it for today. I hope you enjoyed.

Rodolfo



<< All Posts