WINDOWS XP SP2修改了TCPIP.SYS,增加了对于RAW SOCKET的发送和伪造源地的限制,详情如下 :
1) 不能通过raw socket发送TCP报文。做此尝试时会得到10004号错误。
2) 不能通过raw socket发送伪造源IP的UDP报文。
3) 不能通过raw socket发送IP碎片。做此尝试时会得到10004号错误。
不知微软在哪次对2000 SP4的修补中实现了类似上述第三条的限制,只是要宽松一些:
3) 不能通过raw socket发送全部IP碎片,只有第一个碎片可被发送出去。试图发送
后续碎片时会得到10004号错误。
来自微软的说明:
//What new functionality is added to this feature in Windows XP Service Pack 2?
//Restricted traffic over raw sockets
//Detailed description
A very small number of Windows applications make use of raw IP sockets, which provide an industry-standard way for applications to create TCP/IP packets with fewer integrity and security checks by the TCP/IP stack. The Windows implementation of TCP/IP still supports receiving traffic on raw IP sockets. However, the ability to send traffic over raw sockets has been restricted in two ways:
//
//TCP data cannot be sent over raw sockets.
//
//UDP datagrams with invalid source addresses cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped.
//
//Why is this change important? What threats does it help mitigate?
//
//This change limits the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets, which are TCP/IP packets with a forged source IP address.
//
这个限制是能过一些判断和跳转实现的,跳转的地方如下:
汇编代码来自对于WINDOWS XP SP2的 反汇编,这段代码使RAW SOCKET的SENTO失败:
.text:00034007 loc_34007: ; CODE XREF: IPTransmit(x,x,x,x,x,x,x,x,x,x)+213C4j
.text:00034007 8B 45 B4 mov eax, [ebp+var_4C]
.text:0003400A 89 50 0C mov [eax+0Ch], edx
.text:0003400D 8B 45 B4 mov eax, [ebp+var_4C]
.text:00034010 88 58 1C mov [eax+1Ch], bl
.text:00034013 8B 4D AC mov ecx, [ebp+var_54]
.text:00034016 8A 41 09 mov al, [ecx+9] ; <---开始判断类型
.text:00034019 3C 06 cmp al, 6
.text:0003401B 0F 84 A9 14 00 00 jz pos_to_drop_skip_packet <--这里改为jmp 0003405D 即可绕过这个限制.
.text:00034021 3C 04 cmp al, 4
.text:00034023 0F 84 A1 14 00 00 jz pos_to_drop_skip_packet
.text:00034029 3C 29 cmp al, 29h
.text:0003402B 0F 84 99 14 00 00 jz pos_to_drop_skip_packet
.text:00034031 FF 71 0C push dword ptr [ecx+0Ch]
.text:00034034 E8 D6 CD FD FF call _GetAddrType@4 ; GetAddrType(x)
.text:00034039 84 C0 test al, al
.text:0003403B 74 20 jz short loc_3405D ; <---不检查,直接执行
.text:0003403D 8B 45 AC mov eax, [ebp+var_54]
.text:00034040 FF 70 10 push dword ptr [eax+10h]
.text:00034043 E8 C7 CD FD FF call _GetAddrType@4 ; GetAddrType(x)
.text:00034048 3C 03 cmp al, 3
.text:0003404A 0F 85 7A 14 00 00 jnz pos_to_drop_skip_packet
.text:00034050 8B 45 8C mov eax, [ebp+var_74]
.text:00034053 F6 40 0C 20 test byte ptr [eax+0Ch], 20h
.text:00034057 0F 84 6D 14 00 00 jz pos_to_drop_skip_packet
.text:0003405D
.text:0003405D loc_3405D: ; CODE XREF: IPTransmit(x,x,x,x,x,x,x,x,x,x)+213FDj
.text:0003405D 8B 45 AC mov eax, [ebp+var_54] ; <---不检查,直接执行
.text:00034060 0F B6 00 movzx eax, byte ptr [eax]
.text:00034063 83 E0 0F and eax, 0Fh
.text:00034066 C1 E0 02 shl eax, 2
.text:00034069 8B F0 mov esi, eax
.text:0003406B 83 FE 14 cmp esi, 14h
.text:0003406E 89 B5 64 FF FF FF mov [ebp+var_9C], esi
.text:00034074 0F 82 50 14 00 00 jb pos_to_drop_skip_packet
.text:0003407A 76 67 jbe short loc_340E3
.text:0003407C 6A 10 push 10h ; Priority
.text:0003407E 8D 46 EC lea eax, [esi-14h]
.text:00034081 68 54 43 69 77 push 77694354h ; Tag
.text:00034086 33 FF xor edi, edi
.text:00034088 50 push eax ; NumberOfBytes
.text:00034089 47 inc edi
.text:0003408A 53 push ebx ; PoolType
.text:0003408B 89 7D 80 mov [ebp+var_80], edi
.text:0003408E 89 45 88 mov [ebp+Length], eax
.text:00034091 FF 15 AC F2 04 00 call ds:__imp__ExAllocatePoolWithTagPriority@16 ; ExAllocatePoolWithTagPriority(x,x,x,x)
.text:00034097 3B C3 cmp eax, ebx
.text:00034099 89 45 A8 mov [ebp+VirtualAddress], eax
.text:0003409C 75 0C jnz short loc_340AA
.text:0003409E BE FE 2A 00 00 mov esi, 2AFEh
.text:000340A3 56 push esi
.text:000340A4 57 push edi
.text:000340A5 E9 3C 14 00 00 jmp loc_354E6
另外如果你要发送伪造的源地址,你需要关闭WINDOWS XP的个人防火墙方可.
顺便做些对比: window 2003 sp1 对应代码如下:
text:0003A088 F7 D0 not eax
.text:0003A08A 66 89 41 0A mov [ecx+0Ah], ax
.text:0003A08E 38 1D B0 CC 08 00 cmp _RunningOnWorkstation, bl <---如果是工作站上运行的话也会有限制,不过你是server的话就没有问题....试过了,确实没有问题
.text:0003A094 74 46 jz short loc_3A0DC
.text:0003A096 8B 4D AC mov ecx, [ebp+var_54]
.text:0003A099 8A 41 09 mov al, [ecx+9]
.text:0003A09C 3C 06 cmp al, 6
.text:0003A09E 74 2C jz short loc_3A0CC
.text:0003A0A0 3C 04 cmp al, 4
.text:0003A0A2 74 28 jz short loc_3A0CC
.text:0003A0A4 3C 29 cmp al, 29h
.text:0003A0A6 74 24 jz short loc_3A0CC
.text:0003A0A8 FF 71 0C push dword ptr [ecx+0Ch]
.text:0003A0AB E8 0B A5 FE FF call _GetAddrType@4 ; GetAddrType(x)
.text:0003A0B0 84 C0 test al, al
.text:0003A0B2 74 28 jz short loc_3A0DC
.text:0003A0B4 8B 45 AC mov eax, [ebp+var_54]
.text:0003A0B7 FF 70 10 push dword ptr [eax+10h]
.text:0003A0BA E8 FC A4 FE FF call _GetAddrType@4 ; GetAddrType(x)
.text:0003A0BF 3C 03 cmp al, 3
.text:0003A0C1 75 09 jnz short loc_3A0CC
.text:0003A0C3 8B 45 84 mov eax, [ebp+var_7D+1]
.text:0003A0C6 F6 40 0C 20 test byte ptr [eax+0Ch], 20h
.text:0003A0CA 75 10 jnz short loc_3A0DC
.text:0003A0CC
.text:0003A0CC loc_3A0CC: ; CODE XREF: _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13E69j
.text:0003A0CC ; _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13E6Dj ...
.text:0003A0CC FF 05 AC 04 06 00 inc dword_604AC
.text:0003A0D2 BE 2A 2B 00 00 mov esi, 2B2Ah
.text:0003A0D7 E9 C6 00 00 00 jmp loc_3A1A2
.text:0003A0DC ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0003A0DC
.text:0003A0DC loc_3A0DC: ; CODE XREF: _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13E5Fj
.text:0003A0DC ; _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13E7Dj ...
.text:0003A0DC 8B 45 AC mov eax, [ebp+var_54]
.text:0003A0DF 66 8B 95 36 FF FF FF mov dx, [ebp-0CAh]
.text:0003A0E6 33 C9 xor ecx, ecx
.text:0003A0E8 8A 08 mov cl, [eax]
.text:0003A0EA 66 89 50 02 mov [eax+2], dx
.text:0003A0EE 8B 45 84 mov eax, [ebp+var_7D+1]
.text:0003A0F1 8A 40 0A mov al, [eax+0Ah]
.text:0003A0F4 8B 55 AC mov edx, [ebp+var_54]
.text:0003A0F7 88 42 01 mov [edx+1], al
.text:0003A0FA 8B 45 AC mov eax, [ebp+var_54]
.text:0003A0FD 66 89 58 0A mov [eax+0Ah], bx
.text:0003A101 83 E1 0F and ecx, 0Fh
.text:0003A104 8B C1 mov eax, ecx
.text:0003A106 C1 E0 02 shl eax, 2
.text:0003A109 50 push eax
.text:0003A10A FF 75 AC push [ebp+var_54]
.text:0003A10D 53 push ebx
.text:0003A10E FF 15 38 01 06 00 call _tcpxsum_routine ; tcpxsum(x,x,x)
.text:0003A114 8B 4D AC mov ecx, [ebp+var_54]
.text:0003A117 8B 75 8C mov esi, [ebp+var_74]
.text:0003A11A F7 D0 not eax
.text:0003A11C 66 89 41 0A mov [ecx+0Ah], ax
.text:0003A120 E9 D8 C4 FE FF jmp loc_265FD
.text:0003A125 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:0003A125
.text:0003A125 loc_3A125: ; CODE XREF: _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13FE2j
.text:0003A125 33 F6 xor esi, esi
.text:0003A127
.text:0003A127 loc_3A127: ; CODE XREF: _IPTransmit(x,x,x,x,x,x,x,x,x,x)+13FEDj
.text:0003A127 56 push esi ; int
.text:0003A128 6A 01 push 1 ; P
.text:0003A12A FF 75 B4 push [ebp+var_4C] ; BytesCopied
.text:0003A12D E8 EC B8 FE FF call _FreeIPPacket@12 ; FreeIPPacket(x,x,x)
.text:0003A132 39 5D B0 cmp [ebp+var_50], ebx
.text:0003A135 0F 84 F4 0C FE FF jz loc_1AE2F
.text:0003A13B FF 75 B0 push [ebp+var_50]
.text:0003A13E E9 85 03 00 00 jmp loc_3A4C8
WIN2003 ENT原版:
text:00023BB0 loc_23BB0: ; CODE XREF: SendRSTFromTCB(x,x)+42A7j
.text:00023BB0 mov eax, [ebp+4]
.text:00023BB3 mov [eax+0Ch], edx
.text:00023BB6 mov eax, [ebp+4]
.text:00023BB9 mov [eax+1Ch], bl
.text:00023BBC mov eax, [ebp+Packet]
.text:00023BBF movzx eax, byte ptr [eax]
.text:00023BC2 and eax, 0Fh
.text:00023BC5 shl eax, 2
.text:00023BC8 cmp eax, esi
.text:00023BCA mov [ebp+arg_54], eax
.text:00023BCD jb loc_2F98C
.text:00023BD3 ja loc_23A81
.text:00023BD9
.text:00023BD9 loc_23BD9: ; CODE XREF: SendRSTFromTCB(x,x)-7C01j
.text:00023BD9 mov eax, [ebp+arg_58]
.text:00023BDC mov eax, [eax+14h]
.text:00023BDF mov esi, [ebp+arg_54]
.text:00023BE2 push 10h ; Priority
.text:00023BE4 push [ebp+var_4C] ; int
.text:00023BE7 add eax, esi
.text:00023BE9 sub [ebp+arg_5C], eax
.text:00023BEC call _TcpipBufferVirtualAddress@8 ; TcpipBufferVirtualAddress(x,x)
.text:00023BF1 cmp eax, ebx
.text:00023BF3 jz loc_2F9DB
.text:00023BF9 mov ecx, [ebp+var_4C]
.text:00023BFC mov edi, [ecx]
.text:00023BFE mov ecx, [ecx+14h]
.text:00023C01 sub ecx, esi
.text:00023C03 jz loc_2F9CB
.text:00023C09 push ecx ; Length
.text:00023C0A add eax, esi
.text:00023C0C push eax ; VirtualAddress
.text:00023C0D push _BufferPool ; PoolHandle
.text:00023C13 lea eax, [ebp+Buffer]
.text:00023C19 push eax ; Buffer
.text:00023C1A lea eax, [ebp+Status]
.text:00023C1D push eax ; Status
.text:00023C1E call ds:__imp__NdisAllocateBuffer@20 ; NdisAllocateBuffer(x,x,x,x,x)
.text:00023C24
.text:00023C24 loc_23C24: ; CODE XREF: SendRSTFromTCB(x,x)+4321j
.text:00023C24 ; SendRSTFromTCB(x,x)+432Dj
.text:00023C24 cmp [ebp+Status], ebx
.text:00023C27 jnz loc_2FA12
.text:00023C2D mov eax, [ebp+MemoryDescriptorList]
.text:00023C30 mov ecx, [ebp+var_4C]
.text:00023C33 mov [eax+1Ch], ecx
.text:00023C36 mov eax, [ebp+Buffer]
.text:00023C3C mov ecx, [ebp+arg_58]
.text:00023C3F mov [ecx], eax
.text:00023C41 mov [eax], edi
.text:00023C43 mov edi, [ebp+Packet]
.text:00023C46 mov [ecx+14h], ebx
.text:00023C49 cmp [edi+4], bx
.text:00023C4D jnz short loc_23C71
.text:00023C4F xor eax, eax
.text:00023C51 inc eax
.text:00023C52 mov ecx, offset _IPIDCacheLine
.text:00023C57 lock xadd [ecx], eax
.text:00023C5B mov [edi+4], ax
.text:00023C5F mov edi, [ebp+Packet]
.text:00023C62 mov ax, [edi+4]
.text:00023C66 mov ch, al
.text:00023C68 mov cl, ah
.text:00023C6A mov [edi+4], cx
.text:00023C6E mov edi, [ebp+Packet]
.text:00023C71
.text:00023C71 loc_23C71: ; CODE XREF: SendRSTFromTCB(x,x)-7A93j
.text:00023C71 mov eax, [ebp+arg_5C]
.text:00023C74 add esi, eax
.text:00023C76 mov ax, si
.text:00023C79 mov esi, [ebp+MemoryDescriptorList]
.text:00023C7C mov ch, al
.text:00023C7E mov cl, ah
.text:00023C80 mov eax, [ebp+arg_68]
.text:00023C83 mov [edi+2], cx
.text:00023C87 mov al, [eax+0Ah]
.text:00023C8A mov ecx, [ebp+Packet]
.text:00023C8D mov [ecx+1], al
.text:00023C90 mov eax, [ebp+Packet]
.text:00023C93 mov [eax+0Ah], bx
.text:00023C97 jmp loc_13544
.text:00023C97 ; END OF FUNCTION CHUNK FOR _SendRSTFromTCB@8
.text:00023C9C ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00023C9C ; START OF FUNCTION CHUNK FOR _IPTransmit@40
.text:00023C9C
.text:00023C9C loc_23C9C: ; CODE XREF: IPTransmit(x,x,x,x,x,x,x,x,x,x)+5Fj
.text:00023C9C cmp [ebp+50h+arg_C], 0FFFFh
.text:00023CA3 jg loc_2F3EA
.text:00023CA9 jmp loc_1330F
.text:00023CAE ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00023CAE
.text:00023CAE loc_23CAE: ; CODE XREF: IPTransmit(x,x,x,x,x,x,x,x,x,x)+1B5j
.text:00023CAE mov eax, [ebp+50h+arg_8]
.text:00023CB1 mov esi, [eax]
.text:00023CB3 lea eax, [ebp+50h+var_54]
.text:00023CB6 push eax
.text:00023CB7 push _IpHeaderPool
.text:00023CBD mov [ebp+50h+var_D4], ebx
.text:00023CC3 mov [ebp+50h+var_9C], esi
.text:00023CC6 call _MdpAllocate@8 ; MdpAllocate(x,x)
.text:00023CCB cmp eax, ebx
.text:00023CCD mov [ebp+50h+var_98], eax
.text:00023CD0 jz loc_26B4C
.text:00023CD6 push 10h ; Priority
.text:00023CD8 push esi ; int
.text:00023CD9 call _TcpipBufferVirtualAddress@8 ; TcpipBufferVirtualAddress(x,x)
.text:00023CDE jmp loc_23B63
如果你修改了tcpip.sys,记得也把它的checksum修正一下.