Example #1
0
/*!
 * @brief Add an exception to a packet.
 * @details When adding an exception, both a TLV_EXCEPTION_CODE and TLV_EXCEPTION_STRING
 *          are added to the packet.
 * @param packet Pointer to the packet to add the detail to.
 * @param code Exception code.
 * @param fmt Form string for the exception string.
 * @param ... Varargs for the format string.
 * @return Indication of success or failure.
 * @retval ERROR_NOT_ENOUGH_MEMORY Unable to allocate memory for the request packet.
 * @retval ERROR_SUCCESS Transmission was successful.
 */
DWORD packet_add_exception(Packet *packet, DWORD code, PCHAR fmt, ...)
{
	DWORD codeNbo = htonl(code);
	char buf[8192];
	Tlv entries[2];
	va_list ap;

	// Ensure null termination
	buf[sizeof(buf)-1] = 0;

	va_start(ap, fmt);
	_vsnprintf(buf, sizeof(buf)-1, fmt, ap);
	va_end(ap);

	// Populate the TLV group array
	entries[0].header.type = TLV_TYPE_EXCEPTION_CODE;
	entries[0].header.length = 4;
	entries[0].buffer = (PUCHAR)&codeNbo;
	entries[1].header.type = TLV_TYPE_EXCEPTION_STRING;
	entries[1].header.length = (DWORD)strlen(buf) + 1;
	entries[1].buffer = (PUCHAR)buf;

	// Add the TLV group, or try to at least.
	return packet_add_tlv_group(packet, TLV_TYPE_EXCEPTION, entries, 2);
}
Example #2
0
/*
 * Returns zero or more routes to the requestor from the active routing table
 */
DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	PMIB_IPFORWARDTABLE table = NULL;
	DWORD tableSize = sizeof(MIB_IPFORWARDROW) * 96;
	DWORD index;

	do
	{
		// Allocate storage for the routing table
		if (!(table = (PMIB_IPFORWARDTABLE)malloc(tableSize)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the routing table
		if (GetIpForwardTable(table, &tableSize, TRUE) != NO_ERROR)
		{
			result = GetLastError();
			break;
		}

		// Enumerate it
		for (index = 0;
		     index < table->dwNumEntries;
		     index++)
		{
			Tlv route[3];

			route[0].header.type   = TLV_TYPE_SUBNET;
			route[0].header.length = sizeof(DWORD);
			route[0].buffer        = (PUCHAR)&table->table[index].dwForwardDest;
			route[1].header.type   = TLV_TYPE_NETMASK;
			route[1].header.length = sizeof(DWORD);
			route[1].buffer        = (PUCHAR)&table->table[index].dwForwardMask;
			route[2].header.type   = TLV_TYPE_GATEWAY;
			route[2].header.length = sizeof(DWORD);
			route[2].buffer        = (PUCHAR)&table->table[index].dwForwardNextHop;

			packet_add_tlv_group(response, TLV_TYPE_NETWORK_ROUTE,
					route, 3);
		}

	} while (0);

	if (table)
		free(table);

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Example #3
0
/*
 * Write the supplied buffer to the remote endpoint of the channel.
 *
 * This will cause the passed buffer to be written in channel->ops.buffered on the
 * remote endpoint.
 */
DWORD channel_write_to_remote(Remote *remote, Channel *channel, PUCHAR chunk,
                              ULONG chunkLength, PULONG bytesWritten)
{
    Packet *request = packet_create(PACKET_TLV_TYPE_REQUEST,
                                    "core_channel_write");
    DWORD res = ERROR_SUCCESS;
    Tlv entries[2];
    DWORD idNbo;

    do
    {
        // Did the allocation fail?
        if (!request)
        {
            res = ERROR_NOT_ENOUGH_MEMORY;
            break;
        }

        idNbo = htonl(channel_get_id(channel));

        entries[0].header.type   = TLV_TYPE_CHANNEL_ID;
        entries[0].header.length = sizeof(DWORD);
        entries[0].buffer        = (PUCHAR)&idNbo;

        // if the channel data is ment to be compressed, compress it!
        if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) )
            entries[1].header.type = TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED;
        else
            entries[1].header.type = TLV_TYPE_CHANNEL_DATA;

        entries[1].header.length = chunkLength;
        entries[1].buffer        = chunk;

        // Add the TLV data
        if ((res = packet_add_tlv_group(request, TLV_TYPE_CHANNEL_DATA_GROUP, entries, 2)) != ERROR_SUCCESS)
            break;

        // Transmit the packet
        res = packet_transmit(remote, request, NULL);

    } while (0);

    return res;
}
Example #4
0
/*!
 * @brief Add an environment variable / value pair to a response packet.
 * @param response The \c Response packet to add the values to.
 * @param envVar The name of the environment variable to add.
 * @param envVal The value of the environment.
 */
