3) "BIND Over Write AndX"简介 当Bind(11)由SMB命令Write AndX(0x2f)承载时,即"BIND Over Write AndX"。 可以简单地将Transaction理解成Write/Read的合成命令,区别在于前者处理小数据 量的通信,后者处理大数据量的通信。至于多少算小多少算大,你我都不必关心细节。 它们之间的关系远非如此简单,与本文关系不大,不纠缠了。 前面说过,SMB层的实现同时用到了139、445/TCP,二者之间是竞争关系。此次出于 演示目的,我用程序手工发送报文,指定使用445/TCP。下面是一次枚举共享操作中 出现的报文(SMB_37_4.cap): -------------------------------------------------------------------------- Transmission Control Protocol, Src Port: 37665 (37665), Dst Port: 445 (445), Len: 140 NetBIOS Session Service Message Type: Session message Length: 136 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response in: 2 SMB Command: Write AndX (0x2f) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x08 0... .... = Request/Response: Message is a request to the server .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc001 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 0... .... .... = Extended Security Negotiation: Extended security negotiation is not supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 38271 User ID: 2048 Multiplex ID: 25139 Write AndX Request (0x2f) Word Count (WCT): 14 AndXCommand: No further commands (0xff) Reserved: 00 AndXOffset: 0 FID: 0x4000 Offset: 0 Reserved: FFFFFFFF Write Mode: 0x0008 .... .... .... 1... = Message Start: This is the START of a MESSAGE (pipe) .... .... .... .0.. = Write Raw: DON'T use WriteRawNamedPipe (pipe) .... .... .... ..0. = Return Remaining: DON'T return remaining (pipe/dev) .... .... .... ...0 = Write Through: Write through not requested Remaining: 72 Data Length High (multiply with 64K): 0 Data Length Low: 72 Data Offset: 64 High Offset: 0 Byte Count (BCC): 73 Padding: 00 DCE RPC Bind, Fragment: Single, FragLen: 72, Call: 1 Version: 5 Version (minor): 0 Packet type: Bind (11) Packet Flags: 0x03 0... .... = Object: Not set .0.. .... = Maybe: Not set ..0. .... = Did Not Execute: Not set ...0 .... = Multiplex: Not set .... 0... = Reserved: Not set .... .0.. = Cancel Pending: Not set .... ..1. = Last Frag: Set .... ...1 = First Frag: Set Data Representation: 10000000 Byte order: Little-endian (1) Character: ASCII (0) Floating-point: IEEE (0) Frag Length: 72 Auth Length: 0 Call ID: 1 Max Xmit Frag: 4280 Max Recv Frag: 4280 Assoc Group: 0x00000000 Num Ctx Items: 1 Context ID: 0 Num Trans Items: 1 Interface UUID: 4b324fc8-1670-01d3-1278-5a47bf6ee188 Interface Ver: 3 Interface Ver Minor: 0 Transfer Syntax: 8a885d04-1ceb-11c9-9fe8-08002b104860 Syntax ver: 2 0040 00 00 00 88 ff 53 4d 42 2f 00 00 00 00 08 .....SMB/..... 0050 01 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ 0060 7f 95 00 08 33 62 0e ff 00 00 00 00 40 00 00 00 ....3b......@... 0070 00 ff ff ff ff 08 00 48 00 00 00 48 00 40 00 00 .......H...H.@.. 0080 00 00 00 49 00 00 05 00 0b 03 10 00 00 00 48 00 ...I..........H. 0090 00 00 01 00 00 00 b8 10 b8 10 00 00 00 00 01 00 ................ 00a0 00 00 00 00 01 00 c8 4f 32 4b 70 16 d3 01 12 78 .......O2Kp....x 00b0 5a 47 bf 6e e1 88 03 00 00 00 04 5d 88 8a eb 1c ZG.n.......].... 00c0 c9 11 9f e8 08 00 2b 10 48 60 02 00 00 00 ......+.H`.... Transmission Control Protocol, Src Port: 445 (445), Dst Port: 37665 (37665), Len: 51 NetBIOS Session Service Message Type: Session message Length: 47 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response to: 1 Time from request: 0.000601000 seconds SMB Command: Write AndX (0x2f) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x88 1... .... = Request/Response: Message is a response to the client/redirector .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc001 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 0... .... .... = Extended Security Negotiation: Extended security negotiation is not supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 38271 User ID: 2048 Multiplex ID: 25139 Write AndX Response (0x2f) Word Count (WCT): 6 AndXCommand: No further commands (0xff) Reserved: 00 AndXOffset: 47 FID: 0x4000 Count Low: 72 Remaining: 65535 Count High (multiply with 64K): 0 Reserved: 0000 Byte Count (BCC): 0 0040 00 00 00 2f ff 53 4d 42 2f 00 00 00 00 88 .../.SMB/..... 0050 01 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ 0060 7f 95 00 08 33 62 06 ff 00 2f 00 48 00 ff ff 00 ....3b.../.H.... 0070 00 00 00 00 00 ..... -------------------------------------------------------------------------- 对于139/TCP来说,TCP数据区前4字节算是NBT层的。对于445/TCP来说,TCP数据区前 4字节不算是NBT层的,直接交给SMB层的代码处理了,但在旁路解码处理时,不必关 心这些细节,方便起见,仍称这4字节为NBT层数据。 对比SMB_37_2.cap与SMB_37_4.cap中NBT层的解码,后者已经没有了Flags字段,而 Length字段由17-bits扩展到24-bits。 Write AndX(0x2f)承载的RPC层仍占72字节,与前面两小节相比没有任何区别,作为 承载者的SMB层本身却发生重大变化。SMB Command变成Write AndX(0x2f),对SMB层 的解码也就变了,Data Offset字段本身在TCP数据区的偏移变成59。Data Length等 于72,正好是RPC层的大小,RPC层是做为SMB层数据区出现的! 至此已经很清晰地感受到协议分层处理这个事实。在讨论DCE/MS RPC时,应将SMB层 看作与TCP层一样的传输层,RPC层可以在这些传输层中选择一个作为承载者。至于传 输层内部如何实现,不关RPC层的事。 用协议分析工具时可以先过滤出Write AndX(0x2f),再直接假设RPC层在TCP数据区的 偏移是+0x044,进而针对RPC层各字段进行过滤。 与前面两小节相比,另一个重要变化是Bind_ack(12)报文并未随Write AndX(0x2f)的 响应报文出现,此时必须显式调用Read AndX(0x2e)读取Bind_ack(12): -------------------------------------------------------------------------- Transmission Control Protocol, Src Port: 37665 (37665), Dst Port: 445 (445), Len: 63 NetBIOS Session Service Message Type: Session message Length: 59 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response in: 4 SMB Command: Read AndX (0x2e) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x08 0... .... = Request/Response: Message is a request to the server .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc001 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 0... .... .... = Extended Security Negotiation: Extended security negotiation is not supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 39203 User ID: 2048 Multiplex ID: 46171 Read AndX Request (0x2e) Word Count (WCT): 12 AndXCommand: No further commands (0xff) Reserved: 00 AndXOffset: 0 FID: 0x4000 Offset: 0 Max Count Low: 32767 Min Count: 32767 Remaining: 32767 High Offset: 0 Byte Count (BCC): 0 0040 00 00 00 3b ff 53 4d 42 2e 00 00 00 00 08 ...;.SMB...... 0050 01 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ 0060 23 99 00 08 5b b4 0c ff 00 00 00 00 40 00 00 00 #...[.......@... 0070 00 ff 7f ff 7f ff ff ff ff ff 7f 00 00 00 00 00 ................ 0080 00 . Transmission Control Protocol, Src Port: 445 (445), Dst Port: 37665 (37665), Len: 132 NetBIOS Session Service Message Type: Session message Length: 128 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response to: 3 Time from request: 0.000471000 seconds SMB Command: Read AndX (0x2e) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x88 1... .... = Request/Response: Message is a response to the client/redirector .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc001 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 0... .... .... = Extended Security Negotiation: Extended security negotiation is not supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 39203 User ID: 2048 Multiplex ID: 46171 Read AndX Response (0x2e) Word Count (WCT): 12 AndXCommand: No further commands (0xff) Reserved: 00 AndXOffset: 0 FID: 0x4000 Remaining: 0 Data Compaction Mode: 0 Reserved: 0000 Data Length Low: 68 Data Offset: 60 Data Length High (multiply with 64K): 0 Reserved: 000000000000 Byte Count (BCC): 69 Padding: 00 DCE RPC Bind_ack, Fragment: Single, FragLen: 68, Call: 1 Version: 5 Version (minor): 0 Packet type: Bind_ack (12) Packet Flags: 0x03 0... .... = Object: Not set .0.. .... = Maybe: Not set ..0. .... = Did Not Execute: Not set ...0 .... = Multiplex: Not set .... 0... = Reserved: Not set .... .0.. = Cancel Pending: Not set .... ..1. = Last Frag: Set .... ...1 = First Frag: Set Data Representation: 10000000 Byte order: Little-endian (1) Character: ASCII (0) Floating-point: IEEE (0) Frag Length: 68 Auth Length: 0 Call ID: 1 Max Xmit Frag: 4280 Max Recv Frag: 4280 Assoc Group: 0x00024b67 Scndry Addr len: 13 Scndry Addr: \PIPE\ntsvcs Num results: 1 Ack result: Acceptance (0) Transfer Syntax: 8a885d04-1ceb-11c9-9fe8-08002b104860 Syntax ver: 2 0040 00 00 00 80 ff 53 4d 42 2e 00 00 00 00 88 .....SMB...... 0050 01 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ 0060 23 99 00 08 5b b4 0c ff 00 00 00 00 00 00 00 00 #...[........... 0070 00 44 00 3c 00 00 00 00 00 00 00 00 00 00 00 45 .D.<...........E 0080 00 00 05 00 0c 03 10 00 00 00 44 00 00 00 01 00 ..........D..... 0090 00 00 b8 10 b8 10 67 4b 02 00 0d 00 5c 50 49 50 ......gK....\PIP 00a0 45 5c 6e 74 73 76 63 73 00 00 01 00 00 00 00 00 E\ntsvcs........ 00b0 00 00 04 5d 88 8a eb 1c c9 11 9f e8 08 00 2b 10 ...]..........+. 00c0 48 60 02 00 00 00 H`.... -------------------------------------------------------------------------- Bind_ack(12)报文随Read AndX(0x2e)的响应报文出现。Data Offset字段本身在TCP 数据区的偏移是49。 用协议分析工具时可以先过滤出Read AndX(0x2e),再直接假设RPC层在TCP数据区的 偏移是+0x040,进而针对RPC层各字段进行过滤。重复提醒,Padding字段长度不固定, 偏移+0x040只是权宜之计,如能动态根据Data Offset字段的值计算偏移最好不过。 前两小节的BIND操作只涉及一来一回两个报文,本小节的BIND操作却涉及四个报文, 麻烦了许多。一般"BIND Over Transaction"都能安全替代"BIND Over Write AndX", 自己写程序实现BIND操作时不必选用后者。但是在协议分析过程中,却有可能同时碰 上二者。 扯远一点。当出现一些DCE/MS RPC类蠕虫时,会有公司或个人提供一些定制后的过滤 规则。从我们前期的短小分析来看,这些过滤规则面临一些难题,或者说因协议分析 工具自身能力不足带来的难题。一是动态端口,这个现在仍不急着讲。二是从协议层 次上精确定位RPC层,我不清楚现有工具中哪个可以识别了SMB Command之后动态定位 Data Offset字段本身在TCP数据区的偏移,动态根据Data Offset字段的值计算RPC层 在TCP数据区的偏移,同时以这个偏移为基准定位其它RPC层的协议字段。更多时候这 些公开发布的过滤规则就像我前面介绍的那样,做了一些重大假设,比如填充域长度 固定,只考虑"BIND Over Write AndX",不考虑"BIND Over Transaction"等等。针对 蠕虫的某一特定实例,做这样的重大假设是可以的,其作者不太可能变态到同时实现 了两种BIND操作,随机挑着用。但我今天这么公开提到了,难说下次蠕虫作者不这样 干。真要出现这样的局面,只好设置多套过滤,逻辑或一下。总有人抱怨过滤规则不 工作,那是因为出现了蠕虫变种、Exploit变种等等,违背了原过滤规则所做的重大 假设。这时应抓取样本报文,自行设置过滤规则。话说回来,协议分析工具做这种事 确实太勉为其难了,交互式分析工具严重依赖于人的参与,这也导致NIDS、NIPS必然 出场。NIDS、NIPS是程序实现的解码分析,灵活得多。 协议分析工具、NIDS、NIPS的相同点是都要做协议分层解码,都要逐层剥离,一旦中 间某层解码失败,作为负载出现的后续层次都将解码失败。DCE/MS RPC由SMB承载时, 首先要对SMB层进行解码才好继续进行后续分析。Ethereal是目前我所用过的协议分 析工具中对SMB层解码最深入的一个,推荐使用。而Samba是目前我所见过的对SMB层 Hacking最深的开源项目,远比Ethereal深入,甚至可以说不在一个层次。即使现在 部份Windows源码泄露,也还是值得研读Samba源码。 协议分层越多,解码越麻烦,也越容易忽略许多例外情形。换句话说,很多工具、程 序只考虑到最常见的情形,多多少少、有意无意做了一些假设,当例外情形出现违背 了这些假设,问题就来了。Ethereal对SMB层解码太深,历史上出现过的问题就很多, 我敢打赌,到现在还有问题。至于Samba么,一样的,在Samba项目的历史上出现过很 多现在也鲜为人知的趣事,这群天才们从无到有Hacking SMB,那还是Windows的早期, Samba与Windows通信时搞出个BSOD实在是太普通了。要是搁在现在,不成了大漏洞、 大新闻么。当时的环境、氛围与现在太不同,最终多半是安静地通知微软并协助修补 了事。有个叫Luke Kenneth Casson Leighton的人,此人是半路加盟Samba Team的, 也算是天才,很强悍,后来因个人理念冲突与Samba Team分道扬镳,再后来加入ISS 的XForce小组继续从事SMB协议分析。他写过一本书: <> 99年出的。因为Ethereal已经得到相当程度的加强,这书搁到现在算不上稀世奇珍了, 但仍可从中找到一些Ethereal至今未做解码的内容,Samba早在99年之前就解码了! 他在该书中提到一件事,NT 4 SP4之前有一个与Auth Length字段相关的BUG,微软成 功地在保持了向后兼容性的前提下修正了BUG,作者称之为"quite a feat"。在该书 中看到多处历史上悄悄修补过的SMB层BUG,叹息啊,没赶上好时光,也没那群天才们 的实力,同时相当佩服微软保持向后兼容性的强悍。 其它协议分析工具对SMB层解码相比Ethereal就太浅了,但同时也少了很多麻烦,比 如Iris这个小不点,当成玩具就可以了,不会擦枪走火的。不要迷信商业版协议分析 软件,一样的,解码越深死得越快,不解码或只简单解码活下来的机会更大。snort、 tcpdump死得不比Ethereal少。ISS的商业版NIDS很强,对SMB层的解码分析能力是我 接触过的同型产品中最强的一个,没办法,人家的XForce小组中就有好几个前Samba Team的人。但这同时意味着解码风险增加,已经出过几次问题了。想像一下,假设我 知道某竞争对手的产品对SMB层解码很强,就针对性地制造畸型SMB报文,会如何。不 过放心啦,国内的NIDS、NIPS没这水平,想搞它们都没机会。这事有点讽刺,就跟傻 也是一种幸福一样。 SMB_37_5.cap与SMB_37_3.cap类似。发送Bind报文试图绑定不存在的接口UUID,引发 Provider rejection(2)报文。承载者都是SMB,但这次是"BIND Over Write AndX"。 同样这个包不可能在身边的环境中抓到,我用程序发出来的,提供在此仅用于研究。 这一节只起对比作用,结果由技术文章写成八卦话题了,就当灌水吧。