pentestdb 架构详解

工欲善其事,必先利其器。

在渗透测试领域有琳琅满目的工具、神器,它们可以大大简化渗透测试的工作量。但很多时候仅仅使用别人的工具是不够的,我们需要自己去编写一些脚本、插件来完成定制的内容,而这样的工作会很大程度提升渗透测试的效率。笔者认为没有最好的工具,如果有则一定是自己根据自己需要开发的工具。

本文结合 pentestdb 这个项目介绍一些安全工具设计实现方面的思路,项目地址如下:

https://github.com/alpha1e0/pentestdb

pentestdb 使用 python 语言实现,而 python 这门编程语言非常适合编写此类工具,不仅语法简单、入门容易,而且有大量的非常优秀的库可以帮助我们很快解决问题。

pentestdb 最早的时候只是一个“数据集合”,用于存放一些在渗透测试中常用的信息,比如 webshell 、弱口令字典、url 爆破字典等,后来发现如果基于这些信息编写一些工具则可以一定程度上提高渗透测试的效率,于是有了 pentestdb 当前这个项目。

pentestdb 项目的设计原则:

1、一切围绕“数据”。因此的各种字典文件、特征文件、插件、exploit 是最核心的内容。

2、易用、易扩展。可以通过修改字典文件、特征文件、插件来扩展能力。

3、各个子模块可以相互协调工作。例如一个模块生成的结果可以作为输入给其他模块使用。

4、便携。无需要安装,可在任何 python2.x 环境执行。

在本文中会介绍 pentestdb 的服务识别、google hacking、域名爆破、编解码等内容,希望这些内容对于需要实现工具的人有所启发。

1 服务识别

在 web 渗透测试中,当确定目标站点地址后首先要做的事情就是了解这些 web 站点的相关信息:

1、web 站点所在主机的操作系统是什么

2、使用的编程语言是什么

3、后端的数据库是什么

4、使用的 web 服务器、容器是什么

5、使用哪些开源 CMS 或开源组件

我们会通过发送一些 http 请求通过观察、推测从而获得以上信息。而在探测过程中有如下几种信息是关键的:

1、http 返回中的 header 信息。例如 Server: nginx 表示后端使用的是 nginx 服务器

2、返回html中的信息。例如很多开源CMS会有一个 Powered by xxxx 的字段

3、特殊 url 路径。每种 CMS 都会有一些特殊 url 路径,通过访问这些路径可以确定是否是相关的 CMS

4、robots 文件信息。

例如,我们向目标 web 服务器发送一个 GET 请求,收到了如下信息:

那么我们可以通过返回的 http headers 中的 Server 字段推断出,被测试的 web 站点是搭建在 windows 操作系统上,并且服务器是 IIS8.5,而且进一步我们可以猜测 web 后端可能会使用 ASP/ASP.net/C# 来构建应用。

将这些维度的信息总结、提炼、格式化就形成了 web 的指纹数据库。pentestdb 中的指纹“数据库”使用 yaml 格式来编写,可以参考 app_fingerprint.yaml 这个文件。这里简单举例

以上是 PHPWind 的指纹信息定义,其中:

1、cats 表示该指纹信息的分类,pentestdb 中的其他类别有 OS/Sever/Language/Middleware

2、implies 表示推测的信息,例如 PHPWind 显然可以推断出后端使用了 PHP 作为编程语言

3、matches 是真正的指纹定义。这里有 html/requests/robots 三种方式,html 是正则的定义,用于通过正则表达式在返回的 HTML 中匹配模式; requests 是特殊 URL 的匹配定义, robots 是匹配 robots.txt 文件的模式;另外还有 headers 定义这里没有看到,同样也是使用正则匹配 http headers 中的字段

另外, pentestdb 中其实还有一个 CMS 识别的小模块,其原理和这里的 requests 匹配类似,通过特殊 URL 来匹配,只是规则稍微复杂一些,可参考 cms_fingerprint.yaml 这个文件。

当然可以利用的指纹特征不仅仅有这些,例如不同 web 服务器返回的 headers 中各个字段的顺序是不同的,通过这些顺序也可以猜测到目标的信息。关于这方面的内容可参考 OWASP OTG-INFO-002

https://www.owasp.org/index.php/Fingerprint_Web_Server_(OTG-INFO-002)

不过在多数场合下以上的数据都是够用的。

在定义了指纹之后,就可以编写业务逻辑,只需要一个 http 客户端 requests,然后用 if-esle 实现逻辑代码即可。具体实现可参考 service.py 这个文件。

前文中提到了, pentestdb 最初是一个渗透测试的数据、资源集合,这里也可以看到,这些 yaml 配置文件本身也是很好的记录知识、经验的方法,在研究了某些 CMS 之后完全可以将研究的结果随手添加到 yaml 配置中,这样既记录了知识,又完善了自动化工具。