VOID add_env_pair(Packet *response, char * envVar, char *envVal)
{
	Tlv entries[2] = { 0 };

	if (envVal)
	{
		entries[0].header.type = TLV_TYPE_ENV_VARIABLE;
		entries[0].header.length = (DWORD)strlen(envVar) + 1;
		entries[0].buffer = (PUCHAR)envVar;

		entries[1].header.type = TLV_TYPE_ENV_VALUE;
		entries[1].header.length = (DWORD)strlen(envVal) + 1;
		entries[1].buffer = (PUCHAR)envVal;

		packet_add_tlv_group(response, TLV_TYPE_ENV_GROUP, entries, 2);
	}
	else
	{
		dprintf("[ENV] No value found for %s", envVar);
	}
}
Example #5
0
// 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;
}
Example #6
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;
}
DWORD linux_get_connection_table(Remote *remote, Packet *response)
{
	struct connection_table *table_connection = NULL;
	__u32 local_port_be, remote_port_be, uid_be, inode_be;
	__u32 index;
	DWORD result;

	dprintf("getting connection list through /proc/net");
	result = linux_proc_get_connection_table(&table_connection);
	dprintf("result = %d, table_connection = 0x%p , entries : %d", result, table_connection, table_connection->entries);

	for(index = 0; index < table_connection->entries; index++) {
		Tlv connection[9];
		if (table_connection->table[index].type == AF_INET) {
			connection[0].header.type      = TLV_TYPE_LOCAL_HOST_RAW;
			connection[0].header.length    = sizeof(__u32);
			connection[0].buffer           = (PUCHAR)&table_connection->table[index].local_addr.addr;

			connection[1].header.type      = TLV_TYPE_PEER_HOST_RAW;
			connection[1].header.length    = sizeof(__u32);
			connection[1].buffer           = (PUCHAR)&table_connection->table[index].remote_addr.addr;
		}
		else {
			connection[0].header.type      = TLV_TYPE_LOCAL_HOST_RAW;
			connection[0].header.length    = sizeof(__u128);
			connection[0].buffer           = (PUCHAR)&table_connection->table[index].local_addr.addr6;

			connection[1].header.type      = TLV_TYPE_PEER_HOST_RAW;
			connection[1].header.length    = sizeof(__u128);
			connection[1].buffer           = (PUCHAR)&table_connection->table[index].remote_addr.addr6;
		}

		local_port_be = htonl(table_connection->table[index].local_port & 0x0000ffff);
		connection[2].header.type      = TLV_TYPE_LOCAL_PORT;
		connection[2].header.length    = sizeof(__u32);
		connection[2].buffer           = (PUCHAR)&local_port_be;

		remote_port_be = htonl(table_connection->table[index].remote_port & 0x0000ffff);
		connection[3].header.type      = TLV_TYPE_PEER_PORT;
		connection[3].header.length    = sizeof(__u32);
		connection[3].buffer           = (PUCHAR)&remote_port_be;

		connection[4].header.type      = TLV_TYPE_MAC_NAME;
		connection[4].header.length    = strlen(table_connection->table[index].protocol) + 1;
		connection[4].buffer           = (PUCHAR)(table_connection->table[index].protocol);

		connection[5].header.type      = TLV_TYPE_SUBNET_STRING;
		connection[5].header.length    = strlen(table_connection->table[index].state) + 1;
		connection[5].buffer           = (PUCHAR)(table_connection->table[index].state);

		uid_be = htonl(table_connection->table[index].uid);
		connection[6].header.type      = TLV_TYPE_PID;
		connection[6].header.length    = sizeof(__u32);
		connection[6].buffer           = (PUCHAR)&uid_be;

		inode_be = htonl(table_connection->table[index].inode);
		connection[7].header.type      = TLV_TYPE_ROUTE_METRIC;
		connection[7].header.length    = sizeof(__u32);
		connection[7].buffer           = (PUCHAR)&inode_be;

		connection[8].header.type      = TLV_TYPE_PROCESS_NAME;
		connection[8].header.length    = strlen(table_connection->table[index].program_name) + 1;
		connection[8].buffer           = (PUCHAR)(table_connection->table[index].program_name);

		packet_add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 9);
	}
	dprintf("sent %d connections", table_connection->entries);

	if (table_connection)
		free(table_connection);

}
DWORD windows_get_connection_table(Remote *remote, Packet *response)
{
	struct connection_table *table_connection = NULL;
	struct connection_entry * current_connection;
	DWORD dwRetVal;
	int index;
	DWORD local_port_be, remote_port_be;

	table_connection = (struct connection_table *)calloc(sizeof(struct connection_table) + 10 * sizeof(struct connection_entry), 1);
	table_connection->max_entries = 10;

	dwRetVal = windows_get_tcp_table(&table_connection);
	if (dwRetVal == ERROR_NOT_ENOUGH_MEMORY)
		return ERROR_NOT_ENOUGH_MEMORY;

	dwRetVal = windows_get_udp_table(&table_connection);
	if (dwRetVal == ERROR_NOT_ENOUGH_MEMORY)
		return ERROR_NOT_ENOUGH_MEMORY;


	for(index = 0; index < table_connection->entries; index++) {
		Tlv connection[7];
		current_connection = &table_connection->table[index];
		if (current_connection->type == AF_INET) {
			connection[0].header.type      = TLV_TYPE_LOCAL_HOST_RAW;
			connection[0].header.length    = sizeof(__u32);
			connection[0].buffer           = (PUCHAR)&current_connection->local_addr.addr;

			connection[1].header.type      = TLV_TYPE_PEER_HOST_RAW;
			connection[1].header.length    = sizeof(__u32);
			connection[1].buffer           = (PUCHAR)&current_connection->remote_addr.addr;
		}
		else {
			connection[0].header.type      = TLV_TYPE_LOCAL_HOST_RAW;
			connection[0].header.length    = sizeof(__u128);
			connection[0].buffer           = (PUCHAR)&current_connection->local_addr.addr6;

			connection[1].header.type      = TLV_TYPE_PEER_HOST_RAW;
			connection[1].header.length    = sizeof(__u128);
			connection[1].buffer           = (PUCHAR)&current_connection->remote_addr.addr6;
		}

		local_port_be = htonl(current_connection->local_port);
		connection[2].header.type      = TLV_TYPE_LOCAL_PORT;
		connection[2].header.length    = sizeof(__u32);
		connection[2].buffer           = (PUCHAR)&local_port_be;

		remote_port_be = htonl(current_connection->remote_port);
		connection[3].header.type      = TLV_TYPE_PEER_PORT;
		connection[3].header.length    = sizeof(__u32);
		connection[3].buffer           = (PUCHAR)&remote_port_be;

		connection[4].header.type      = TLV_TYPE_MAC_NAME;
		connection[4].header.length    = strlen(current_connection->protocol) + 1;
		connection[4].buffer           = (PUCHAR)(current_connection->protocol);

		connection[5].header.type      = TLV_TYPE_SUBNET_STRING;
		connection[5].header.length    = strlen(current_connection->state) + 1;
		connection[5].buffer           = (PUCHAR)(current_connection->state);

		connection[6].header.type      = TLV_TYPE_PROCESS_NAME;
		connection[6].header.length    = strlen(current_connection->program_name) + 1;
		connection[6].buffer           = (PUCHAR)(current_connection->program_name);

		packet_add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 7);
	}
	dprintf("sent %d connections", table_connection->entries);

	if (table_connection)
		free(table_connection);

	return ERROR_SUCCESS;
}
Example #9
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;
}
Example #10
0
DWORD get_interfaces_windows(Remote *remote, Packet *response) {
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;
	// Most of the time we'll need:
	//   index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
	// In some cases, the interface will have multiple addresses, so we'll realloc
	// this when necessary, but this will cover the common case.
	DWORD allocd_entries = 20;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 20);
	int prefixes[30];
	int prefixes_cnt = 0;

	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;

	ULONG flags = GAA_FLAG_INCLUDE_PREFIX
		| GAA_FLAG_SKIP_DNS_SERVER
		| GAA_FLAG_SKIP_MULTICAST
		| GAA_FLAG_SKIP_ANYCAST;

	LPSOCKADDR sockaddr;

	ULONG family = AF_UNSPEC;
	IP_ADAPTER_ADDRESSES *pAdapters = NULL;
	IP_ADAPTER_ADDRESSES *pCurr = NULL;
	ULONG outBufLen = 0;
	DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);

	// Use the newer version so we're guaranteed to have a large enough struct.
	// Unfortunately, using these probably means it won't compile on older
	// versions of Visual Studio.  =(
	IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
	IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
	// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
	// Since we request older versions of things, we have to be explicit
	// when using newer structs.
	IP_ADAPTER_PREFIX_XP *pPrefix = NULL;

	do
	{
		gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
				GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
			);
		if (!gaa) {
			result = get_interfaces_windows_mib(remote, response);
			break;
		}

		gaa(family, flags, NULL, pAdapters, &outBufLen);
		if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
		if (gaa(family, flags, NULL, pAdapters, &outBufLen))
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(pCurr->IfIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->PhysicalAddress;
			tlv_cnt++;

			entries[tlv_cnt].header.length = wcslen(pCurr->Description)*2 + 1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->Description;
			tlv_cnt++;

			mtu_bigendian            = htonl(pCurr->Mtu);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			if (pCurr->Length > 68) {
				// Then this is a Longhorn struct version and it contains the
				// FirstPrefix member, save it for later in case we don't have
				// an OnLinkPrefixLength
				pPrefix = pCurr->FirstPrefix;
			}

			for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
			{
				sockaddr = pAddr->Address.lpSockaddr;
				if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) {
					// Skip interfaces that aren't IP
					continue;
				}

				// This loop can add up to three Tlv's - one for address, one
				// for scope_id, one for netmask.  Go ahead and allocate enough
				// room for all of them.
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}

				if (pAddr->Length > 44) {
					// Then this is Vista+ and the OnLinkPrefixLength member
					// will be populated
					prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength);
				}
				if (pPrefix && 0 == prefixes[prefixes_cnt]) {
					// Otherwise, we have to walk the FirstPrefix linked list
					prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength);
					pPrefix = pPrefix->Next;
				} else {
					// This is XP SP0 and as far as I can tell, we have no way
					// of determining the netmask short of bailing on
					// this method and falling back to MIB, which doesn't
					// return IPv6 addresses. Older versions (e.g. NT4, 2k)
					// don't have GetAdapterAddresses, so they will have fallen
					// through earlier to the MIB implementation.
					free(entries);
					free(pAdapters);
					return get_interfaces_windows_mib(remote, response);
				}

				if (prefixes[prefixes_cnt]) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX;
					entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt];
					tlv_cnt++;
					prefixes_cnt++;
				}

				if (sockaddr->sa_family == AF_INET) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
					tlv_cnt++;

				} else {
					entries[tlv_cnt].header.length = 16;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
					tlv_cnt++;

					entries[tlv_cnt].header.length = sizeof(DWORD);
					entries[tlv_cnt].header.type = TLV_TYPE_IP6_SCOPE;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
					tlv_cnt++;
				}

			}
			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
					entries, tlv_cnt);
		}
	} while (0);

	if (entries)
		free(entries);
	if (pAdapters)
		free(pAdapters);

	return result;
}
Example #11
0
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
{
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;

	Tlv entries[6];
	PMIB_IPADDRTABLE table = NULL;
	DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
	DWORD index;
	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;
	MIB_IFROW iface;

	do
	{
		// Allocate memory for reading addresses into
		if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the IP address table
		if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (index = 0; index < table->dwNumEntries; index++)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(table->table[index].dwIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_IP;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwAddr;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwMask;
			tlv_cnt++;

			iface.dwIndex = table->table[index].dwIndex;

			// If interface information can get gotten, use it.
			if (GetIfEntry(&iface) == NO_ERROR)
			{
				entries[tlv_cnt].header.length = iface.dwPhysAddrLen;
				entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
				entries[tlv_cnt].buffer = (PUCHAR)iface.bPhysAddr;
				tlv_cnt++;

				mtu_bigendian = htonl(iface.dwMtu);
				entries[tlv_cnt].header.length = sizeof(DWORD);
				entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
				entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
				tlv_cnt++;

				if (iface.bDescr)
				{
					entries[tlv_cnt].header.length = iface.dwDescrLen + 1;
					entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
					entries[tlv_cnt].buffer = (PUCHAR)iface.bDescr;
					tlv_cnt++;
				}
			}

			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
			entries, tlv_cnt);
		}

	} while (0);

	if (table)
		free(table);

	return result;
}
Example #12
0
#include "precomp.h"

