基于Cache的隱藏文件(與注冊(cè)表)檢測(cè)的一些思路
發(fā)表時(shí)間:2023-05-31 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]為了考研, 庸庸碌碌的過(guò)了半年。 現(xiàn)在終于出頭了, 現(xiàn)在又忙于畢業(yè)設(shè)計(jì)(軟件界面美化和驅(qū)動(dòng)文件加殼), 沒(méi)空學(xué)習(xí)內(nèi)核知識(shí) 。 今天特把以前的一些想法發(fā)出來(lái), 大家討論討論。 在網(wǎng)上找了一...
為了考研, 庸庸碌碌的過(guò)了半年。 現(xiàn)在終于出頭了, 現(xiàn)在又忙于畢業(yè)設(shè)計(jì)(軟件界面美化和驅(qū)動(dòng)文件加殼), 沒(méi)空學(xué)習(xí)內(nèi)核知識(shí) 。 今天特把以前的一些想法發(fā)出來(lái), 大家討論討論。
在網(wǎng)上找了一下, 談文件隱藏的不少, 說(shuō)如何檢測(cè)隱藏文件的好像不多。 這里說(shuō)說(shuō)我關(guān)于隱藏文件(和注冊(cè)表)檢測(cè)的一些思路, 錯(cuò)誤和不足希望大牛們指出。
我們知道現(xiàn)在一般隱藏文件的檢測(cè)方法有幾種, 一種是文件系統(tǒng)層即直接發(fā)irp到文件系統(tǒng)進(jìn)行詢(xún)問(wèn), 一種是直接對(duì)磁盤(pán)的數(shù)據(jù)進(jìn)行分析。 當(dāng)然后者應(yīng)該說(shuō)是比前者更安全。 但相信你看過(guò)mj0011大牛的《基于IO Packet隱藏文件和注冊(cè)表, 過(guò)磁盤(pán)解析和總線解析》(當(dāng)然你用他公布的代碼可能不一定成功, 因?yàn)槠渲杏行┬ug), 其實(shí)這也不是安全的, 怎么辦?前有azy大牛的ak922, 后有mj0011大牛的總線過(guò)濾。 那我們只好夾縫中求生存了, 呵呵。
入正題, 我們知道就windows ntfs系統(tǒng)而言, 第一方法自己構(gòu)建的irp包其實(shí)走的線路是NtfsFsdDirectoryControl NtfsCommonDirectoryControl NtfsQueryDirectory在后面就是走NtfsRestartIndexEnumeration和NtfsContinueIndexEnumeration等等到ReadIndexBuffer到NtfsMapStream到CcMapData, 通過(guò)CcMapData得到相應(yīng)FileObject的Cache地址, 然后進(jìn)行解析。 其中Cache的具體地址為在CcMapData最后一個(gè)參數(shù)里。
這是我用syser分析中的兩分截圖, 分析過(guò)NTFS文件系統(tǒng)的話當(dāng)你看到FILE0和INDX字樣的時(shí)候一定很是熟悉, 文件的解析就從這里開(kāi)始了。 其實(shí)在這做分析, 比直接讀磁盤(pán)數(shù)據(jù)分析要簡(jiǎn)單點(diǎn), 代碼如下:
復(fù)制內(nèi)容到剪貼板
代碼:
VOID ListDir (LPBYTE pDir, UINT uAlcSize)
{
LPINDX pIndx;
LPINDXATTR pIndxAttr;
DWORD dwRes;
BYTE pRuns[0x200];
pIndx = ( LPINDX ) pDir;
pIndxAttr = (LPINDXATTR)( pDir + ( 0x18 + pIndx->wHeadSize ) );
if ( 'I' != pIndx->bDirID [0] 'N' != pIndx->bDirID [1] 'D' != pIndx->bDirID [2] 'X' != pIndx->bDirID [3] )
{
return ;
}
while ( TRUE )
{
if ( ( (ULONG)( pIndxAttr ) - (ULONG)(pIndx) ) >= pIndx->dwUseSize )
{
if ( 0 == uAlcSize - ( pIndx->dwAllocSize + 0x18 ) )
break;
else
{
uAlcSize -= ( pIndx->dwAllocSize + 0x18 );
pIndx = ( LPINDX )( (LPSTR)pIndx + ( pIndx->dwAllocSize+ 0x18 ) );
if ( 'I' != pIndx->bDirID [0]
'N' != pIndx->bDirID [1]
'D' != pIndx->bDirID [2]
'X' != pIndx->bDirID [3] )
{
return;
}
pIndxAttr = (LPINDXATTR)( (LPSTR)( pIndx ) + ( 0x18 + pIndx->wHeadSize ) );
}
}
if ( 12 > pIndxAttr->dwMFTIndx )
{
pIndxAttr = (LPINDXATTR)( (LPSTR)( pIndxAttr ) + pIndxAttr->wcbSize );
}
else
{
if ( FALSE == (0x01 & pIndxAttr->bFileNSpace ) )
{
pIndxAttr = (LPINDXATTR)( (LPSTR)( pIndxAttr ) + pIndxAttr->wcbSize );
continue;
}
KdPrint(("File Name is:%ls\n",pIndxAttr->wzFileName));
pIndxAttr = (LPINDXATTR)( (LPSTR)( pIndxAttr ) + pIndxAttr->wcbSize );
}
}
return;
}
當(dāng)然這段代碼只是求個(gè)驗(yàn)證, 并不完善。 因?yàn)槠鋵?shí)直接讀取內(nèi)存數(shù)據(jù), 我測(cè)試了能檢測(cè)出AK922了, 另外mj0011的總線過(guò)濾沒(méi)有做Cache的工作, 當(dāng)然也能檢測(cè)到。
下面說(shuō)說(shuō)怎么獲得Cache地址, 兩種方法。 一是你自己得到FileObject然后用CcMapData去獲得, 做過(guò)文件過(guò)濾驅(qū)動(dòng)的話這應(yīng)該比較簡(jiǎn)單。 另一種就是做Hook, 從中獲得。 既然是做檢測(cè)文件隱藏, 那么你可以先正常的枚舉, 然后根據(jù)獲得的Cache地址讀取數(shù)據(jù)分析和開(kāi)始的進(jìn)行對(duì)比。
該方法的優(yōu)點(diǎn):
這種方法是直接讀取Cache中的數(shù)據(jù), 不走IofCompleteRequest, 得到的數(shù)據(jù)比直接Irp來(lái)的安全。 你可能要說(shuō)我不能對(duì)Cache中的數(shù)據(jù)進(jìn)行修改來(lái)進(jìn)行隱藏嗎?其實(shí)這在AZY的另一篇文章《掛接緩存管理器CcMapData()實(shí)現(xiàn)文件XXX》中提過(guò)。 我是有可以成功, 但系統(tǒng)也就無(wú)法定位到該文件進(jìn)行正常的工作, 還不如直接刪除來(lái)隱藏來(lái)的好。 當(dāng)然強(qiáng)大的LZ同學(xué)們肯定有你的好方法。
該方法的缺點(diǎn):
同樣這也要做文件系統(tǒng)的解析, 很麻煩。 我用的是和我在《NTFS文件解析系統(tǒng)的簡(jiǎn)單分析》中提到的解析索引列表來(lái)讀文件名一樣的方法。 其實(shí)這樣并不好, 應(yīng)該索引列表中的文件名有時(shí)是短名, 有時(shí)甚至有些字符還不錯(cuò)誤的。 這也是mj0011《基于IO Packet隱藏文件和注冊(cè)表, 過(guò)磁盤(pán)解析和總線解析》代碼中過(guò)濾不嚴(yán)導(dǎo)致隱藏失敗的一個(gè)小bug。 所以用他來(lái)枚舉文件不大準(zhǔn)確。 真正準(zhǔn)確的應(yīng)該是在MFT30屬性中獲得的文件名。
當(dāng)然其實(shí)注冊(cè)表的獲取同樣也是走CcMapData, 所以他能夠檢測(cè)基于ZZZEVAZZZ公布的注冊(cè)表隱藏的方法。
文章就寫(xiě)到這里, 最后謝謝你的觀看。
上面是電腦上網(wǎng)安全的一些基礎(chǔ)常識(shí),學(xué)習(xí)了安全知識(shí),幾乎可以讓你免費(fèi)電腦中毒的煩擾。