对 web 指纹识别感兴趣的也可以参考 wappalyzer 这个项目,项目地址:

https://www.wappalyzer.com

该项目提供了一个浏览器插件,在访问网站的时候可以直接显示网站的一些组成信息,非常方便,pentestdb 的指纹格式设计就是参考了该项目。

2 google hacking

google hacking 是一种常见的前期信息收集工具,可以完成子域名收集、敏感文件收集等,当然 google hacking 本身也是一种在互联网上寻找测试对象的好方法。

pentestdb 引入了专门的模块做 google hacking ,语法和 google hacking 的常用语法完全一样,关于 google hacking 语法方面的资料互联网上有很多,可参考 GHDB

https://www.exploit-db.com/google-hacking-database/

本文不再详细介绍。

在 pentestdb 中引入 google hacking 是因为在很多自动化工具中,我们需要直接获取到一个 URL 列表,例如 pentestdb 的 exploit、url 爆破模块都可以直接输入一个 URL 列表进行批量的测试,而是用浏览器是无法实现这些的。

google hacking 模块实现了 bing/google/baidu 三个 SearchEngine ,同时作为一个基础模块(要为子域名爆破服务)提供了 Query 类作为入口方便调用,相关实现可参考 searchengine.py

在 google hacking 的实现中最麻烦的地方在于,目前的搜索引擎都有 机器人识别程序 ,使用脚本进行批量搜索的时候如果不做一些处理,很容易被机器人识别程序发现,并进行“阻断”。

笔者并没有深入研究过几个搜索引擎的机器人识别程序, pentestdb 中使用的 bypass 机器人方法是基于常用的机器人识别算法开发的,实际使用效果不错。机器人识别程序一般通过以下几个特征判别是否是机器人

1、user-agent。爬虫、框架都有“专属”的 user-agent 和浏览器明显不同,例如 python requests 框架的 user-agent 为 python-requests

2、通过同一源的访问频率。如果同一个源地址频繁的访问,则会认为是机器人。注意这里的源,包含源 IP:port/session 等信息。

搜索引擎在发现机器人后,常见的处理方式是发送“挑战页面”,而不是直接断开连接,挑战页面需要人输入验证码从而最终判定是否为机器人程序。

因此,bypass 机器人识别的关键在于: 让搜索引擎觉得工具的的搜索请求来自于不同的、合法的客户端。

在 pentestdb 中使用三种方式来 bypass 机器人识别。

1、修改 user-agent 。 pentestdb 会读取常见浏览器的 user-agent ,然后随机挑选一个来使用

2、随机延时。 pentestdb 在两个相邻 http 请求之间会随机延时 1 到 3 秒时间。

3、添加随机的 X-Forward-For 头部。 搜索引擎可能会通过 X-Forward-For 来获取“真实的”源IP地址,不过该字段是否有意义尚待考证,因为目前至少在国内作为家庭用户一般都是通过 NAT 到运营商网络,所以很多人的源 IP 是一致的,搜索引擎在机器人识别的时候不大可能仅仅通过源 IP 来进行判断。

4、去掉 cookie 头。在 pentestdb 提交查询的时候是不携带 cookie 的,这样搜索引擎无法通过同一个 cookie 来判断是否来自相同的客户端。

3 子域名爆破

当 web 渗透测试的对象是一个较大规模的对象的时候,一般正面突破的可能性比较小,例如一个公司,它的官网一定是防护最严格的地方,这时候我们要考虑旁注,公司一般有一些子域名的网站,不会经常用,从而防护较弱,例如公司一般都有论坛、考试之类的子域名网站,往往更具有价值。因此在 web 渗透测试前期工作中识别出子域名是非常重要的。

在 web 渗透测试中,常见的子域名获取方式有:

1、通过域传送漏洞。如果目标存在域传送漏洞,则可以一劳永逸的获取所有子域名。

2、通过 google hacking。

3、通过字典爆破。

4、通过 C 段,然后通过IP地址反查。不过支持 IP 地址反查的 DNS 比较少。

pentestdb 实现了前三种方式。

DNS 域传送

DNS 服务在部署的时候,为了稳定性,一般会采用主备的模式,而备服务器同步主服务器的信息通过 AXLR 协议,在有的情况下,由于运维人员的错误配置会允许任何源(比如我们自己的电脑)通过 AXLR 访问 DNS 服务器,这就是“域传送漏洞”的原理,一般在手工探测的时候我们会使用:

host -t ns domain; 查询ns记录获取DNS Server,然后:host -l domain server, dig NS domain; 查询ns记录获取DNS Server,然后:dig axlr domain @server,

在 python 当然有 DNS 相关的库, pentestdb 中使用 dnspython 这个库实现 DNS AXLR 查询,可参考 dnsparse.py 文件。