#ifdef _WIN32
#include <iptypes.h>
#include <ws2ipdef.h>
#endif

#ifdef _WIN32
DWORD get_interfaces_windows_mib(Remote *remote, Packet *response)
{
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;

	Tlv entries[6];
	PMIB_IPADDRTABLE table = NULL;
	DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
	DWORD index;
	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;
	MIB_IFROW iface;

	do
	{
		// Allocate memory for reading addresses into
		if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the IP address table
		if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (index = 0; index < table->dwNumEntries; index++)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(table->table[index].dwIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_IP;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwAddr;
			tlv_cnt++;

			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type = TLV_TYPE_NETMASK;
			entries[tlv_cnt].buffer = (PUCHAR)&table->table[index].dwMask;
			tlv_cnt++;

			iface.dwIndex = table->table[index].dwIndex;

			// If interface information can get gotten, use it.
			if (GetIfEntry(&iface) == NO_ERROR)
			{
				entries[tlv_cnt].header.length = iface.dwPhysAddrLen;
				entries[tlv_cnt].header.type = TLV_TYPE_MAC_ADDR;
				entries[tlv_cnt].buffer = (PUCHAR)iface.bPhysAddr;
				tlv_cnt++;

				mtu_bigendian = htonl(iface.dwMtu);
				entries[tlv_cnt].header.length = sizeof(DWORD);
				entries[tlv_cnt].header.type = TLV_TYPE_INTERFACE_MTU;
				entries[tlv_cnt].buffer = (PUCHAR)&mtu_bigendian;
				tlv_cnt++;

				if (iface.bDescr)
				{
					entries[tlv_cnt].header.length = iface.dwDescrLen + 1;
					entries[tlv_cnt].header.type = TLV_TYPE_MAC_NAME;
					entries[tlv_cnt].buffer = (PUCHAR)iface.bDescr;
					tlv_cnt++;
				}
			}

			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
			entries, tlv_cnt);
		}

	} while (0);

	if (table)
		free(table);

	return result;
}


DWORD get_interfaces_windows(Remote *remote, Packet *response) {
	DWORD result = ERROR_SUCCESS;
	DWORD tlv_cnt;
	// Most of the time we'll need:
	//   index, name (description), MAC addr, mtu, flags, IP addr, netmask, maybe scope id
	// In some cases, the interface will have multiple addresses, so we'll realloc
	// this when necessary, but this will cover the common case.
	DWORD allocd_entries = 20;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 20);
	int prefixes[30];
	int prefixes_cnt = 0;

	DWORD mtu_bigendian;
	DWORD interface_index_bigendian;

	ULONG flags = GAA_FLAG_INCLUDE_PREFIX
		| GAA_FLAG_SKIP_DNS_SERVER
		| GAA_FLAG_SKIP_MULTICAST
		| GAA_FLAG_SKIP_ANYCAST;

	LPSOCKADDR sockaddr;

	ULONG family = AF_UNSPEC;
	IP_ADAPTER_ADDRESSES *pAdapters = NULL;
	IP_ADAPTER_ADDRESSES *pCurr = NULL;
	ULONG outBufLen = 0;
	DWORD (WINAPI *gaa)(DWORD, DWORD, void *, void *, void *);

	// Use the newer version so we're guaranteed to have a large enough struct.
	// Unfortunately, using these probably means it won't compile on older
	// versions of Visual Studio.  =(
	IP_ADAPTER_UNICAST_ADDRESS_LH *pAddr = NULL;
	IP_ADAPTER_UNICAST_ADDRESS_LH *pPref = NULL;
	// IP_ADAPTER_PREFIX is only defined if NTDDI_VERSION > NTDDI_WINXP
	// Since we request older versions of things, we have to be explicit
	// when using newer structs.
	IP_ADAPTER_PREFIX_XP *pPrefix = NULL;

	do
	{
		gaa = (DWORD (WINAPI *)(DWORD,DWORD,void*,void*,void*))GetProcAddress(
				GetModuleHandle("iphlpapi"), "GetAdaptersAddresses"
			);
		if (!gaa) {
			result = get_interfaces_windows_mib(remote, response);
			break;
		}

		gaa(family, flags, NULL, pAdapters, &outBufLen);
		if (!(pAdapters = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
		if (gaa(family, flags, NULL, pAdapters, &outBufLen))
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (pCurr = pAdapters; pCurr; pCurr = pCurr->Next)
		{
			tlv_cnt = 0;

			interface_index_bigendian = htonl(pCurr->IfIndex);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = pCurr->PhysicalAddressLength;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->PhysicalAddress;
			tlv_cnt++;

			entries[tlv_cnt].header.length = wcslen(pCurr->Description)*2 + 1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)pCurr->Description;
			tlv_cnt++;

			mtu_bigendian            = htonl(pCurr->Mtu);
			entries[tlv_cnt].header.length = sizeof(DWORD);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			if (pCurr->Length > 68) {
				// Then this is a Longhorn struct version and it contains the
				// FirstPrefix member, save it for later in case we don't have
				// an OnLinkPrefixLength
				pPrefix = pCurr->FirstPrefix;
			}

			for (pAddr = (void*)pCurr->FirstUnicastAddress; pAddr; pAddr = (void*)pAddr->Next)
			{
				sockaddr = pAddr->Address.lpSockaddr;
				if (AF_INET != sockaddr->sa_family && AF_INET6 != sockaddr->sa_family) {
					// Skip interfaces that aren't IP
					continue;
				}

				// This loop can add up to three Tlv's - one for address, one
				// for scope_id, one for netmask.  Go ahead and allocate enough
				// room for all of them.
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}

				if (pAddr->Length > 44) {
					// Then this is Vista+ and the OnLinkPrefixLength member
					// will be populated
					prefixes[prefixes_cnt] = htonl(pAddr->OnLinkPrefixLength);
				}
				if (pPrefix && 0 == prefixes[prefixes_cnt]) {
					// Otherwise, we have to walk the FirstPrefix linked list
					prefixes[prefixes_cnt] = htonl(pPrefix->PrefixLength);
					pPrefix = pPrefix->Next;
				} else {
					// This is XP SP0 and as far as I can tell, we have no way
					// of determining the netmask short of bailing on
					// this method and falling back to MIB, which doesn't
					// return IPv6 addresses. Older versions (e.g. NT4, 2k)
					// don't have GetAdapterAddresses, so they will have fallen
					// through earlier to the MIB implementation.
					free(entries);
					free(pAdapters);
					return get_interfaces_windows_mib(remote, response);
				}

				if (prefixes[prefixes_cnt]) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP_PREFIX;
					entries[tlv_cnt].buffer = (PUCHAR)&prefixes[prefixes_cnt];
					tlv_cnt++;
					prefixes_cnt++;
				}

				if (sockaddr->sa_family == AF_INET) {
					entries[tlv_cnt].header.length = 4;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr);
					tlv_cnt++;

				} else {
					entries[tlv_cnt].header.length = 16;
					entries[tlv_cnt].header.type = TLV_TYPE_IP;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr);
					tlv_cnt++;

					entries[tlv_cnt].header.length = sizeof(DWORD);
					entries[tlv_cnt].header.type = TLV_TYPE_IP6_SCOPE;
					entries[tlv_cnt].buffer = (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id);
					tlv_cnt++;
				}

			}
			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
					entries, tlv_cnt);
		}
	} while (0);

	if (entries)
		free(entries);
	if (pAdapters)
		free(pAdapters);

	return result;
}

