예제 #1
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;

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

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

		CloseHandle(h);
	}

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

	return ERROR_SUCCESS;
}
예제 #2
0
/*
 * Process a request to print one or more strings
 */
DWORD remote_request_core_console_write(Remote *remote, Packet *packet)
{
	DWORD res = ERROR_NOT_FOUND;
	DWORD index;
	Tlv tlv;

	console_write_output("\n");

	do
	{
		for (index = 0;
		     packet_enum_tlv(packet, index, TLV_TYPE_STRING, &tlv) 
			  	== ERROR_SUCCESS;
		     index++)
			console_write_output("%s", (PCHAR)tlv.buffer);

		res = ERROR_SUCCESS;

	} while (0);

	fflush(stdout);

	console_write_prompt();

	return res;
}
예제 #3
0
DWORD request_resolve_hosts(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	Tlv hostname = {0};
	int index = 0;
	int iResult;
	u_short ai_family = packet_get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);

	while( packet_enum_tlv( packet, index++, TLV_TYPE_HOST_NAME, &hostname ) == ERROR_SUCCESS )
	{
		struct in_addr addr = {0};
		struct in6_addr addr6 = {0};
		
		iResult = resolve_host((LPCSTR)hostname.buffer, 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));
			}
		}
		else
		{
			dprintf("Unable to resolve_host %s error: %x", hostname.buffer, iResult);		
			packet_add_tlv_raw(response, TLV_TYPE_IP, NULL, 0);
		}
		packet_add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
	}

	packet_transmit_response(NO_ERROR, remote, response);
	return ERROR_SUCCESS;
}
예제 #4
0
DWORD request_custom_command(Remote *remote, Packet *packet)
{
	Packet * response = packet_create_response(packet);
	Tlv argTlv             = {0};
	DWORD index            = 0;
	vector<wstring> args;

	LPCSTR func = packet_get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION);
	dprintf("Function: %s", packet_get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION));
	wstring function = s2ws(func);

	while( packet_enum_tlv( packet, index++, TLV_TYPE_MIMIKATZ_ARGUMENT, &argTlv ) == ERROR_SUCCESS )
	{
		dprintf("Arg: %s", (PCHAR)argTlv.buffer);
		args.push_back(s2ws((PCHAR)argTlv.buffer));
	}

	clear_buffer();

	initialize_mimikatz();
	myMimiKatz->doCommandeLocale(&function, &args);

	wchar_t* output = convert_wstring_to_wchar_t(oss.str());
	
	clear_buffer();

	packet_add_tlv_raw(response, TLV_TYPE_MIMIKATZ_RESULT, output, (DWORD)(wcslen(output)*sizeof(wchar_t)));
	packet_transmit_response(ERROR_SUCCESS, remote, response);

	return ERROR_SUCCESS;	
}
예제 #5
0
/*
 * Validate command arguments
 */
DWORD command_validate_arguments(Command *command, Packet *packet)
{
	PacketDispatcher *dispatcher = NULL;
	PacketTlvType type = packet_get_type(packet);
	DWORD res = ERROR_SUCCESS, 
		packetIndex, commandIndex;
	Tlv current;

	// Select the dispatcher table
	if ((type == PACKET_TLV_TYPE_RESPONSE) ||
	    (type == PACKET_TLV_TYPE_PLAIN_RESPONSE))
		dispatcher = &command->response;
	else
		dispatcher = &command->request;

	// Enumerate the arguments, validating the meta types of each
	for (commandIndex = 0, packetIndex = 0;
	     ((packet_enum_tlv(packet, packetIndex, TLV_TYPE_ANY, &current) 
			 == ERROR_SUCCESS) &&
	      (res == ERROR_SUCCESS));
	     commandIndex++, packetIndex++)
	{
		TlvMetaType tlvMetaType;

		// Check to see if we've reached the end of the command arguments
		if ((dispatcher->numArgumentTypes) &&
		    (commandIndex == (dispatcher->numArgumentTypes & ARGUMENT_FLAG_MASK)))
		{
			// If the repeat flag is set, reset the index
			if (commandIndex & ARGUMENT_FLAG_REPEAT)
				commandIndex = 0;
			else
				break;
		}
		
		// Make sure the argument is at least one of the meta types
		tlvMetaType = packet_get_tlv_meta(packet, &current);

		// Validate argument meta types
		switch (tlvMetaType)
		{
			case TLV_META_TYPE_STRING:
				if (packet_is_tlv_null_terminated(packet, &current) != ERROR_SUCCESS)
					res = ERROR_INVALID_PARAMETER;
				break;
			default:
				break;
		}
	
		if ((res != ERROR_SUCCESS) && 
		    (commandIndex < dispatcher->numArgumentTypes))
			break;
	}

	return res;
}
예제 #6
0
/*!
 * @brief Expand a given set of environment variables.
 * @param remote Pointer to the \c Remote instance making the request.
 * @param packet Pointer to the \c Request packet.
 * @remarks This will return a hash of the list of environment variables
 *          and their values, as requested by the caller.
 * @returns Indication of success or failure.
 */
