Beispiel #1
0
static void init_user_stack(elf_prog_t *prog, int prot)
{
	long argc = strings_count(prog->argv),
	     envc = strings_count(prog->envp),
	     auxc = auxv_count(prog->auxv);

	char *tmp_argv[argc+1],
	     *tmp_envp[envc+1],
	     *platform      = (char *)get_aux(prog->auxv, AT_PLATFORM),
	     *base_platform = (char *)get_aux(prog->auxv, AT_BASE_PLATFORM),
	     *rand_bytes    = (char *)get_aux(prog->auxv, AT_RANDOM);

	char *sp = (char *)(prog->task_size-get_stack_random_shift(prog->auxv));

	sp -= sizeof(long);
	sp = prog->filename = stack_push_string(sp, prog->filename);

	char *untrusted_data_end=sp;
	sp = stack_push_strings(sp, tmp_envp, prog->envp);
	sp = stack_push_strings(sp, tmp_argv, prog->argv);
	taint_mem(sp, untrusted_data_end-sp, TAINT_ENV);
	sp = (char *)(((long)sp-0x100)&~0xf);

	if (platform)
		sp = platform      = stack_push_string(sp, platform);
	if (base_platform)
		sp = base_platform = stack_push_string(sp, base_platform);
	if (rand_bytes)
		sp = rand_bytes    = stack_push_data(sp, rand_bytes, 16);

	sp = (char *)((long)sp&~0xf);

	sp = stack_push_data(sp, prog->auxv, (auxc+1)*2*sizeof(long));
	prog->auxv = (long *)sp;

	sp = stack_push_data(sp, tmp_envp, (envc+1)*sizeof(char *));
	prog->envp = (char **)sp;

	sp = stack_push_data(sp, tmp_argv, (argc+1)*sizeof(char *));
	prog->argv = (char **)sp;

	sp = stack_push_data(sp, &argc, sizeof(long));

	set_aux(prog->auxv, AT_EXECFN, (long)prog->filename);
	set_aux(prog->auxv, AT_PLATFORM, (long)platform);
	set_aux(prog->auxv, AT_BASE_PLATFORM, (long)base_platform);
	set_aux(prog->auxv, AT_RANDOM, (long)rand_bytes);
	set_aux(prog->auxv, AT_PHDR, (long)prog->bin.phdr);
	set_aux(prog->auxv, AT_PHNUM, prog->bin.hdr.e_phnum);
	set_aux(prog->auxv, AT_BASE, prog->bin.base);
	set_aux(prog->auxv, AT_ENTRY, prog->bin.base + prog->bin.hdr.e_entry);

	prog->sp = (long *)sp;
}
Beispiel #2
0
/* Return hook (executed after the return instruction) */
static int getsockname_ret(void *opaque)
{
  static int offset  = 0;
  int read_err = 0;
  uint32_t bufRealLen = 0;
  getsockname_t *s = (getsockname_t *)opaque;
  struct sockaddr_in addrData;
  char addrStr[INET_ADDRSTRLEN];

  /* Remove return hook */
  hookapi_remove_hook(s->hook_handle);

  /* Check return value -> status */
  uint32_t eax = 0;
  read_reg(eax_reg, &eax);
  if (eax != 0) return 0;

  /* Read size of address structure */
  read_err = read_mem(s->bufLenPtr, 4, (unsigned char*)&bufRealLen);
  if (!read_err) {
    WRITE ("tracenetlog","\tNumBytesWritten: %u\n",bufRealLen);
  }
  else {
    WRITE ("tracenetlog","\tCould not get number of bytes written\n");
    return 0;
  }

  /* Read the address structure */
  read_err = read_mem(s->bufStart, 16, (unsigned char*)&addrData);
  if (read_err) return 0;

  /* Print the address structure */
  inet_ntop(AF_INET, &addrData.sin_addr, addrStr, sizeof(addrStr));
  WRITE ("tracenetlog","\tFamily: %d Port: %u Address: %s\n",
   addrData.sin_family,ntohs(addrData.sin_port),addrStr);

  /* Taint address structure */
  if (bufRealLen > 0) {
    hook_taint_record_t tr;
    tr.source = TAINT_SOURCE_API_SOCK_INFO_IN;
    tr.origin = GETSOCKNAME_ORIGIN;
    tr.offset = offset;

    taint_mem(s->bufStart+2, 6, (void *)&tr);
  }

  /* Increment the taint offset */
  offset += 6;

  /* Free structure used to pass info between call and return hooks */
  if (s) free(s);

  return 0;
}
Beispiel #3
0
static void taint_iov(struct iovec *iov, int iocnt, unsigned long size, int type)
{
	unsigned long v_size;
	while (size > 0)
	{
		v_size = iov->iov_len;
		if (v_size > size)
			v_size = size;
		size -= v_size;
		taint_mem(iov->iov_base, v_size, type);
		iov++;
	}
}
Beispiel #4
0
void do_taint(long ret, long call, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
{
	if (ret < 0)
		return;

	switch (call)
	{
		case __NR_read:
			taint_mem((char *)arg2, ret, taint_val(arg1));
			return;
		case __NR_readv:
			taint_iov( (struct iovec *)arg2, arg3, ret, taint_val(arg1));
			return;
		case __NR_open:
		case __NR_creat:
		case __NR_openat:
			set_fd(ret, FD_FILE);

			if (strcmp((char *)(call == __NR_openat ? arg2 : arg1), "/proc/self/stat") == 0)
			{
				taint_val(ret);
				fake_proc_self_stat(ret);
			}
			return;
		case __NR_dup:
		case __NR_dup2:
			set_fd( ret, get_thread_ctx()->files->fd_type[arg1]);
			return;
		case __NR_pipe:
			set_fd( ((long *)arg1)[0], FD_SOCKET);
			set_fd( ((long *)arg1)[1], FD_SOCKET);
			return;
		case __NR_socketcall:
		{
			long *sockargs = (long *)arg2;

			switch (arg1)
			{
				case SYS_GETPEERNAME:
					if ( (ret >= 0) && sockargs[1] && sockargs[2])
						taint_mem((char *)sockargs[1], *(long *)sockargs[2], TAINT_SOCKADDR);
					return;
				case SYS_ACCEPT:
					if ( (ret >= 0) && sockargs[1] && sockargs[2])
						taint_mem((char *)sockargs[1], *(long *)sockargs[2], TAINT_SOCKADDR);
				case SYS_SOCKET:
					set_fd(ret, FD_SOCKET);
					return;
				case SYS_RECV:
				case SYS_RECVFROM:
					taint_mem((char *)sockargs[1], ret, TAINT_SOCKET);
					return;
				case SYS_RECVMSG:
				{
					struct msghdr *msg = (struct msghdr *)sockargs[1];
					taint_iov( msg->msg_iov, msg->msg_iovlen, ret, TAINT_SOCKET );
					return;
				}
				default:
					return;
			}
		}
		default:
			return;
	}
}