修改 PE 文件隐藏 IIS6 的 banner

本文已发于《黑客X档案》2011.8、9月合刊

一般来说,渗透测试前,都需要做好信息收集的工作,比如探测对方的端口、开放的服务等等。针对 Web 服务软件攻击时,确认对方所使用的 Web 服务软件以及具体版本也非常重要的,特别是针对特定版本的 0day 攻击的时候,需要得到确凿的版本号。

如何确定对方所使用的 Web 服务软件呢?最简单的是,根据 HTTP1.1 的标准中,服务器返回的 HTTP 消息头中 Server 字段中就包含了对方所使用的 Web 服务软件,有些还包含了具体的版本号。我们可以利用 nc 来看一下。

192.168.0.111 是我网段内安的一台 Web 服务器,在命令提示符中运行 nc 以及带上参数:

nc.exe 192.168.0.111 80

然后可见光标闪烁,意味着需要输入信息,依次输入:

HEAD[空格]/ [空格]HTTP/1.1
HOST:192.168.0.11

上面中“[空格]”标识需要读者自行替换成空格来隔开。接着回车两下。HEAD 字段代表只需要服务器返回 HTTP 头,不需要返回数据;后面的 HTTP/1.1 是具体的 HTTP 版本号,现在绝大多数都是 HTTP1.1 的,基本上不会存在 1.0 版本的了。不过要是提交 HEAD / HTTP/1.0 的话,就不需要 HOST 字段了;HOST 字段指服务器的地址,在 HTTP 1.1 标准头中,HOST 字段是必须存在的,而 HTTP 1.0 中是可选的,但是要是只提交 HEAD / HTTP/1.0 的话,会自动转换成 HTTP 1.1 的字段的,不过可以少输一行达到偷懒的效果。之所以要解释这一段,是为了解释为什么有些人疑惑输入 HEAD / HTTP/1.0 却返回的 HTTP 1.1 的消息。最后需要回车再回车也是跟 HTTP1.1 标准有关,前一个回车是 HTTP 1.1 消息头内需要一个回车结尾,后者回车是提交数据。

之后,服务器将返回 HTTP 消息,如下:

HTTP/1.1 200 OK
Content-Length: 11
Content-Type: text/html
Content-Location: http://192.168.0.111/index.htm
Last-Modified: Fri, 08 Jul 2011 09:31:48 GMT
Accept-Ranges: bytes
ETag: "20917dc513dcc1:392"
Server: Microsoft-IIS/6.0
Date: Sun, 10 Jul 2011 06:21:11 GMT
Connection: close

第一行响应的值是 200,说明请求成功,其他字段在这里不需过多解释,详细的可以见 HTTP 协议方面的资料。关键字段是 Server,冒号后面的值暴露出服务器使用的 Web 软件以及具体版本了。根据这个版本很容易推测出对方使用的 Windows 2003 操作系统。

我一直觉得 Server 头应该可以根据需求自己修改的,因为它很多时候它的弊端大于的利端,而 Nginx、Apache 这些开放源码的 Web 服务软件都可以在编译前修改源码中的信息,IIS 是闭源的,是没法通过源码修改的。

但是再闭源,这些信息也是在文件中存在的,可以直接硬修改文件中的信息来隐藏它,研究了许久,终于找到了方法。之后在网上看到 IIS5.0 的 banner 信息也通过类似的方法修改的,却没有找到针对 IIS6.0 的:)

思考一下,Web 服务软件和客户端浏览器是基于客户端(Client)/服务器(Server)模型的,客户端浏览器发出消息,服务端的 Web 服务软件读取数据,然后传给客户端。所以,我们有两个办法来隐藏信息,一是在它传送给客户端的之前就劫持信息,修改后某些敏感信息后再传送,类似于代理,不过这样降低了不少的性能;二是干脆就修改了文件中的信息,让它传给客户端我们修改后的信息。

经过一番研究,终于发现这些信息是存在 c:\windows\system32\inetsrv\w3core.dll 文件中的,对于这样的二进制 PE 文件,只有通过修改二进制来了。下来咱们就开始修改。

默认下,Windows 2003 是开启了系统文件保护的,所以欲开刀,需删除 c:\windows\system32\dllcache 中备份的 w3core.dll 文件。若不删除,修改了文件后会被替换回来的。这个路径需要直接在地址栏中手动输入。

删除后,咱们用 Uedit32 打开 c:\windows\system32\inetsrv\w3core.dll。在茫茫 16 进制代码中,咱们一个一个寻找关键信息是比较麻烦的。咱们直接搜索,点击菜单栏上的“搜索”——“查找”,至于搜索内容,咱们就从刚才用 nc 提交信息后服务器返回的消息中 Server 字段中提取关键字,我就用“6.0”为关键字。记得勾选“查找 ASCII”,如图 1 所示:

%E5%9B%BE1.jpg

图 1

查找结果如图 2:

%E5%9B%BE2.jpg

图 2

图 2 中刷黑部分就是查找的结果,就可以直接修改这里了。我把“36”直接改成“37”,后边的显示就成了 7.0 了,读者可以按自己的喜好修改,这里我伪造成 IIS7.0,如图 3:

%E5%9B%BE3.jpg

图 3

之后对修改后的文件进行保存,不过,因为 IIS 在运行,在保存时需要停止 IIS 的服务。在控制面板-管理工具-服务里,找到 IIS Admin Service,然后停止它。之后保存对 w3core.dll 的修改。倘若还是无法保存,最直接的方法便是将它另存为其他名字,然后删除原 w3core.dll,再将它重命名为 w3core.dll。

保存后再启动 IIS Admin Service 服务,启动后再对它重启一次,保证全部依赖的服务都启动。

图 4是我修改后抓的包,如图:

%E5%9B%BE4.jpg

图 4

图 5是我用 Nmap 扫描的结果,如图 5:

%E5%9B%BE5.jpg

图 5

不过修改后用 httprint 也容易猜测出版本,因为 httprint 采用了 HTTP 指纹识别和 HTTP 签名技术,再结合了统计学的原理。