DWORD request_sys_config_getenv(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD dwResult = ERROR_SUCCESS;
	DWORD dwTlvIndex = 0;
	Tlv envTlv;
	char* pEnvVarStart;
	char* pEnvVarEnd;

	do
	{
		while (ERROR_SUCCESS == packet_enum_tlv(packet, dwTlvIndex++, TLV_TYPE_ENV_VARIABLE, &envTlv))
		{
			pEnvVarStart = (char*)envTlv.buffer;

			dprintf("[ENV] Processing: %s", pEnvVarStart);

			// skip any '%' or '$' if they were specified.
			while (*pEnvVarStart != '\0' && (*pEnvVarStart == '$' || *pEnvVarStart == '%'))
			{
				++pEnvVarStart;
			}

			dprintf("[ENV] pEnvStart: %s", pEnvVarStart);

			pEnvVarEnd = pEnvVarStart;

			// if we're on windows, the caller might have passed in '%' at the end, so remove that
			// if it's there.
			while (*pEnvVarEnd != '\0')
			{
				if (*pEnvVarEnd == '%')
				{
					// terminate it here instead
					*pEnvVarEnd = '\0';
					break;
				}
				++pEnvVarEnd;
			}

			dprintf("[ENV] Final env var: %s", pEnvVarStart);

			// grab the value of the variable and stick it in the response.
			add_env_pair(response, pEnvVarStart, getenv(pEnvVarStart));

			dprintf("[ENV] Env var added");
		}
	} while (0);

	dprintf("[ENV] Transmitting response.");
	packet_transmit_response(dwResult, remote, response);

	dprintf("[ENV] done.");
	return dwResult;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
0
/*!
 * @brief Get a TLV of a given type from the packet.
 * @param packet Pointer to the packet to get the TLV from.
 * @param type Type of TLV to get.
 * @param tlv Pointer to the TLV that will receive the data.
 * @return Indication of success or failure.
 * @retval ERROR_SUCCESS The operation completed successfully.
 * @retval ERROR_NOT_FOUND Unable to find the TLV.
 */
DWORD packet_get_tlv(Packet *packet, TlvType type, Tlv *tlv)
{
	return packet_enum_tlv(packet, 0, type, tlv);
}
/*!
 * @brief Perform an ASDI query against a domain.
 * @param remote Pointer to the \c Remote instance.
 * @param packet Pointer to the incoming \c Packet instance.
 * @returns Indication of success or failure.
 * @remark Real error codes are returned to the caller via a response packet.
 */
DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
{
	DWORD dwResult = ERROR_SUCCESS;
	LPSTR lpValue = NULL;
	LPWSTR lpwDomain = NULL;
	LPWSTR lpwFilter = NULL;
	LPWSTR* lpwFields = NULL;
	DWORD fieldCount = 0;
	DWORD fieldIndex = 0;
	Packet * response = packet_create_response(packet);
	Tlv fieldTlv;
	DWORD maxResults;
	DWORD pageSize;

	do
	{
		if (!response)
		{
			BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to create response packet", ERROR_OUTOFMEMORY);
		}

		lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
		dprintf("[EXTAPI ADSI] Domain: %s", lpValue);
		dwResult = to_wide_string(lpValue, &lpwDomain);
		if (dwResult != ERROR_SUCCESS)
		{
			dprintf("[EXTAPI ADSI] Failed to get Domain");
			break;
		}

		lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_FILTER);
		dprintf("[EXTAPI ADSI] Filter: %s", lpValue);
		dwResult = to_wide_string(lpValue, &lpwFilter);
		if (dwResult != ERROR_SUCCESS)
		{
			dprintf("[EXTAPI ADSI] Failed to get Filter");
			break;
		}

		maxResults = packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_ASDI_MAXRESULTS);
		dprintf("[EXTAPI ADSI] Max results will be %u", maxResults);

		pageSize = packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_ASDI_PAGESIZE);
		dprintf("[EXTAPI ADSI] Page size specified as %u", pageSize);

		// Set the page size to something sensible if not given.
		if (pageSize == 0)
		{
			pageSize = DEFAULT_PAGE_SIZE;
		}

		// If max results is given, there's no point in having a page size
		// that's bigger!
		if (maxResults != 0)
		{
			pageSize = min(pageSize, maxResults);
		}
		dprintf("[EXTAPI ADSI] Page size will be %u", pageSize);

		while (packet_enum_tlv(packet, fieldCount, TLV_TYPE_EXT_ADSI_FIELD, &fieldTlv) == ERROR_SUCCESS)
		{
			lpValue = (char*)fieldTlv.buffer;
			dprintf("[EXTAPI ADSI] Field %u: %s", fieldCount, lpValue);
			lpwFields = (LPWSTR*)realloc(lpwFields, sizeof(LPWSTR) * (fieldCount + 1));

			if (lpwFields == NULL)
			{
				BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to allocate memory", ERROR_OUTOFMEMORY);
			}

			dwResult = to_wide_string(lpValue, &lpwFields[fieldCount]);
			if (dwResult != ERROR_SUCCESS)
			{
				dprintf("[EXTAPI ADSI] Failed to get field as wide string");
				break;
			}
			++fieldCount;
		}

		dprintf("[EXTAPI ADSI] Field count: %u", fieldCount, lpValue);

		if (dwResult == ERROR_SUCCESS)
		{
			dprintf("[EXTAPI ADSI] Beginning user enumeration");
			dwResult = domain_query(lpwDomain, lpwFilter, lpwFields, fieldCount, maxResults, pageSize, response);
			dprintf("[EXTAPI ADSI] Result of processing: %u (0x%x)", dwResult, dwResult);
		}
	} while (0);

	if (lpwFields)
	{
		for (fieldIndex = 0; fieldIndex < fieldCount; ++fieldIndex)
		{
			if (lpwFields[fieldIndex])
			{
				free(lpwFields[fieldIndex]);
			}
		}
		free(lpwFields);
	}

	if (lpwFilter)
	{
		free(lpwFilter);
	}

	if (lpwDomain)
	{
		free(lpwDomain);
	}

	dprintf("[EXTAPI ADSI] Transmitting response back to caller.");
	if (response)
	{
		packet_transmit_response(dwResult, remote, response);
	}

	return dwResult;
}
예제 #11
0
/*
 * Set the register state of the supplied thread
 *
 * req: TLV_TYPE_THREAD_HANDLE - The thread to set
 * req: TLV_TYPE_REGISTER x N  - The registers to set
 */
