/* * Removes a registry key with the supplied root and base key information. * * TLVs: * * req: TLV_TYPE_ROOT_KEY - The root key handle. * req: TLV_TYPE_BASE_KEY - The base key name. * opt: TLV_TYPE_FLAGS - Zero or more flags that control how the key is * deleted. */ DWORD request_registry_delete_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR baseKey = NULL; DWORD result = ERROR_SUCCESS; DWORD flags = 0; HKEY rootKey = NULL; rootKey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_ROOT_KEY); baseKey = packet_get_tlv_value_string(packet, TLV_TYPE_BASE_KEY); flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS); if ((!rootKey) || (!baseKey)) result = ERROR_INVALID_PARAMETER; else { if (flags & DELETE_KEY_FLAG_RECURSIVE) result = SHDeleteKey(rootKey, baseKey); else result = RegDeleteKey(rootKey, baseKey); } // Set the result and send the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
static void set_value(Remote *remote, Packet *packet, HKEY hkey) { Packet *response = packet_create_response(packet); LPCSTR valueName = NULL; DWORD valueType = 0; DWORD result = ERROR_SUCCESS; Tlv valueData; // Acquire the standard TLVs valueName = packet_get_tlv_value_string(packet, TLV_TYPE_VALUE_NAME); valueType = packet_get_tlv_value_uint(packet, TLV_TYPE_VALUE_TYPE); do { // Get the value data TLV if (packet_get_tlv(packet, TLV_TYPE_VALUE_DATA, &valueData) != ERROR_SUCCESS) { result = ERROR_INVALID_PARAMETER; break; } // Now let's rock this shit! result = RegSetValueEx(hkey, valueName, 0, valueType, valueData.buffer, valueData.header.length); } while (0); // Populate the result code packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); // Transmit the response packet_transmit(remote, response, NULL); }
/* * Copies source file path to destination * * req: TLV_TYPE_FILE_PATH - The file path to expand */ DWORD request_fs_file_move(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result = ERROR_SUCCESS; LPCSTR oldpath; LPCSTR newpath; oldpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_NAME); newpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH); if (!oldpath) result = ERROR_INVALID_PARAMETER; #ifdef _WIN32 else if (!MoveFile(oldpath,newpath)) #else else if (!rename(oldpath,newpath)) #endif result = GetLastError(); packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Queries a registry class for a given HKEY. * * TLVs: * * req: TLV_TYPE_HKEY - The HKEY to query the class on */ DWORD request_registry_query_class(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR valueName = NULL; BYTE valueData[4096]; DWORD valueDataSize = 4096; DWORD result = ERROR_SUCCESS; DWORD valueType = 0; HKEY hkey = NULL; // Acquire the standard TLVs hkey = (HKEY)packet_get_tlv_value_qword(packet, TLV_TYPE_HKEY); do { // Get the size of the value data if ((result = RegQueryInfoKey(hkey, valueData, &valueDataSize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) != ERROR_SUCCESS) break; packet_add_tlv_string(response, TLV_TYPE_VALUE_DATA, (LPCSTR)valueData); } while (0); // Populate the result code packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); // Transmit the response packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Creates a registry key and returns the associated HKEY to the caller if the * operation succeeds. * * TLVs: * * req: TLV_TYPE_ROOT_KEY - The root key * req: TLV_TYPE_BASE_KEY - The base key * opt: TLV_TYPE_PERMISSION - Permissions with which to create the key */ DWORD request_registry_create_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCTSTR baseKey = NULL; HKEY rootKey = NULL, resKey; DWORD permission; DWORD result; rootKey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_ROOT_KEY); baseKey = packet_get_tlv_value_string(packet, TLV_TYPE_BASE_KEY); permission = packet_get_tlv_value_uint(packet, TLV_TYPE_PERMISSION); // Validate the parameters and then attempt to create the key if ((!rootKey) || (!baseKey)) result = ERROR_INVALID_PARAMETER; else { if (!permission) permission = KEY_ALL_ACCESS; result = RegCreateKeyEx(rootKey, baseKey, 0, NULL, 0, permission, NULL, &resKey, NULL); } // Add the HKEY if we succeeded, but always return a result if (result == ERROR_SUCCESS) packet_add_tlv_uint(response, TLV_TYPE_HKEY, (DWORD)resKey); packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Opens a remote registry key and returns the associated HKEY to the caller if the * operation succeeds. * * TLVs: * * req: TLV_TYPE_ROOT_KEY - The root key * req: TLV_TYPE_TARGET_HOST - The target machine name */ DWORD request_registry_open_remote_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCTSTR targetHost = NULL; HKEY rootKey = NULL, resKey; DWORD result; targetHost = packet_get_tlv_value_string(packet, TLV_TYPE_TARGET_HOST); rootKey = (HKEY)packet_get_tlv_value_qword(packet, TLV_TYPE_ROOT_KEY); // Validate the parameters and then attempt to create the key if ((!rootKey) || (!targetHost)) result = ERROR_INVALID_PARAMETER; else { result = RegConnectRegistry(targetHost, rootKey, &resKey); } // Add the HKEY if we succeeded, but always return a result if (result == ERROR_SUCCESS) { packet_add_tlv_qword(response, TLV_TYPE_HKEY, (QWORD)resKey); } packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Gets information about the file path that is supplied and returns it to the * requestor * * TLVs: * * req: TLV_TYPE_FILE_PATH - The file path that is to be stat'd */ DWORD request_fs_stat(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); struct meterp_stat buf; LPCSTR filePath; LPSTR expanded = NULL; DWORD result = ERROR_SUCCESS; filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH); // Validate parameters if (!filePath) result = ERROR_INVALID_PARAMETER; else if (!(expanded = fs_expand_path(filePath))) result = ERROR_NOT_ENOUGH_MEMORY; else { result = fs_stat(expanded, &buf); if (0 == result) packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf)); } // Set the result and transmit the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); if (expanded) free(expanded); return result; }
/* * sys_getuid * ---------- * * Gets the user information of the user the server is executing as */ DWORD request_getuid(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD res = ERROR_SUCCESS; CHAR username[512]; DWORD size = sizeof(username); memset(username, 0, sizeof(username)); do { // Get the username if (!GetUserName(username, &size)) { res = GetLastError(); break; } packet_add_tlv_string(response, TLV_TYPE_USER_NAME, username); } while (0); // Transmit the response if (response) { packet_add_tlv_uint(response, TLV_TYPE_RESULT, res); packet_transmit(remote, response, NULL); } return res; }
/* * Open a TCP channel with the remote endpoint */ DWORD network_open_tcp_channel(Remote *remote, LPCSTR remoteHost, USHORT remotePort, PacketRequestCompletion *complete) { Packet *request = packet_create(PACKET_TLV_TYPE_REQUEST, "network_open_tcp_channel"); DWORD res = ERROR_SUCCESS; do { // Verify that the packet was allocated if (!request) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the host/port combination packet_add_tlv_string(request, TLV_TYPE_NETWORK_GENERAL_REMOTE_HOST, remoteHost); packet_add_tlv_uint(request, TLV_TYPE_NETWORK_GENERAL_REMOTE_PORT, remotePort); // Transmit the request res = packet_transmit(remote, request, complete); } while (0); return res; }
/* * Queries a registry value's type and data for a given HKEY. * * TLVs: * * req: TLV_TYPE_HKEY - The HKEY to query the value on * req: TLV_TYPE_VALUE_NAME - The name of the value to query */ DWORD request_registry_query_value(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR valueName = NULL; LPBYTE valueData = NULL; DWORD valueDataSize = 4096; DWORD result = ERROR_SUCCESS; DWORD valueType = 0; HKEY hkey = NULL; // Acquire the standard TLVs hkey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_HKEY); valueName = packet_get_tlv_value_string(packet, TLV_TYPE_VALUE_NAME); do { // Get the size of the value data if ((result = RegQueryValueEx(hkey, valueName, 0, NULL, NULL, &valueDataSize)) != ERROR_SUCCESS) break; // Allocate storage for the value data if (!(valueData = (LPBYTE)malloc(valueDataSize))) continue; // Query the value's information if ((result = RegQueryValueEx(hkey, valueName, 0, &valueType, valueData, &valueDataSize)) != ERROR_SUCCESS) break; // Add the information about the value to the response packet_add_tlv_uint(response, TLV_TYPE_VALUE_TYPE, valueType); switch (valueType) { case REG_SZ: packet_add_tlv_string(response, TLV_TYPE_VALUE_DATA, (LPCSTR)valueData); break; case REG_DWORD: packet_add_tlv_uint(response, TLV_TYPE_VALUE_DATA, *(LPDWORD)valueData); break; default: packet_add_tlv_raw(response, TLV_TYPE_VALUE_DATA, valueData, valueDataSize); break; } } while (0); // Populate the result code packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); // Transmit the response packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Write to the remote end of the channel */ DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; LPCSTR method = "core_channel_write"; Packet *request; Tlv methodTlv; do { // Allocate a request packet if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Add the channel identifier and the length to write packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); // if the channel data is ment to be compressed, compress it! if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) ) packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, buffer, length); else packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA, buffer, length); packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel)); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Interact with a given channel such that data on the remote end is * forwarded in real time rather than being polled. */ DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; LPCSTR method = "core_channel_interact"; DWORD res = ERROR_SUCCESS; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Add the channel identifier packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); // Add the enable/disable boolean packet_add_tlv_bool(request, TLV_TYPE_BOOL, enable); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Returns the SHA1 hash for a specified file path * * TLVs: * * req: TLV_TYPE_FILE_PATH - The file path that is to be stat'd */ DWORD request_fs_sha1(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR filePath; LPSTR expanded = NULL; DWORD result = ERROR_SUCCESS; SHA_CTX context; FILE *fd; size_t ret; unsigned char buff[16384]; unsigned char hash[128]; filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH); // Validate parameters if (!filePath) result = ERROR_INVALID_PARAMETER; else if (!(expanded = fs_expand_path(filePath))) result = ERROR_NOT_ENOUGH_MEMORY; else { do { SHA1_Init(&context); fd = fopen(expanded, "rb"); if (! fd) { result = GetLastError(); break; } while((ret = fread(buff, 1, sizeof(buff), fd)) > 0 ) { SHA1_Update(&context, buff, ret); } fclose(fd); SHA1_Final(hash, &context); // One byte extra for the NULL packet_add_tlv_raw(response, TLV_TYPE_FILE_NAME, hash, 21); } while(0); } // Set the result and transmit the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); if (expanded) free(expanded); return ERROR_SUCCESS; }
/* * Transmits a response with nothing other than a result code in it */ DWORD packet_transmit_empty_response(Remote *remote, Packet *packet, DWORD res) { Packet *response = packet_create_response(packet); if (!response) return ERROR_NOT_ENOUGH_MEMORY; // Add the result code packet_add_tlv_uint(response, TLV_TYPE_RESULT, res); // Transmit the response return packet_transmit(remote, response, NULL); }
DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; LPCSTR method = "core_channel_write"; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } packet_add_tlvs(request, addend, addendLength); if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) ) packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, buffer, length); else packet_add_tlv_raw(request, TLV_TYPE_CHANNEL_DATA, buffer, length); packet_add_tlv_uint(request, TLV_TYPE_LENGTH, channel_get_id(channel)); if (completionRoutine) { dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Tries to open a channel with the remote endpoint, optionally calling the * supplied completion routine upon response. */ DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; DWORD res = ERROR_SUCCESS; PCHAR method = "core_channel_open"; Packet *request; Tlv methodTlv; do { // Allocate the request if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the supplied TLVs packet_add_tlvs(request, addend, addendLength); // If no method TLV as added, add the default one. if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); // Initialize the packet completion routine if (completionRoutine) { // Duplicate the completion routine dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } // Transmit the packet with the supplied completion routine, if any. res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * core_channel_open * ----------------- * * Opens a channel with the remote endpoint. The response handler for this * request will establish the relationship on the other side. * * opt: TLV_TYPE_CHANNEL_TYPE * The channel type to allocate. If set, the function returns, allowing * a further up extension handler to allocate the channel. */ DWORD remote_request_core_channel_open(Remote *remote, Packet *packet) { Packet *response; DWORD res = ERROR_SUCCESS; Channel *newChannel; PCHAR channelType; DWORD flags = 0; do { // If the channel open request had a specific channel type if ((channelType = packet_get_tlv_value_string(packet, TLV_TYPE_CHANNEL_TYPE))) { res = ERROR_NOT_FOUND; break; } // Get any flags that were supplied flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS); // Allocate a response response = packet_create_response(packet); // Did the response allocation fail? if ((!response) || (!(newChannel = channel_create(0, flags)))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Get the channel class and set it newChannel->cls = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_CLASS); // Add the new channel identifier to the response if ((res = packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel))) != ERROR_SUCCESS) break; // Transmit the response res = packet_transmit(remote, response, NULL); } while (0); return res; }
DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine *completionRoutine) { PacketRequestCompletion requestCompletion, *realRequestCompletion = NULL; ChannelCompletionRoutine *dupe = NULL; LPCSTR method = "core_channel_interact"; DWORD res = ERROR_SUCCESS; Packet *request; Tlv methodTlv; do { if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, NULL))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } packet_add_tlvs(request, addend, addendLength); if (packet_get_tlv(request, TLV_TYPE_METHOD, &methodTlv) != ERROR_SUCCESS) packet_add_tlv_string(request, TLV_TYPE_METHOD, method); packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(channel)); packet_add_tlv_bool(request, TLV_TYPE_BOOL, enable); if (completionRoutine) { dupe = channel_duplicate_completion_routine(completionRoutine); requestCompletion.context = dupe; requestCompletion.routine = _channel_packet_completion_routine; realRequestCompletion = &requestCompletion; } res = packet_transmit(remote, request, realRequestCompletion); } while (0); return res; }
/* * Gets the directory separator for this system */ DWORD request_fs_separator(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); #ifdef _WIN32 LPCSTR separator = "\\"; #else LPCSTR separator = "/"; #endif packet_add_tlv_string(response, TLV_TYPE_STRING, separator); // Set the result and transmit the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, ERROR_SUCCESS); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * 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; }
/* * Closes the supplied HKEY * * TLVs: * * req: TLV_TYPE_HKEY - The HKEY that is to be closed */ DWORD request_registry_close_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result; HKEY hkey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_HKEY); // No param? No love. if (!hkey) result = ERROR_INVALID_PARAMETER; else result = RegCloseKey(hkey); // Set the result and send the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Opens a registry key and returns the associated HKEY to the caller if the * operation succeeds. * * TLVs: * * req: TLV_TYPE_ROOT_KEY - The root key * req: TLV_TYPE_BASE_KEY - The base key * opt: TLV_TYPE_PERMISSION - Permissions with which to open the key */ DWORD request_registry_open_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result; HKEY rootKey, resKey; result = open_key(packet, &rootKey, &resKey); // Add the HKEY if we succeeded, but always return a result if (result == ERROR_SUCCESS) { packet_add_tlv_qword(response, TLV_TYPE_HKEY, (QWORD)resKey); } packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
DWORD request_registry_unload_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCTSTR baseKey = NULL; HKEY rootKey = NULL; DWORD result; rootKey = (HKEY)packet_get_tlv_value_qword(packet, TLV_TYPE_ROOT_KEY); baseKey = packet_get_tlv_value_string(packet, TLV_TYPE_BASE_KEY); if ((!rootKey) || (!baseKey)) result = ERROR_INVALID_PARAMETER; else { result = RegUnLoadKey(rootKey,baseKey); } packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * core_crypto_negotiate * --------------------- * * Negotiates a cryptographic session with the remote host * * req: TLV_TYPE_CIPHER_NAME -- The cipher being selected. * opt: TLV_TYPE_CIPHER_PARAMETERS -- The paramters passed to the cipher for * initialization */ DWORD remote_request_core_crypto_negotiate(Remote *remote, Packet *packet) { LPCSTR cipherName = packet_get_tlv_value_string(packet, TLV_TYPE_CIPHER_NAME); DWORD res = ERROR_INVALID_PARAMETER; Packet *response = packet_create_response(packet); // If a cipher name was supplied, set it if (cipherName) res = remote_set_cipher(remote, cipherName, packet); // Transmit a response if (response) { packet_add_tlv_uint(response, TLV_TYPE_RESULT, res); packet_transmit(remote, response, NULL); } return ERROR_SUCCESS; }
/* * Transmit a single string to the remote connection with instructions to * print it to the screen or whatever medium has been established. */ DWORD send_core_console_write(Remote *remote, LPCSTR fmt, ...) { Packet *request = NULL; CHAR buf[8192]; va_list ap; DWORD res; do { va_start(ap, fmt); _vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); // Create a message with the 'core_print' method if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST, "core_console_write"))) { res = ERROR_NOT_ENOUGH_MEMORY; break; } // Add the string to print if ((res = packet_add_tlv_string(request, TLV_TYPE_STRING, buf)) != NO_ERROR) break; res = packet_transmit(remote, request, NULL); } while (0); // Cleanup on failure if (res != ERROR_SUCCESS) { if (request) packet_destroy(request); } return res; }
/* * core_channel_close * ------------------ * * Closes a previously opened channel. * * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close */ DWORD remote_request_core_channel_close(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD res = ERROR_SUCCESS, channelId; Channel *channel = NULL; dprintf( "[CHANNEL] remote_request_core_channel_close." ); do { // Get the channel identifier channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID); // Try to locate the specified channel if (!(channel = channel_find_by_id(channelId))) { res = ERROR_NOT_FOUND; break; } // Destroy the channel channel_destroy(channel, packet); if (response) packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId); } while (0); // Transmit the acknowledgement if (response) { packet_add_tlv_uint(response, TLV_TYPE_RESULT, res); res = packet_transmit(remote, response, NULL); } return res; }
/* * Removes the supplied file from disk * * TLVs: * * req: TLV_TYPE_FILE_PATH - The file that is to be removed. */ DWORD request_fs_delete_file(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR path; DWORD result = ERROR_SUCCESS; path = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH); if (!path) result = ERROR_INVALID_PARAMETER; #ifdef _WIN32 else if (!DeleteFile(path)) #else else if (!unlink(path)) #endif result = GetLastError(); packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Deletes a registry value from the supplied registry key * * TLVs: * * req: TLV_TYPE_HKEY - The HKEY from which to delete the value * req: TLV_TYPE_VALUE_NAME = The name of the value to delete */ DWORD request_registry_delete_value(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCSTR valueName = NULL; DWORD result = ERROR_SUCCESS; HKEY hkey = NULL; hkey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_HKEY); valueName = (LPCSTR)packet_get_tlv_value_string(packet, TLV_TYPE_VALUE_NAME); // Check for invalid parameters if ((!hkey) || (!valueName)) result = ERROR_INVALID_PARAMETER; else result = RegDeleteValue(hkey, valueName); // Set the result and send the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }
/* * Gets information about the file path that is supplied and returns it to the * requestor * * TLVs: * * req: TLV_TYPE_FILE_PATH - The file path that is to be stat'd */ DWORD request_fs_stat(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); struct stat buf; LPCSTR filePath; LPSTR expanded = NULL; DWORD result = ERROR_SUCCESS; filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH); // Validate parameters if (!filePath) result = ERROR_INVALID_PARAMETER; else if (!(expanded = fs_expand_path(filePath))) result = ERROR_NOT_ENOUGH_MEMORY; else { // Stat the file using the Microsoft stat wrapper so that we don't have to // do translations if (stat(expanded, &buf) < 0) result = GetLastError(); else packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf)); } // Set the result and transmit the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); if (expanded) free(expanded); return ERROR_SUCCESS; }
/* * Enumerates a supplied registry key and returns a list of all the direct * sub-keys. * * TLVs: * * req: TLV_TYPE_HKEY - The HKEY that is to be enumerated */ DWORD request_registry_enum_key(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); DWORD result; HKEY hkey = (HKEY)packet_get_tlv_value_uint(packet, TLV_TYPE_HKEY); if (!hkey) result = ERROR_INVALID_PARAMETER; else { DWORD nameSize = 4096; DWORD index = 0; DWORD tries = 0; LPSTR name = NULL; // Keep looping until we reach the end while (1) { // If the name storage is NULL, allocate it if (!name) name = (LPSTR)malloc(nameSize); result = RegEnumKey(hkey, index, name, nameSize); // If we need more room... if (result == ERROR_MORE_DATA) { if (tries > 3) break; free(name); nameSize *= 2; name = NULL; tries++; continue; } // If we've reached the end of our road... else if (result == ERROR_NO_MORE_ITEMS) { result = ERROR_SUCCESS; break; } // If we flunked out of school... else if (result != ERROR_SUCCESS) break; // Reset tries tries = 0; // Add the registry key name packet_add_tlv_string(response, TLV_TYPE_KEY_NAME, name); // Next entry index++; } } // Set the result and transmit the response packet_add_tlv_uint(response, TLV_TYPE_RESULT, result); packet_transmit(remote, response, NULL); return ERROR_SUCCESS; }