Nmap的高级网络服务器指纹识别 httprecon-nse
作者:Sec-Labs | 发布时间:
httprecon - 高级网络服务器指纹识别
简介
httprecon项目正在网络服务器指纹识别领域进行一些研究,也称为http指纹识别。其目标是高度准确地识别给定的httpd实现。这在专业的漏洞分析中是非常重要的。
除了对不同方法的讨论和对收集到的结果的记录,还提供了一个自动分析的实现。这个软件将提高这种列举的便捷性和效率。传统的方法,如banner抓取、状态码列举和标题排序分析被使用。然而,许多其他的分析技术被引入以增加准确的网络服务器指纹识别的可能性。其中一些已经在《渗透测试的艺术》一书中讨论过(第9.3章,HTTP指纹分析,第530-550页)。
项目地址
https://github.com/scipag/httprecon-nse
流程
该应用程序的工作非常简单。在用户定义了应被打指纹的目标服务后,一个普通的TCP连接被打开到目标端口。如果连接可以建立,http请求将被发送到目标服务。这个服务将作出响应。这些可以被剖析以识别一些特定的指纹元素。这些元素在本地指纹数据库中被查找。如果有一个匹配的,相应的实现被标记为 "已识别"。所有这些标志都被计算在内,因此httprecon能够确定哪个实施方案具有最佳的匹配率。

架构
下图说明了整个框架的结构。扫描引擎使用九个不同的请求,这些请求被发送到目标网络服务器上。这些请求将引发可用于指纹识别的响应。使用了不同种类的请求。其中一些是非常常见和合法的(如GET/HTTP/1.1),而其他的请求由于其恶意性质通常是不被接受的(如GET请求中的一个很长的URI)。

响应的剖析是由解析和指纹引擎处理的。正如你所看到的,许多不同的指纹元素被查找(例如,状态码、横幅、Etag长度、头序等)。这些元素被保存在本地的指纹数据库中,允许匹配的总和。所有的数据都是相互关联的,这将导致最终的指纹扫描报告。
特点
这些是httprecon当前实现的主要特点,使该解决方案优于其他同类工具。
许多测试案例。有9个可能的测试案例
- 支持HTTPS/SSL。也可以测试安全的网络服务器
- 先进的结果分析。提供不同的结果分析方法
- 许多指纹细节。分析是基于许多指纹元素
- 纯文本数据库。指纹数据被保存在基于文件的明文数据库中
- 指纹向导。指纹可以在GUI中保存和更新
- IDS规避机制。配置设置允许使用IDS规避机制
- 报告。为专业测试人员提供XML、HTML和TXT报告。
- 自动更新:自动更新功能可以通知新的版本
- 开源(GPLv3)。每个人都可以为自己改进这个应用程序
目前有不同的http指纹识别应用程序。这个Excel表格比较了四个最流行的HTTP指纹工具(httprecon、httprint、hmap和WebserverFP)。
反措施
指纹的可能性不是传统意义上的漏洞,它允许入侵主机。它更像是一种缺陷或暴露,可能为进一步的列举和具体的攻击方案提供基础。