DWORD request_sys_process_thread_set_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 = 0;
			Tlv reg;

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

			// Get the current thread register state
			context.ContextFlags = CONTEXT_FULL;

			if (!GetThreadContext(thread, &context))
			{
				result = GetLastError();
				break;
			}

			// Enumerate through all of the register we're setting
			while (packet_enum_tlv(packet, index++, TLV_TYPE_REGISTER, 
					&reg) == ERROR_SUCCESS)
			{
				LPCSTR name;
				ULONG value;
				Tlv nameTlv, valueTlv;

				// Get the group's entries
				if ((packet_get_tlv_group_entry(packet, &reg, 
						TLV_TYPE_REGISTER_NAME, &nameTlv) != ERROR_SUCCESS) ||
				    (packet_get_tlv_group_entry(packet, &reg,
						TLV_TYPE_REGISTER_VALUE_32, &valueTlv) != ERROR_SUCCESS))
					continue;
				
				// Validate them
				if ((packet_is_tlv_null_terminated(packet, 
						&nameTlv) != ERROR_SUCCESS) ||
				    (valueTlv.header.length < sizeof(ULONG)))
					continue;
				
				// Stash them
				name  = (LPCSTR)nameTlv.buffer;
				value = ntohl(*(PULONG)valueTlv.buffer);

				// Set this register's value
				set_thread_register_value(&context, name, value);
			}

			// Update the thread's context
			if (!SetThreadContext(thread, &context))
			{
				result = GetLastError();
				break;
			}
		}
		else
			result = ERROR_INVALID_PARAMETER;

	} while (0);

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}