/* * 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; }
/* * core_channel_eof * ----------------- * * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to check eof on */ DWORD remote_request_core_channel_eof(Remote *remote, Packet *packet) { Channel *channel = NULL; Packet *response = packet_create_response(packet); DWORD result = ERROR_SUCCESS; BOOL isEof = FALSE; do { // Lookup the channel by its identifier if (!(channel = channel_find_by_id( packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID)))) { result = ERROR_NOT_FOUND; break; } lock_acquire( channel->lock ); // Make sure this class is compatible if (channel_get_class(channel) != CHANNEL_CLASS_POOL) { result = ERROR_NOT_SUPPORTED; break; } // Call the function if it's set if (channel->ops.pool.eof) result = channel->ops.pool.eof(channel, packet, channel->ops.pool.native.context, &isEof); else result = ERROR_NOT_SUPPORTED; } while (0); if( channel ) lock_release( channel->lock ); // Add the EOF flag packet_add_tlv_bool(response, TLV_TYPE_BOOL, isEof); // Transmit the response packet_transmit_response(result, remote, response); return result; }
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; }
/* * core_shutdown * ----------------- * */ DWORD remote_request_core_shutdown(Remote *remote, Packet *packet) { Channel *channel = NULL; Packet *response = packet_create_response(packet); DWORD result = ERROR_SUCCESS; // Acknowledge the shutdown request packet_add_tlv_bool(response, TLV_TYPE_BOOL, TRUE); // Transmit the response packet_transmit_response(result, remote, response); #ifdef _WIN32 // see note about posix above - egypt dprintf("[SHUTDOWN] Shutting down the Meterpreter thread 1 (killing the main thread)..."); thread_kill( serverThread ); #endif return result; }
/* * core_shutdown * ----------------- */ DWORD remote_request_core_shutdown( Remote *remote, Packet *packet, DWORD* pResult ) { Channel *channel = NULL; Packet *response = packet_create_response( packet ); DWORD result = ERROR_SUCCESS; // Acknowledge the shutdown request packet_add_tlv_bool( response, TLV_TYPE_BOOL, TRUE ); // Transmit the response dprintf("[DISPATCH] Ack shutdown request"); packet_transmit_response( result, remote, response ); *pResult = result; dprintf("[DISPATCH] Telling dispatch loop to finish"); // We always return FALSE here to tell the server to terminate. return FALSE; }
/*! * @brief Check to see if a registry key exists. * @param remote Pointer to the \c Remote instance. * @param packet Pointer to the request \c Packet instance. * @returns Always returns \c ERROR_SUCCESS. */ DWORD request_registry_check_key_exists(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); LPCTSTR baseKey = NULL; HKEY rootKey = NULL; HKEY resultKey = NULL; BOOL exists = FALSE; 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 = RegOpenKeyA(rootKey, baseKey, &resultKey); if (result == ERROR_SUCCESS) { dprintf("[REG] Key found"); RegCloseKey(resultKey); exists = TRUE; } dprintf("[REG] Key exists? %s", exists ? "TRUE" : "FALSE"); packet_add_tlv_bool(response, TLV_TYPE_BOOL, exists); result = ERROR_SUCCESS; } else { dprintf("[REG] Invalid parameter"); result = ERROR_INVALID_PARAMETER; } dprintf("[REG] Returning result: %u %x", result, result); packet_transmit_response(result, remote, response); dprintf("[REG] done."); return ERROR_SUCCESS; }