Hydra的一个BUG

来源:互联网 发布:枪神纪免费刷英雄软件 编辑:程序博客网 时间:2024/06/05 19:58

简介

hydra是一个非常有名的网络暴力破解(brute force attack)工具,被评为Kali(原BackTrack)工具箱的Top 10工具之一。 它的主要特点有:

  • 支持网络协议种类齐全。从系统登录协议、一般的网络应用层协议到Web表单都十分齐全;
  • 内建字典生成引擎。内建一个简单的口令字典生成引擎,能够攻击一般的弱口令;
  • 支持读入字典文件。这个必须要有;
  • 支持中断和恢复。能够停止之后,再重启恢复之前的任务,不怕出故障心血白费了;
  • 多进程并发。同时发起多个连接,虽然非阻塞式IO才是最好的并发方式,ab之类的压力测试工具轻松能够创建上万个连接,但是Linux创建进程的成本很低,再考虑到服务器承受能力一般不会创建太多进程,几十上百足矣,并没有性能上的不足。

它也有硬伤:

  • 不支持使用多http代理和http代理的轮换。原因可能在于它并不是一个特别专业的http表单破解工具;
  • 所有的协议都通过自己实现的套接字连接模块来实现,而自身对连接异常没有准确的处理,导致在防护者配置了防火墙或者IDS的情况下,Hydra会返回错误的结果。

总的来说,作为一款开源工具,Hydra是相当不错的暴力破解专用工具。

使用配置方法

Hydra在http表单暴力破解的典型使用方法如下:

1
hydra -l admin -P PASSWORDS.TXT -t 60 -f HOST http-post-form PATH:POSTDATA:FAILURE_SIGNATURE

以上选项的意义如下所示:

  • -l admin 指定攻击目标的用户ID为admin
  • -P PASSWORD.TXT 指定暴力破解所使用的字典文件
  • -t 60 指定并发任务数为60
  • -f 指定当第一个成功结果出现时就立即返回
  • HOST 的地方填写主机地址(域名或者IP地址)
  • http-post-form 指定攻击方法为HTTP表单攻击
  • PATH:POSTDATA:FAILURE_SIGNATURE 这块由三个字段组成。第一个字段 PATH 指定http请求的远程路径,第二个字段POSTDATA 指定http请求的提交数据,其中用元单词表示用户ID和口令出现的位置,第三个字段 FAILURE_SIGNATURE 指定输入错误口令时的响应数据标识

BUG介绍

表现

在使用过程中,某网站返回了页面重定向,而Hydra将重定向页面丢弃了一个尾字母,定向到了错误的页面。

成因分析

Hydra提供了debug选项,在启动参数中加入 -d 就能够启用调试模式,将代码的具体执行信息打印出来。

在hydra-http-form.c里找找处理重定向的代码:

123456789101112131415
if (hydra_strcasestr(buf, "Location: ") != NULL) {  char *startloc, *endloc;  char str[2048];  startloc = hydra_strcasestr(buf, "Location: ") + strlen("Location: ");  strncpy(str, startloc, sizeof(str) - 1);  str[sizeof(str) - 1] = 0;  endloc = strchr(str, '\n');  if (endloc != NULL)    *endloc = 0;  endloc = strchr(str, '\r');  if (endloc != NULL)    *endloc = 0;  strcpy(redirected_url_buff, str);}

看到就无语了,用最简单的字符数组处理字符串,可能Hydra为了可移植没有使用glibc或者glib里面的高级字符串结构,然后字符串数组很容易就出现长度不够的问题,malloc 堆分配还好点,不过看了几处 malloc 的代码,健壮性也很差,明显有堆溢出漏洞。

不过这还不是出问题的地方,从debug模式下返回的信息可以定位到以下的代码:

123456
if (strlen(str) - strlen(str2) == 0) {  strcpy(str3, "/");} else {  strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) - 1);  str3[strlen(str) - strlen(str2) - 1] = 0;}

看样子这段代码是想把 str 切成 str2str3 两部分,那这个 -1 是怎么回事? strlen 返回的是除去 '\0' 的真实字符串长度,strncpy实际的拷贝长度包括'\0' 字符总共不超过第三个字符指定的长度,那这个减一就莫名其妙了,应该是加1才是。

而下面的那句代码 str3[strlen(str) - strlen(str2) - 1] = 0; 就是祸根,两个长度都是除去 '\0' 的真实字符串长度,这样岂不是把字符串的最后一位给置零了。

修复

最简单的修复办法是把 strncpy 改成 strcpy ,不指定拷贝长度,而后面的那段画蛇添足的添加 '\0' 的代码也可以扔了。

当然原来作者是考虑一定的健壮性,所以最好的改法是 strncpy 的长度改为加一,而后面代码的 - 1 删去。如下面所示:

123456
if (strlen(str) - strlen(str2) == 0) {  strcpy(str3, "/");} else {  strncpy(str3, str + strlen(str2), strlen(str) - strlen(str2) + 1);  str3[strlen(str) - strlen(str2)] = 0;}

结论

Hydra不是一个专门的http表单暴力破解工具,尽管它有非常不错的暴力破解框架:字典支持、多进程、断点恢复。它的Web请求处理代码不够标准和健壮,这点明显比不上标准的Web请求处理库,如python的urllib2等等。

有意思的是,Hydra似乎有不错的模块化,最好能对http form模块进行重写。