google hacking

子域名查询的另外一种常用的方式就是 google hacking 一般我们通过下面的语法进行查询

site:xxx.com -site:www.xxx.com

pentestdb 中会调用 google hacking 模块进行处理,并返回子域名列表

域名字典爆破

pentestdb 的 dns 目录下收集整理了一些常用的子域名字典文件,工具会基于这些字典文件进行爆破。这里需要注意的是,不要忘了顶级域名的爆破,因为有的网站会有多个顶级域名。例如

xxx.com ==> xxx.cc xxx.xin xxx.info

4 编解码

编解码是非常考验安全人员基本功的的知识,在渗透测试中有广泛的应用,尤其是在 bypass 各种安全机制、安全产品中编解码都起到了重要作用。

web 渗透测试中我们经常使用 firefox+hackbar 或者 burpsuite 来完成编解码,但笔者使用的过程中还是会遇到一些不尽人意的地方,所以自己开发了编解码的工具。

pentestdb 中涉及编解码的有 encode/decode/code 三个子命令,前两者类似有 hackbar,后者用来对文件进行编解码。

为了便于理解,本文将编解码分为“非 ASCII 编解码”和“特殊编解码”。

非 ASCII 编解码

由于 ASCII 只能表示非常有限的字符集,因此对于“非英文”字符无法表示,比如中文,因此有

1、中文专用编码。例如,简体中文的 GB2312/GBK ( GBK 是 GB2312 的扩展集,是目前最常用的,中文 windows 的默认编码),繁体中文的 BIG5

2、Unicode 系列编码。和 GBK 不同的是 Unicode 系列的编码是全球通用的,包含绝大多数语言,常见的有 UTF8/UTF16/UTF32/UTF7

这里需要区分 Unicode 和 UTFxx。 Unicode 只是一个码表,为了便于理解可以将其看作和计算机无关的数学映射,一个自然数对应一个字符,而为了将这个映射实现到计算机中就需要一个“转换格式”,这个就是 UTF(Unicode Transformation Format)

最初的 Unicode 码表长度是小于 65536 的,因此最直观的一种转换方式就是使用 2 个字节表示,这种编码就是 UTF16。因此有时候 Unicode 和 UTFxx 会有一些概念混淆,例如 windows 记事本中的 Unicode 格式其实是 UTF16 格式。

在 python 中实现非 ASCII 编解码是非常简单的事情, python 的标准库里面实现了全世界几乎所有的编解码方式,使用方式非常简单

"some string".decode("utf8") # 将字符串( str 类型)按照 utf8 格式进行解码,返回 unicode 类型字符串 u"一些字符串".encode("gbk") # 将字符串( unicode 类型)按照 gbk 格式进行编码,返回 str 类型字符串

注意这里的 unicode 是 python 内部的一种 Unicode 的数据格式,并非上文的 Unicode 码表。

有时候,我们可能不知道某个字符串的编码格式,需要对编码格式进行猜解,此时可以使用 chardet 这个 python 库。

chardet.detect("some string") ==> {'confidence': 1.0, 'encoding': 'ascii'} chardet.detect(u"中华人民共和国".encode("gbk")) ==> {'confidence': 0.99, 'encoding': 'GB2312'}

chardet 只能获取到一个概率结果,一般在文本较长的时候才能获取较准确的结果

特殊编解码

我们常见的”特殊编解码“有 url 编码、html 编码、base64、php-chr、8 进制、16 进制等等。

这些编码经常和”非 ascii 编解码“混合在一起,例如URL中包含中文的情况,在 firefox 中会先进行 UTF8 编码,然后再使用 URL 编码。

pentestdb 中支持同时制定两种编码方式来进行编解码,而这个是很多其他工具不具备的。

5 其他模块

pentestdb 还有社会化密码生成模块、exploit 模块、C 段扫描模块在此做简单介绍。

社会化密码生成模块

渗透测试的时候我们经常需要去做密码猜解,在猜解的时候获取的信息越多越好,这些信息包括但不限于如下:

人名 昵称 英文名 爱人名称 手机号 QQ号 公司名称 域名

根据这些信息使用一定的模式来生成弱口令字典,猜解正确率会高很多。而这其中最关键的就是 模式 ,例如 XXX520、zhangsan@1111 是将人名加上一些前后缀的修饰。pentestdb 中使用了简单的模式来根据这些信息生成密码字典。

pentestdb 中定义了一些常用的前后缀,例如:

1、常用密码关键数字

_numList = ['123456', '123123', ...]

2、常用前缀列表

_prefixList = ['a','qq','yy','aa','abc', ...]

3、常用密码

_commonPasswd = ['123456', 'a123456', ...]

4、和 partner 混合的常用前缀列表