#else /* _WIN32 */
int get_interfaces_linux(Remote *remote, Packet *response) {
	struct ifaces_list *ifaces = NULL;
	int i;
	int result;
	uint32_t interface_index_bigendian, mtu_bigendian;
	DWORD allocd_entries = 10;
	Tlv *entries = (Tlv *)malloc(sizeof(Tlv) * 10);

	dprintf("Grabbing interfaces");
	result = netlink_get_interfaces(&ifaces);
	dprintf("Got 'em");

	if (!result) {
		for (i = 0; i < ifaces->entries; i++) {
			int tlv_cnt = 0;
			int j = 0;
			dprintf("Building TLV for iface %d", i);

			entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].name)+1;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_NAME;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].name;
			tlv_cnt++;

			entries[tlv_cnt].header.length = 6;
			entries[tlv_cnt].header.type   = TLV_TYPE_MAC_ADDR;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].hwaddr;
			tlv_cnt++;

			mtu_bigendian            = htonl(ifaces->ifaces[i].mtu);
			entries[tlv_cnt].header.length = sizeof(uint32_t);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_MTU;
			entries[tlv_cnt].buffer        = (PUCHAR)&mtu_bigendian;
			tlv_cnt++;

			entries[tlv_cnt].header.length = strlen(ifaces->ifaces[i].flags)+1;
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_FLAGS;
			entries[tlv_cnt].buffer        = (PUCHAR)ifaces->ifaces[i].flags;
			tlv_cnt++;

			interface_index_bigendian = htonl(ifaces->ifaces[i].index);
			entries[tlv_cnt].header.length = sizeof(uint32_t);
			entries[tlv_cnt].header.type   = TLV_TYPE_INTERFACE_INDEX;
			entries[tlv_cnt].buffer        = (PUCHAR)&interface_index_bigendian;
			tlv_cnt++;

			for (j = 0; j < ifaces->ifaces[i].addr_count; j++) {
				if (allocd_entries < tlv_cnt+3) {
					entries = realloc(entries, sizeof(Tlv) * (tlv_cnt+3));
					allocd_entries += 3;
				}
				if (ifaces->ifaces[i].addr_list[j].family == AF_INET) {
					dprintf("ip addr for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u32);
					entries[tlv_cnt].header.type   = TLV_TYPE_IP;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr;
					tlv_cnt++;

					//dprintf("netmask for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u32);
					entries[tlv_cnt].header.type   = TLV_TYPE_NETMASK;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask;
					tlv_cnt++;
				} else {
					dprintf("-- ip six addr for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u128);
					entries[tlv_cnt].header.type   = TLV_TYPE_IP;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].ip.addr6;
					tlv_cnt++;

					//dprintf("netmask6 for %s", ifaces->ifaces[i].name);
					entries[tlv_cnt].header.length = sizeof(__u128);
					entries[tlv_cnt].header.type   = TLV_TYPE_NETMASK;
					entries[tlv_cnt].buffer        = (PUCHAR)&ifaces->ifaces[i].addr_list[j].nm.netmask6;
					tlv_cnt++;
				}
			}

			dprintf("Adding TLV to group");
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, tlv_cnt);
			dprintf("done Adding TLV to group");
		}
	}

	if (ifaces)
		free(ifaces);
	if (entries)
		free(entries);


	return result;
}
Example #13
0
/*!
 * @brief Perform a WMI query.
 * @param lpwRoot Name of the root object that is to be queried against.
 * @param lpwQuery The filter to use when reading objects (LDAP style).
 * @param response The response \c Packet to add the results to.
 */
DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
{
	HRESULT hResult;

	dprintf("[WMI] Initialising COM");
	if ((hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED)) == S_OK)
	{
		dprintf("[WMI] COM initialised");
		IWbemLocator* pLocator = NULL;
		IWbemServices* pServices = NULL;
		IEnumWbemClassObject* pEnumerator = NULL;
		IWbemClassObject* pSuperClass = NULL;
		IWbemClassObject* pObj = NULL;
		Tlv* valueTlvs = NULL;
		char* values = NULL;
		VARIANT** fields = NULL;

		do
		{
			if (FAILED(hResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0)))
			{
				dprintf("[WMI] Failed to initialize security: %x", hResult);
				break;
			}
			dprintf("[WMI] Security initialised");

			if (FAILED(hResult = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator))))
			{
				dprintf("[WMI] Failed to create WbemLocator: %x", hResult);
				break;
			}
			dprintf("[WMI] WbemLocator created.");

			if (FAILED(hResult = pLocator->ConnectServer(_bstr_t(lpwRoot), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pServices)))
			{
				dprintf("[WMI] Failed to create WbemServices at %S: %x", lpwRoot, hResult);
				break;
			}
			dprintf("[WMI] WbemServices created.");

			if (FAILED(hResult = pServices->ExecQuery(L"WQL", lpwQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator)))
			{
				dprintf("[WMI] Failed to create Enumerator for query %S: %x", lpwQuery, hResult);
				break;
			}
			dprintf("[WMI] Enumerated created.");

			ULONG numFound;
			if (FAILED(hResult = pEnumerator->Next(ENUM_TIMEOUT, 1, &pObj, &numFound)))
			{
				dprintf("[WMI] Failed to get the first query element: %x", lpwQuery, hResult);
				break;
			}
			dprintf("[WMI] First result read. hr=%x p=%p", hResult, pObj);

			if (hResult == WBEM_S_FALSE)
			{
				// this is not an error
				dprintf("[WMI] No results found!");
				break;
			}

			// get the names of the fields out of the first object before doing anything else.
			LPSAFEARRAY pFieldArray = NULL;
			if (FAILED(hResult = pObj->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &pFieldArray)))
			{
				dprintf("[WMI] Failed to get field names: %x", hResult);
				break;
			}
			dprintf("[WMI] Field Names extracted. hr=%x p=%p", hResult, pFieldArray);

			// lock the array
			if (FAILED(hResult = SafeArrayLock(pFieldArray)))
			{
				dprintf("[WMI] Failed to get array dimension: %x", hResult);
				break;
			}
			dprintf("[WMI] Field name array locked.");

			do
			{
				dprintf("[WMI] Array dimensions: %u", SafeArrayGetDim(pFieldArray));

				// this array is just one dimension, let's get the bounds of the first dimension
				LONG lBound, uBound;
				if (FAILED(hResult = SafeArrayGetLBound(pFieldArray, 1, &lBound))
					|| FAILED(hResult = SafeArrayGetUBound(pFieldArray, 1, &uBound)))
				{
					dprintf("[WMI] Failed to get array dimensions: %x", hResult);
					break;
				}
				dprintf("[WMI] Bounds: %u to %u", lBound, uBound);

				LONG fieldCount = uBound - lBound - SYSTEM_FIELD_COUNT - 1;
				dprintf("[WMI] Query results in %u fields", fieldCount);

				fields = (VARIANT**)malloc(fieldCount * sizeof(VARIANT**));
				valueTlvs = (Tlv*)malloc(fieldCount * sizeof(Tlv));
				values = (char*)malloc(fieldCount * FIELD_SIZE);
				memset(fields, 0, fieldCount * sizeof(VARIANT**));
				memset(valueTlvs, 0, fieldCount * sizeof(Tlv));
				memset(values, 0, fieldCount * FIELD_SIZE);

				for (LONG i = 0; i < fieldCount; ++i)
				{
					LONG indices[1] = { i + SYSTEM_FIELD_COUNT };
					char* fieldName = values + (i * FIELD_SIZE);
					SafeArrayPtrOfIndex(pFieldArray, indices, (void**)&fields[i]);
					_bstr_t bstr(fields[i]->bstrVal);

					strncpy_s(fieldName, FIELD_SIZE, (const char*)bstr, FIELD_SIZE - 1);

					valueTlvs[i].header.type = TLV_TYPE_EXT_WMI_FIELD;
					valueTlvs[i].header.length = (UINT)strlen(fieldName) + 1;
					valueTlvs[i].buffer = (PUCHAR)fieldName;

					dprintf("[WMI] Added header field: %s", fieldName);
				}

				dprintf("[WMI] added all field headers");
				// add the field names to the packet
				packet_add_tlv_group(response, TLV_TYPE_EXT_WMI_FIELDS, valueTlvs, fieldCount);

				dprintf("[WMI] processing values...");
				// with that horrible pain out of the way, let's actually grab the data
				do
				{
					if (FAILED(hResult))
					{
						dprintf("[WMI] Loop exited via %x", hResult);
						break;
					}

					memset(valueTlvs, 0, fieldCount * sizeof(Tlv));
					memset(values, 0, fieldCount * FIELD_SIZE);

					for (LONG i = 0; i < fieldCount; ++i)
					{
						char* value = values + (i * FIELD_SIZE);
						valueTlvs[i].header.type = TLV_TYPE_EXT_WMI_VALUE;
						valueTlvs[i].buffer = (PUCHAR)value;

						VARIANT varValue;
						VariantInit(&varValue);

						_bstr_t field(fields[i]->bstrVal);
						dprintf("[WMI] Extracting value for %s", (char*)field);
						if (SUCCEEDED(pObj->Get(field, 0, &varValue, NULL, NULL)))
						{
							variant_to_string(_variant_t(varValue), value, FIELD_SIZE);
						}

						valueTlvs[i].header.length = (UINT)strlen(value) + 1;
						dprintf("[WMI] Added value for %s: %s", (char*)_bstr_t(fields[i]->bstrVal), value);
					}

					// add the field values to the packet
					packet_add_tlv_group(response, TLV_TYPE_EXT_WMI_VALUES, valueTlvs, fieldCount);

					pObj->Release();
					pObj = NULL;
				} while ((hResult = pEnumerator->Next(ENUM_TIMEOUT, 1, &pObj, &numFound)) != WBEM_S_FALSE);

			} while (0);

			SafeArrayUnlock(pFieldArray);
		} while (0);

		if (fields)
		{
			free(fields);
		}

		if (values)
		{
			free(values);
		}

		if (valueTlvs)
		{
			free(valueTlvs);
		}

		if (pObj)
		{
			pObj->Release();
		}

		if (pEnumerator)
		{
			pEnumerator->Release();
		}

		if (pServices)
		{
			pServices->Release();
		}

		if (pLocator)
		{
			pLocator->Release();
		}
		CoUninitialize();

		if (SUCCEEDED(hResult))
		{
			hResult = S_OK;
			dprintf("[WMI] Things appeard to go well!");
		}
	}
	else
	{
		dprintf("[WMI] Failed to initialize COM");
	}

	if (FAILED(hResult))
	{
		// if we failed, we're going to convert the error to a string, add it and still return success, but we'll
		// also include the hresult.
		char errorMessage[1024];
		memset(errorMessage, 0, 1024);
		_com_error comError(hResult);
		_snprintf_s(errorMessage, 1024, 1023, "%s (0x%x)", comError.ErrorMessage(), hResult);
		dprintf("[WMI] returning error -> %s", errorMessage);
		packet_add_tlv_string(response, TLV_TYPE_EXT_WMI_ERROR, errorMessage);
		hResult = S_OK;
	}

	return (DWORD)hResult;
}
Example #14
0
/*
 * Returns zero or more local interfaces to the requestor
 */
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	DWORD entryCount;

#ifdef _WIN32
	Tlv entries[5];
	PMIB_IPADDRTABLE table = NULL;
	DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
	DWORD index;

	MIB_IFROW iface;

	do
	{
		// Allocate memory for reading addresses into
		if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the IP address table
		if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
		{
			result = GetLastError();
			break;
		}

		// Enumerate the entries
		for (index = 0;
		     index < table->dwNumEntries;
		     index++)
		{
			entryCount = 0;

			entries[entryCount].header.length = sizeof(DWORD);
			entries[entryCount].header.type   = TLV_TYPE_IP;
			entries[entryCount].buffer        = (PUCHAR)&table->table[index].dwAddr;
			entryCount++;

			entries[entryCount].header.length = sizeof(DWORD);
			entries[entryCount].header.type   = TLV_TYPE_NETMASK;
			entries[entryCount].buffer        = (PUCHAR)&table->table[index].dwMask;
			entryCount++;

			iface.dwIndex = table->table[index].dwIndex;

			// If interface information can get gotten, use it.
			if (GetIfEntry(&iface) == NO_ERROR)
			{
				entries[entryCount].header.length = iface.dwPhysAddrLen;
				entries[entryCount].header.type   = TLV_TYPE_MAC_ADDR;
				entries[entryCount].buffer        = (PUCHAR)iface.bPhysAddr;
				entryCount++;

				if (iface.bDescr)
				{
					entries[entryCount].header.length = iface.dwDescrLen + 1;
					entries[entryCount].header.type   = TLV_TYPE_MAC_NAME;
					entries[entryCount].buffer        = (PUCHAR)iface.bDescr;
					entryCount++;
				}
			}

			// Add the interface group
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
					entries, entryCount);
		}

	} while (0);

	if (table)
		free(table);

#else
	struct iface *ifaces;
	int count;
	int i;
	int if_error;
	Tlv entries[4];

	if_error = get_ifaces(&ifaces, &count);

	if (if_error) {
		result = if_error;
	} else {
		for (i = 0; i < count; i++) {

			entries[0].header.length = strlen(ifaces[i].name)+1;
			entries[0].header.type   = TLV_TYPE_MAC_NAME;
			entries[0].buffer        = (PUCHAR)ifaces[i].name;

			entries[1].header.length = 6;
			entries[1].header.type   = TLV_TYPE_MAC_ADDR;
			entries[1].buffer        = (PUCHAR)ifaces[i].hwaddr;

			entries[2].header.length = ifaces[i].addr_size;
			entries[2].header.type   = TLV_TYPE_IP;
			entries[2].buffer        = (PUCHAR)ifaces[i].addr;

			entries[3].header.length = ifaces[i].addr_size;
			entries[3].header.type   = TLV_TYPE_NETMASK;
			entries[3].buffer        = (PUCHAR)ifaces[i].netmask;
			
			packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, 4);
		}
	}

	if (ifaces)
		free_ifaces(ifaces, count);