然而,应用一些反措施来强化服务总是一个好主意。由于网络软件之间互动的性质,100%地防止指纹识别是不可能的。但是有一些可能性可以降低这种分析的准确性。这些都是在图中说明的,并在下面列出。
改变或压缩banner
最被接受和广为人知的防御指纹的方法是操纵或改变应用程序的标语。在网络响应中,行服务器宣布了给定的实现的名称。一些网络服务器允许在配置文件中改变这个值。
Apache支持用ServerToken指令来缩减公告。缩减需要Prod的定义,它将只宣布 "Apache"(也见ServerSignature指令)。要改变这个值,需要对源代码中的/src/include/httpd.h文件(AP_SERVER_BASEVENDOR, AP_SERVER_BASEPRODUCT, AP_SERVER_MAJORVERSION_NUMBER, AP_SERVER_MINORVERSION_NUMBER, AP_SERVER_PATCHLEVEL_NUMBER)进行一些操作。
* The below defines the base string of the Server: header. Additional
* tokens can be added via the ap_add_version_component() API call.
*
* The tokens are listed in order of their significance for identifying the
* application.
*
* "Product tokens should be short and to the point -- use of them for
* advertizing or other non-essential information is explicitly forbidden."
*
* Example: "Apache/1.1.0 MrWidget/0.1-alpha"
*/
#define AP_SERVER_BASEVENDOR "Apache Software Foundation"
#define AP_SERVER_BASEPROJECT "Apache HTTP Server"
#define AP_SERVER_BASEPRODUCT "Apache"
#define AP_SERVER_MAJORVERSION_NUMBER 2
#define AP_SERVER_MINORVERSION_NUMBER 2
#define AP_SERVER_PATCHLEVEL_NUMBER 6
#define AP_SERVER_DEVBUILD_BOOLEAN 0
#if AP_SERVER_DEVBUILD_BOOLEAN
#define AP_SERVER_ADD_STRING "-dev"
#else
#define AP_SERVER_ADD_STRING ""
#endif
微软IIS需要在库W3SVC.DLL中使用一些十六进制黑客来改变服务器输出。有一个名为MS IIS/PWS Banner编辑工具的免费软件可以自动进行这种操作。IISBanner是一个著名的ISAPI过滤器,可以通过编辑INI文件安全地删除或掩盖IIS服务器头。微软建议使用 URLscan,它引入了同样的优点。
thttpd 允许在 config.h 文件中做一些细微的改变,在编译过程中引导一些设置(例如 ERR_APPEND_SERVER_INFO 用于在服务器生成的错误页面中公布服务器名称或 DEFAULT_CHARSET 中默认的字符集 iso-8859-1)。此外,还可以改变SHOW_SERVER_VERSION,以抑制服务器行中的版本号公告。要改变或抑制真正的服务器名称,需要修改 libhttpd.c 中的 EXPOSED_SERVER_SOFTWARE。
#define EXPOSED_SERVER_SOFTWARE SERVER_SOFTWARE
#else /* SHOW_SERVER_VERSION */
#define EXPOSED_SERVER_SOFTWARE "thttpd"
#endif /* SHOW_SERVER_VERSION */
开源网络服务器fnord不支持任何配置设置,也不支持在源代码中进行常量突变,以方便修改应用行为。网络服务器作为FNORD的公告是在httpd.c中buffer_puts()创建的分离式回复中实现的,这包括应用程序的标语、状态信息和头文件的顺序。然而,加强搜索和替换的修改可能会改善隐蔽性,而不触及应用程序的架构。进一步的改进,如引入新的http方法(在1.10版本中默认只支持GET、POST和HEAD)需要一些更深层次的修改。
一些模块(如PHP和SSH)在服务器行中公布自己。在大多数情况下,这可以通过对相应模块的配置设置来防止。对于PHP来说,在文件php.ini中,expose_php的值必须被设置为Off。
改变状态代码和状态文本
网络服务器在其响应中包括与实施相关的状态码和状态文本。改变它们可以防止今天的大多数网络服务器的指纹识别。只有少数http守护进程允许在运行时配置中对基本行为进行这种改变。
Apache需要在源代码中进行一些修改,并重新编译。在/src/include/httpd.h中,状态码被定义为整数常量。
* The size of the static array in http_protocol.c for storing
* all of the potential response status-lines (a sparse table).
* A future version should dynamically generate the apr_table_t at startup.
*/
#define RESPONSE_CODES 57
#define HTTP_CONTINUE 100
#define HTTP_SWITCHING_PROTOCOLS 101
#define HTTP_PROCESSING 102
#define HTTP_OK 200
#define HTTP_CREATED 201
#define HTTP_ACCEPTED 202
#define HTTP_NON_AUTHORITATIVE 203
#define HTTP_NO_CONTENT 204
#define HTTP_RESET_CONTENT 205
#define HTTP_PARTIAL_CONTENT 206
#define HTTP_MULTI_STATUS 207
#define HTTP_MULTIPLE_CHOICES 300
#define HTTP_MOVED_PERMANENTLY 301
#define HTTP_MOVED_TEMPORARILY 302
#define HTTP_SEE_OTHER 303
#define HTTP_NOT_MODIFIED 304
#define HTTP_USE_PROXY 305
#define HTTP_TEMPORARY_REDIRECT 307
#define HTTP_BAD_REQUEST 400
#define HTTP_UNAUTHORIZED 401
#define HTTP_PAYMENT_REQUIRED 402
#define HTTP_FORBIDDEN 403
#define HTTP_NOT_FOUND 404
#define HTTP_METHOD_NOT_ALLOWED 405
#define HTTP_NOT_ACCEPTABLE 406
#define HTTP_PROXY_AUTHENTICATION_REQUIRED 407
#define HTTP_REQUEST_TIME_OUT 408
#define HTTP_CONFLICT 409
#define HTTP_GONE 410
#define HTTP_LENGTH_REQUIRED 411
#define HTTP_PRECONDITION_FAILED 412
#define HTTP_REQUEST_ENTITY_TOO_LARGE 413
#define HTTP_REQUEST_URI_TOO_LARGE 414
#define HTTP_UNSUPPORTED_MEDIA_TYPE 415
#define HTTP_RANGE_NOT_SATISFIABLE 416
#define HTTP_EXPECTATION_FAILED 417
#define HTTP_UNPROCESSABLE_ENTITY 422
#define HTTP_LOCKED 423
#define HTTP_FAILED_DEPENDENCY 424
#define HTTP_UPGRADE_REQUIRED 426
#define HTTP_INTERNAL_SERVER_ERROR 500
#define HTTP_NOT_IMPLEMENTED 501
#define HTTP_BAD_GATEWAY 502
#define HTTP_SERVICE_UNAVAILABLE 503
#define HTTP_GATEWAY_TIME_OUT 504
#define HTTP_VERSION_NOT_SUPPORTED 505
#define HTTP_VARIANT_ALSO_VARIES 506
#define HTTP_INSUFFICIENT_STORAGE 507
#define HTTP_NOT_EXTENDED 510
而在 /src/modules/http/http_protocol.c 中,statustexts 被定义为字符串常量。
#else
static const char * const status_lines[RESPONSE_CODES] =
#endif
{
"100 Continue",
"101 Switching Protocols",
"102 Processing",
#define LEVEL_200 3
"200 OK",
"201 Created",
"202 Accepted",
"203 Non-Authoritative Information",
"204 No Content",
"205 Reset Content",
"206 Partial Content",
"207 Multi-Status",
#define LEVEL_300 11
"300 Multiple Choices",
"301 Moved Permanently",
"302 Found",
"303 See Other",
"304 Not Modified",
"305 Use Proxy",
"306 unused",
"307 Temporary Redirect",
#define LEVEL_400 19
"400 Bad Request",
"401 Authorization Required",
"402 Payment Required",
"403 Forbidden",
"404 Not Found",
"405 Method Not Allowed",
"406 Not Acceptable",
"407 Proxy Authentication Required",
"408 Request Time-out",
"409 Conflict",
"410 Gone",
"411 Length Required",
"412 Precondition Failed",
"413 Request Entity Too Large",
"414 Request-URI Too Large",
"415 Unsupported Media Type",
"416 Requested Range Not Satisfiable",
"417 Expectation Failed",
"418 unused",
"419 unused",
"420 unused",
"421 unused",
"422 Unprocessable Entity",
"423 Locked",
"424 Failed Dependency",
/* This is a hack, but it is required for ap_index_of_response
* to work with 426.
*/
"425 No code",
"426 Upgrade Required",
#define LEVEL_500 46
"500 Internal Server Error",
"501 Method Not Implemented",
"502 Bad Gateway",
"503 Service Temporarily Unavailable",
"504 Gateway Time-out",
"505 HTTP Version Not Supported",
"506 Variant Also Negotiates",
"507 Insufficient Storage",
"508 unused",
"509 unused",
"510 Not Extended"
};
改变特定请求类型的状态反应(例如不支持的http方法,如DELETE)的一个更简单的方法是使用重写规则。可以不使用预期的错误信息405,而是将其转发到404错误网站,这样就不那么有用了。大多数网络服务器支持.htaccess文件中的这种定义。下面的例子是将不需要的请求重定向到403 Forbidden,而不是405 Method Not Allowed,如果Apache网络服务器启用了mod_rewrite。
RewriteRule .* - [F]
改变Header和顺序
一些网络服务器的指纹识别工具会考虑Header值和Header的顺序。在网络服务器中改变这一点通常需要对源代码产生一些深层影响。这需要对给定的应用程序有一个非常高的理解水平。这种侵入性的改变,出错率可能会非常高。
在微软的IIS中,可以添加新的自定义Header信息值,从而改变hEADER信息顺序的概述指纹。仅仅通过添加一个新的Header行(通常网络浏览器会忽略那些以X开头的Header行,例如X-Garbage),就可以减少成功指纹的可能性。这在网站属性中的HTTP头栏中是很容易做到的。这些可以在互联网信息服务(IIS)管理器中的相应网站的上下文菜单中找到。在某些情况下,有可能覆盖一些其他的标头值(例如,302移动信息中的位置)。然而,这对服务器标语本身来说是不可能的。
Add Custom HTTP Header in MS IIS
然而,一些脚本语言,如PHP,允许网络开发者通过header()函数对头文件有一些影响。例如,尽管根本没有使用ASP.NET,但可以使用一个新的头文件,并调用header("X-Powered-By: ASP.NET 2.0")。这损害了指纹分析,特别是如果它是非常静态和基于模式的,以任何方式。在ASP.NET中,函数Response.AppendHeader()也被用于同样的目的。
在JSP中,由javax.servlet.http.HttpServletResponse接口定义的响应对象的不同方法可能被使用:response.setHeader()设置一个头值,response.addHeader()添加一个新的头值,response.header()设置一个整数值的头,response.setDateHeader()设置一个日期值的头(例如,来自System.currentTimeMillis())。
ColdFusion标记语言(CFML)使用标签cfheader来定义头信息和它们的值。状态代码可以用类似的语句来改变,新的标题行可以用类似的语句来引入。
重定向已知的攻击脚本
防御指纹识别工具的另一种方法是重定向攻击脚本,如httprecon。在下面的.htaccess例子中,知名的用户代理被检测到并重定向到攻击者自己的计算机。
RewriteCond %{HTTP_USER_AGENT} ^Nikto [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/4.75 [OR]
RewriteCond %{HTTP_USER_AGENT} ^httprecon
RewriteRule ^(.*)$ http://%{REMOTE_HOST}:80 [R=301,L]
这引入了几个优点。首先,攻击者正在消耗更多的资源,这可能会减慢扫描的速度。第二,大多数攻击脚本不能识别重定向,认为最终的目标主机--也就是攻击者自己的计算机--应该被打上指纹。因此,在某些情况下可能会收集到错误的结果。
然而,这种黑名单技术只有在攻击脚本被正确检测到的情况下才有效。如果攻击者要改变扫描软件的方法和行为,可能就不可能有进一步的重定向。
RewriteCond %{HTTP_USER_AGENT} ^Nikto [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/4.75 [OR]
RewriteCond %{HTTP_USER_AGENT} ^httprecon
RewriteRule ^(.*)$ http://%{REMOTE_HOST}:80 [R=301,L]
这引入了几个优点。首先,攻击者正在消耗更多的资源,这可能会减慢扫描的速度。第二,大多数攻击脚本不能识别重定向,认为最终的目标主机--也就是攻击者自己的计算机--应该被打上指纹。因此,在某些情况下可能会收集到错误的结果。
然而,这种黑名单技术只有在攻击脚本被正确检测到的情况下才有效。如果攻击者要改变扫描软件的方法和行为,可能就不可能有进一步的重定向。
琐事和趣事
在开发httprecon和在专业渗透测试中使用该软件的过程中,可以观察到一些有趣的事情。
Wordpress正在使用标题 "X-nananana: Batcache" (@ChrisJohnRiley) (09/22/2010)
只是瑞士的一家大银行正在完全删除服务器线。(04/25/2009)
主机www.ibm.com 有一个错误的头行,它的内容是 "epKe-Alive "而不是 "Keep-Alive"。(04/16/2009)
一家受欢迎的瑞士旅行社将服务器一行定义为 "Game Cube",这显然不是事实。 (11/24/2007)