partnerPrefixList = ['520','5201314','1314','iloveu', ...]

5、和 domian,company 组合的前缀列表

domainPrefixList = ['admin','root','manager', ...]

然后将这些列表和获取的社工信息组合在一起,组合的方式为加前缀、后缀,加分隔符,于是就生成了一份密码文件列表。

exploit 模块

pentestdb 中内置了一个小微的 exploit 框架,其接口参考了知道创宇的 pocsuite

https://github.com/knownsec/Pocsuite

可以基于此框架编写一些 exploit,此框架主要的构成如下:

exploit(包含关于漏洞描述信息) <===> exploit 数据库 <===> exploit 控制器

每个 exploit 都必须填写一些“元信息”,例如:

而这些 元信息 都会存入 sqlite 数据库,在使用的时候 exploit 控制器 可以通过这些 元信息 来过从而滤获得想要的 exploit。这样设计可以提高灵活性,例如现在要对某个 discuz 做测试,可以通过 appName:discuz 找到所有 discuz 的漏洞然后批量验证目标站点是否有这些漏洞。

exploit 模块是一个小微框架,松散结构的,其核心还是提供了方便的过滤方法及组织、格式化 exploit 编写,因此 exploit 并没有提供 payload 生成、多种类型客户端。这也符合 pentestdb 的设计初衷,重点在于组织、归档资源信息。

C 段扫描

pentestdb 的C段扫描模块实现得很简单,因为笔者精力有限,只是简单得调用了 Nmap 做扫描。

对于C段扫描任务,python 中有一个框架 scapy

https://github.com/secdev/scapy

非常适合做此类任务,此框架将常见的网络协议封装成一个个使用起来非常简单直观的类,并且使用中缀语法来构建不同的协议对象,使得协议层面的操作变得非常简单,可以方便得实现很多功能,包括 Nmap/arping/tcpdump/netcat 等等。例如,可以用以下两行代码来进行 ping 操作:

p = IP(dst="1.1.1.1")/ICMP() r = sr1(p)

如果想实现比较复杂的扫描工具,则可以使用 scapy 来实现

6 总结

通过 pentestdb 的介绍可以看到,实现一个安全工具并不是很困难的事情,尤其是使用 python 这样的包含大量第三方库的高级语言,在了解目标需求后可以很快得实现一个定制化的小工具。

这些根据需求定制的安全工具往往也是对安全人员自己来说最“好用”的工具,笔者自己开发的这些工具都在自己的业余和公司工作中发挥了重要的作用,并且提供了非常有价值的代码积累。

原文发布于微信公众号 - 信安之路(xazlsec)

原文发表时间:2018-02-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小文博客

换肤大师国服版FOR6.20即将发布

15750
来自专栏JMCui

Node.js入门以及第一个helloworld程序.

1、概念:简单的说 Node.js 就是运行在服务端的 JavaScript。学之前需要明白Node.js是无法挑战jsp、php或者asp这种老牌网站的地位的...

29030
来自专栏Linyb极客之路

分布式之redis复习精讲

博主的《分布式之消息队列复习精讲》得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。但是还是要说明一下,复习精讲的文章偏面试准备,真正在开发过程中...

18330
来自专栏乐享123

从MongoDB迁移到TokuMx

26180
来自专栏DannyHoo的专栏

利用plist文件查看后台返回数据的数据类型

当看客看到标题的时候或许会有些疑惑,有的人甚至会鄙视写者。查看后台返回的数据类型为什么要用plist文件,这也太麻烦了吧。我既然写这篇博客,肯定是有一定的原因的...

11310
来自专栏緣來來來

第一篇:Python简介和入门

python的创始人为吉多·范罗苏姆(Guido van Rossum)。1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解...

8510
来自专栏不二小段

【爬虫军火库】下载保存图片(文件)

今天开始开一个新坑,暂且叫做【爬虫军火库】吧。以前一直想系统地写些东西,最终大都未能成文,想来我不适合发宏愿立长志,还是一步一个脚印地写点零碎的东西。有关爬虫,...

33680
来自专栏小尘哥的专栏

小程序(1)-入坑

老板想要一个小程序的东西,作为实诚却又没干过小程序开发的程序猿,二话不说,撸起袖子,开整。

16550
来自专栏ImportSource

并发编程-多线程的好处

上一文:并发编程-并发的简史 如果线程使用得当,多线程可以降低你的开发和维护成本,而且还能改善复杂应用程序的性能。多线程让模仿人类工作方式以及交互变得简单,多线...

37360
来自专栏张善友的专栏

事件流处理框架NEsper for .NET

复合事件处理(Complex Event Processing)介绍提到了开源的Esper,NEsper 是一个事件流处理(Event Stream Proce...

25360

扫码关注云+社区

领取腾讯云代金券