#endif

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

	return result;
}
Example #15
0
/*!
 * @brief Handle the request to get the data from the clipboard.
 * @details This function currently only supports the following clipboard data formats:
 *             - CF_TEXT  - raw text data.
 *             - CF_DIB   - bitmap/image information.
 *             - CF_HDROP - file selection.
 *
 *          Over time more formats will be supported.
 * @param remote Pointer to the remote endpoint.
 * @param packet Pointer to the request packet.
 * @return Indication of success or failure.
 * @todo Add support for more data formats.
 */
DWORD request_clipboard_get_data(Remote *remote, Packet *packet)
{
#ifdef _WIN32
	DWORD dwResult;
	HMODULE hKernel32 = NULL;
	HMODULE hUser32 = NULL;
	HMODULE hShell32 = NULL;

	PGLOBALLOCK pGlobalLock = NULL;
	PGLOBALUNLOCK pGlobalUnlock = NULL;

	POPENCLIPBOARD pOpenClipboard = NULL;
	PCLOSECLIPBOARD pCloseClipboard = NULL;
	PGETCLIPBOARDDATA pGetClipboardData = NULL;
	PENUMCLIPBOARDFORMATS pEnumClipboardFormats = NULL;
	PDRAGQUERYFILEA pDragQueryFileA = NULL;
	PCREATEFILEA pCreateFileA = NULL;
	PCLOSEHANDLE pCloseHandle = NULL;
	PGETFILESIZEEX pGetFileSizeEx = NULL;

	HANDLE hSourceFile = NULL;
	PCHAR lpClipString = NULL;
	HGLOBAL hClipboardData = NULL;
	HDROP hFileDrop = NULL;
	UINT uFormat = 0;
	UINT uFileIndex = 0;
	UINT uFileCount = 0;
	CHAR lpFileName[MAX_PATH];
	Tlv entries[2] = { 0 };
	LARGE_INTEGER largeInt = { 0 };
	LPBITMAPINFO lpBI = NULL;
	PUCHAR lpDIB = NULL;
	ConvertedImage image;
	BOOL bImageDownload = FALSE;
	DWORD dwWidth;
	DWORD dwHeight;
	Tlv imageTlv[3];

	Packet *pResponse = packet_create_response(packet);

	do
	{
		dprintf("[EXTAPI CLIPBOARD] Loading user32.dll");
		if ((hUser32 = LoadLibraryA("user32.dll")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load user32.dll");

		dprintf("[EXTAPI CLIPBOARD] Loading kernel32.dll");
		if ((hKernel32 = LoadLibraryA("kernel32.dll")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load kernel32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for GlobalLock");
		if ((pGlobalLock = (PGLOBALLOCK)GetProcAddress(hKernel32, "GlobalLock")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalLock in kernel32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for GlobalUnlock");
		if ((pGlobalUnlock = (PGLOBALUNLOCK)GetProcAddress(hKernel32, "GlobalUnlock")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalUnlock in kernel32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for OpenClipboard");
		if ((pOpenClipboard = (POPENCLIPBOARD)GetProcAddress(hUser32, "OpenClipboard")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate OpenClipboard in user32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for CloseClipboard");
		if ((pCloseClipboard = (PCLOSECLIPBOARD)GetProcAddress(hUser32, "CloseClipboard")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in user32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for GetClipboardData");
		if ((pGetClipboardData = (PGETCLIPBOARDDATA)GetProcAddress(hUser32, "GetClipboardData")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GetClipboardData in user32.dll");

		dprintf("[EXTAPI CLIPBOARD] Searching for EnumClipboardFormats");
		if ((pEnumClipboardFormats = (PENUMCLIPBOARDFORMATS)GetProcAddress(hUser32, "EnumClipboardFormats")) == NULL)
			BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate EnumClipboardFormats in user32.dll");

		// Try to get a lock on the clipboard
		if (!pOpenClipboard(NULL)) {
			dwResult = GetLastError();
			BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Unable to open the clipboard", dwResult);
		}

		dprintf("[EXTAPI CLIPBOARD] Clipboard locked, attempting to get data...");

		while (uFormat = pEnumClipboardFormats(uFormat))
		{
			if (uFormat == CF_TEXT) {
				// there's raw text on the clipboard
				if ((hClipboardData = pGetClipboardData(CF_TEXT)) != NULL
					&& (lpClipString = (PCHAR)pGlobalLock(hClipboardData)) != NULL) {

					dprintf("[EXTAPI CLIPBOARD] Clipboard text captured: %s", lpClipString);
					packet_add_tlv_string(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT, lpClipString);

					pGlobalUnlock(hClipboardData);
				}
			}
			else if (uFormat == CF_DIB) {
				dprintf("[EXTAPI CLIPBOARD] Grabbing the clipboard bitmap data");
				// an image of some kind is on the clipboard
				if ((hClipboardData = pGetClipboardData(CF_DIB)) != NULL
					&& (lpBI = (LPBITMAPINFO)pGlobalLock(hClipboardData)) != NULL) {

					dprintf("[EXTAPI CLIPBOARD] CF_DIB grabbed, extracting dimensions.");

					// grab the bitmap image size
					dwWidth = htonl(lpBI->bmiHeader.biWidth);
					dwHeight = htonl(lpBI->bmiHeader.biHeight);

					imageTlv[0].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMX;
					imageTlv[0].header.length = sizeof(UINT);
					imageTlv[0].buffer = (PUCHAR)&dwWidth;
					imageTlv[1].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY;
					imageTlv[1].header.length = sizeof(UINT);
					imageTlv[1].buffer = (PUCHAR)&dwHeight;

					// only download the image if they want it
					bImageDownload = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD);
					dprintf("[EXTAPI CLIPBOARD] Image is %dx%d and %s be downloaded", lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight,
						bImageDownload ? "WILL" : "will NOT");

					if (!bImageDownload) {
						packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG, imageTlv, 2);
					}
					else {
						lpDIB = ((PUCHAR)lpBI) + get_bitmapinfo_size(lpBI, TRUE);

						// TODO: add the ability to encode with multiple encoders and return the smallest image.
						if (convert_to_jpg(lpBI, lpDIB, 75, &image) == ERROR_SUCCESS) {

							dprintf("[EXTAPI CLIPBOARD] Clipboard bitmap captured to image: %p, Size: %u bytes", image.pImageBuffer, image.dwImageBufferSize);
							imageTlv[2].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA;
							imageTlv[2].header.length = image.dwImageBufferSize;
							imageTlv[2].buffer = (PUCHAR)image.pImageBuffer;

							packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG, imageTlv, 3);

							// Just leaving this in for debugging purposes later on
							//hSourceFile = CreateFileA("C:\\temp\\foo.jpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
							//WriteFile(hSourceFile, image.pImageBuffer, image.dwImageBufferSize, &largeInt.LowPart, NULL);
							//CloseHandle(hSourceFile);

							free(image.pImageBuffer);
						}
						else {
							dwResult = GetLastError();
							dprintf("[EXTAPI CLIPBOARD] Failed to convert clipboard image to JPG");
						}
					}

					pGlobalUnlock(hClipboardData);
				}
				else {
					dwResult = GetLastError();
					dprintf("[EXTAPI CLIPBOARD] Failed to get access to the CF_DIB information");
				}
			}
			else if (uFormat == CF_HDROP) {
				// there's one or more files on the clipboard
				dprintf("[EXTAPI CLIPBOARD] Files have been located on the clipboard");
				do
				{
					dprintf("[EXTAPI CLIPBOARD] Loading shell32.dll");
					if ((hShell32 = LoadLibraryA("shell32.dll")) == NULL)
						BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load shell32.dll");

					dprintf("[EXTAPI CLIPBOARD] Searching for CreateFileA");
					if ((pCreateFileA = (PCREATEFILEA)GetProcAddress(hKernel32, "CreateFileA")) == NULL)
						BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CreateFileA in kernel32.dll");

					dprintf("[EXTAPI CLIPBOARD] Searching for CloseHandle");
					if ((pCloseHandle = (PCLOSEHANDLE)GetProcAddress(hKernel32, "CloseHandle")) == NULL)
						BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseHandle in kernel32.dll");

					dprintf("[EXTAPI CLIPBOARD] Searching for GetFileSizeEx");
					if ((pGetFileSizeEx = (PGETFILESIZEEX)GetProcAddress(hKernel32, "GetFileSizeEx")) == NULL)
						BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GetFileSizeEx in kernel32.dll");

					dprintf("[EXTAPI CLIPBOARD] Searching for DragQueryFileA");
					if ((pDragQueryFileA = (PDRAGQUERYFILEA)GetProcAddress(hShell32, "DragQueryFileA")) == NULL)
						BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in shell32.dll");

					dprintf("[EXTAPI CLIPBOARD] Grabbing the clipboard file drop data");
					if ((hClipboardData = pGetClipboardData(CF_HDROP)) != NULL
						&& (hFileDrop = (HDROP)pGlobalLock(hClipboardData)) != NULL) {

						uFileCount = pDragQueryFileA(hFileDrop, (UINT)-1, NULL, 0);

						dprintf("[EXTAPI CLIPBOARD] Parsing %u file(s) on the clipboard.", uFileCount);

						for (uFileIndex = 0; uFileIndex < uFileCount; ++uFileIndex) {
							if (pDragQueryFileA(hFileDrop, uFileIndex, lpFileName, sizeof(lpFileName))) {
								dprintf("[EXTAPI CLIPBOARD] Clipboard file entry: %s", lpFileName);

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

								entries[0].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME;
								entries[0].header.length = (DWORD)strlen(lpFileName) + 1;
								entries[0].buffer = (PUCHAR)lpFileName;

								entries[1].header.type = TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE;
								entries[1].header.length = sizeof(QWORD);
								entries[1].buffer = (PUCHAR)&largeInt.QuadPart;

								if ((hSourceFile = pCreateFileA(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != NULL) {
									if (pGetFileSizeEx(hSourceFile, &largeInt)) {
										largeInt.QuadPart = htonq(largeInt.QuadPart);
									}

									pCloseHandle(hSourceFile);
								}

								packet_add_tlv_group(pResponse, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE, entries, 2);
							}
						}

						pGlobalUnlock(hClipboardData);
					}

				} while (0);
			}
		}

		dwResult = GetLastError();

		pCloseClipboard();

	} while (0);

	if (hShell32)
		FreeLibrary(hShell32);

	if (hKernel32)
		FreeLibrary(hKernel32);

	if (hUser32)
		FreeLibrary(hUser32);

	if (pResponse)
		packet_transmit_response(dwResult, remote, pResponse);

	return dwResult;
#else
	return ERROR_NOT_SUPPORTED;
#endif
}
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?
		*/
	DWORD result = ERROR_SUCCESS;

#ifdef _WIN32
	HANDLE hCfg;
	unsigned int idx = 1;

	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 = (DWORD)strlen(aname) + 1;
		entries[1].buffer = aname;

		entries[2].header.type = TLV_TYPE_STRING;
		entries[2].header.length = (DWORD)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);

#else
	char errbuf[PCAP_ERRBUF_SIZE+4];
	int aidx = htonl(1);				// :~(
	struct ifaces_list *ifaces;
	uint32_t i;
	int aidx_bigendian;
	int mtu_bigendian;

	int yes_int = htonl(1);
	int no_int = 0;
	int mtu_int = htonl(1514);

	pcap_if_t *interfaces, *int_iter;

	interfaces = int_iter = NULL;
	ifaces = NULL;

	do
	{
		result = pcap_findalldevs(&interfaces, errbuf);

		if(!result)
		{ // pcap_findalldevs suceeded
			for(int_iter = interfaces; int_iter; int_iter = int_iter->next)
			{
				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(int_iter->name)+1;
				entries[1].buffer        = (PUCHAR)int_iter->name;

				entries[2].header.type   = TLV_TYPE_STRING;
				entries[2].header.length = strlen(int_iter->name)+1;
				entries[2].buffer        = (PUCHAR)int_iter->name;

				entries[3].header.type   = TLV_TYPE_UINT;
				entries[3].header.length = sizeof(unsigned int);
				entries[3].buffer        = (PUCHAR)&no_int;		// xxx, get encapsulation type?

				entries[4].header.type   = TLV_TYPE_UINT;
				entries[4].header.length = sizeof(unsigned int);
				entries[4].buffer        = (PUCHAR)&mtu_int;		// PKS :-(

				entries[5].header.type   = TLV_TYPE_BOOL;
				entries[5].header.length = sizeof(BOOL);
				entries[5].buffer        = (PUCHAR)&no_int;		// check encaps options / crap

				entries[6].header.type   = TLV_TYPE_BOOL;
				entries[6].header.length = sizeof(BOOL);
				entries[6].buffer        = (PUCHAR)&yes_int;		// sure, why not.

				entries[7].header.type   = TLV_TYPE_BOOL;
				entries[7].header.length = sizeof(BOOL);
				entries[7].buffer        = (PUCHAR)&no_int;		// hrm. not worth it.

				packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
				aidx = htonl(ntohl(aidx)+1);	// :~(
			}
		}
		else
		{
			dprintf("pcap_findalldevs() failed, trying netlink_get_interfaces now, errbuf was %s", errbuf);
			result = netlink_get_interfaces(&ifaces);

			if(result)
			{
				dprintf("Error when retrieving interfaces info");
				break;
			}

			// netlink_get_interfaces suceeded
			for (i = 0; i < ifaces->entries; i++)
			{
				aidx_bigendian		 = htonl(ifaces->ifaces[i].index);
				entries[0].header.type   = TLV_TYPE_UINT;
				entries[0].header.length = sizeof(uint32_t);
				entries[0].buffer        = (PUCHAR)&aidx_bigendian;

				entries[1].header.type   = TLV_TYPE_STRING;
				entries[1].header.length = strlen(ifaces->ifaces[i].name)+1;
				entries[1].buffer        = (PUCHAR)ifaces->ifaces[i].name;

				entries[2].header.type   = TLV_TYPE_STRING;
				entries[2].header.length = strlen(ifaces->ifaces[i].name)+1;
				entries[2].buffer        = (PUCHAR)ifaces->ifaces[i].name;

				entries[3].header.type   = TLV_TYPE_UINT;
				entries[3].header.length = sizeof(unsigned int);
				entries[3].buffer        = (PUCHAR)&no_int;		// xxx, get encapsulation type?

				mtu_bigendian		 = htonl(ifaces->ifaces[i].mtu);
				entries[4].header.type   = TLV_TYPE_UINT;
				entries[4].header.length = sizeof(uint32_t);
				entries[4].buffer        = (PUCHAR)&mtu_bigendian;

				entries[5].header.type   = TLV_TYPE_BOOL;
				entries[5].header.length = sizeof(BOOL);
				entries[5].buffer        = (PUCHAR)&no_int;		// check encaps options / crap

				entries[6].header.type   = TLV_TYPE_BOOL;
				entries[6].header.length = sizeof(BOOL);
				entries[6].buffer        = (PUCHAR)&yes_int;		// sure, why not.

				entries[7].header.type   = TLV_TYPE_BOOL;
				entries[7].header.length = sizeof(BOOL);
				entries[7].buffer        = (PUCHAR)&no_int;		// hrm. not worth it.

				packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
			}
		}

	} while(0);

	if(ifaces)
	{
		free(ifaces);
	}

	if (interfaces)
	{
		pcap_freealldevs(interfaces);
	}

#endif

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
Example #17
0
/*
 * Returns zero or more local interfaces to the requestor
 */
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
{
    Packet *response = packet_create_response(packet);
    DWORD result = ERROR_SUCCESS;
    DWORD entryCount;

#ifdef _WIN32
    Tlv entries[5];
    PMIB_IPADDRTABLE table = NULL;
    DWORD tableSize = sizeof(MIB_IPADDRROW) * 33;
    DWORD index;

    MIB_IFROW iface;

    do
    {
        // Allocate memory for reading addresses into
        if (!(table = (PMIB_IPADDRTABLE)malloc(tableSize)))
        {
            result = ERROR_NOT_ENOUGH_MEMORY;
            break;
        }

        // Get the IP address table
        if (GetIpAddrTable(table, &tableSize, TRUE) != NO_ERROR)
        {
            result = GetLastError();
            break;
        }

        // Enumerate the entries
        for (index = 0;
                index < table->dwNumEntries;
                index++)
        {
            entryCount = 0;

            entries[entryCount].header.length = sizeof(DWORD);
            entries[entryCount].header.type   = TLV_TYPE_IP;
            entries[entryCount].buffer        = (PUCHAR)&table->table[index].dwAddr;
            entryCount++;

            entries[entryCount].header.length = sizeof(DWORD);
            entries[entryCount].header.type   = TLV_TYPE_NETMASK;
            entries[entryCount].buffer        = (PUCHAR)&table->table[index].dwMask;
            entryCount++;

            iface.dwIndex = table->table[index].dwIndex;

            // If interface information can get gotten, use it.
            if (GetIfEntry(&iface) == NO_ERROR)
            {
                entries[entryCount].header.length = iface.dwPhysAddrLen;
                entries[entryCount].header.type   = TLV_TYPE_MAC_ADDR;
                entries[entryCount].buffer        = (PUCHAR)iface.bPhysAddr;
                entryCount++;

                if (iface.bDescr)
                {
                    entries[entryCount].header.length = iface.dwDescrLen + 1;
                    entries[entryCount].header.type   = TLV_TYPE_MAC_NAME;
                    entries[entryCount].buffer        = (PUCHAR)iface.bDescr;
                    entryCount++;
                }
            }

            // Add the interface group
            packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE,
                                 entries, entryCount);
        }

    } while (0);

    if (table)
        free(table);

#else
    Tlv entries[5]; // xxx, we can probably support more. ip aliases, etc.
    char errbuf[PCAP_ERRBUF_SIZE+4];
    pcap_if_t *interfaces, *iter;
    pcap_addr_t *addresses;
    unsigned char mac[6];

    interfaces = iter = NULL;

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

    do {
        if(pcap_findalldevs(&interfaces, errbuf) == -1) {
            result = ENOMEM; // xxx, send errbuf to remote
            break;
        }

        for(iter = interfaces; iter != NULL ; iter = iter->next ) {
            entryCount = 0;

            if(strcmp(iter->name, "any") == 0) continue;

            dprintf("[%s] Processing %s", __FUNCTION__, iter->name);

            entries[entryCount].header.length = strlen(iter->name)+1;
            entries[entryCount].header.type   = TLV_TYPE_MAC_NAME;
            entries[entryCount].buffer        = (PUCHAR)iter->name;
            entryCount++;

            for(addresses = iter->addresses ; addresses != NULL ; addresses = addresses->next) {
                struct sockaddr_in *sin;

                dprintf("[%s/%s] addr = %p, netmask = %p, broadaddr = %p, dstaddr = %p", __FUNCTION__, iter->name);
                dprintf("[%s/%s] addresses->addr.sa_family = %d", __FUNCTION__, iter->name, addresses->addr->sa_family);

                if(addresses->addr == NULL) {
                    dprintf("[%s/%s] addresses->addr = NULL ?", __FUNCTION__, iter->name);
                    break;
                }

                if(addresses->addr->sa_family == AF_INET) {
                    sin = (struct sockaddr_in *)(addresses->addr);

                    entries[entryCount].header.length = sizeof(DWORD);
                    entries[entryCount].header.type   = TLV_TYPE_IP;
                    entries[entryCount].buffer	  = (PUCHAR)&sin->sin_addr.s_addr;
                    entryCount++;

                    if(addresses->netmask) {
                        sin = (struct sockaddr_in *)(addresses->netmask);
                        entries[entryCount].header.length = sizeof(DWORD);
                        entries[entryCount].header.type   = TLV_TYPE_NETMASK;
                        entries[entryCount].buffer        = (PUCHAR)&sin->sin_addr.s_addr;
                        entryCount++;
                    }



                    break;
                }

            }

            get_interface_mac_addr(iter->name, mac);

            entries[entryCount].header.length = 6;
            entries[entryCount].header.type   = TLV_TYPE_MAC_ADDR;
            entries[entryCount].buffer        = (PUCHAR)(mac);
            entryCount++;


            dprintf("[%s] adding response with %d entries", __FUNCTION__, entryCount);
            packet_add_tlv_group(response, TLV_TYPE_NETWORK_INTERFACE, entries, entryCount);
            dprintf("[%s] done with adding", __FUNCTION__);
        }

    } while(0);

    if(interfaces) {
        dprintf("[%s] calling pcap_freealldevs()", __FUNCTION__);
        pcap_freealldevs(interfaces);
    }

    dprintf("[%s] and done!", __FUNCTION__);

#endif

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

    return result;
}
Example #18
0
/*
 * Query the register state of the supplied thread
 *
 * req: TLV_TYPE_THREAD_HANDLE - The thread to query
 */
DWORD request_sys_process_thread_query_regs(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	HANDLE thread;
	DWORD result = ERROR_SUCCESS;

	do
	{
		if ((thread = (HANDLE)packet_get_tlv_value_uint(packet, 
				TLV_TYPE_THREAD_HANDLE)))
		{
			CONTEXT context;
			DWORD index;
			struct
			{
				LPCSTR    name;
				DWORD     size;
			} regs[] = 
			{
				{ "eax",    4 },
				{ "ebx",    4 },
				{ "ecx",    4 },
				{ "edx",    4 },
				{ "esi",    4 },
				{ "edi",    4 },
				{ "ebp",    4 },
				{ "esp",    4 },
				{ "eip",    4 },
				{ "ss",     2 },
				{ "cs",     2 },
				{ "ds",     2 },
				{ "es",     2 },
				{ "fs",     2 },
				{ "gs",     2 },
				{ "eflags", 4 },
				{ NULL,     0 },
			};
			Tlv reg[3];

			memset(&context, 0, sizeof(context));

			// Get all standard registers
			context.ContextFlags = CONTEXT_FULL;

			// Get the thread's context
			if (!GetThreadContext(thread, &context))
			{
				result = GetLastError();
				break;
			}

			// Get the values associated with each register
			for (index = 0;
			     regs[index].name;
			     index++)
			{
				DWORD sizeNbo, valNbo, value;

				// Get the value 
				value = get_thread_register_value(&context, 
						regs[index].name, regs[index].size);

				// Convert the integer values to network byte order
				sizeNbo = htonl(regs[index].size);
				valNbo  = htonl(value);

				// Translate each register into a grouped TLV
				reg[0].header.length = strlen(regs[index].name) + 1;
				reg[0].header.type   = TLV_TYPE_REGISTER_NAME;
				reg[0].buffer        = (PUCHAR)regs[index].name;
				reg[1].header.length = sizeof(DWORD);
				reg[1].header.type   = TLV_TYPE_REGISTER_SIZE;
				reg[1].buffer        = (PUCHAR)&sizeNbo;
				reg[2].header.length = sizeof(DWORD);
				reg[2].header.type   = TLV_TYPE_REGISTER_VALUE_32;
				reg[2].buffer        = (PUCHAR)&valNbo;

				// Add the register
				packet_add_tlv_group(response, TLV_TYPE_REGISTER, reg, 3);
			}
		}
		else
			result = ERROR_INVALID_PARAMETER;

	} while (0);

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}