freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Whatweb特征修改、插件编写、EXE打包
2021-05-31 10:47:02

​文章目录结构:

0x00 选择whatweb的原因

0x01 简述whatweb打包EXE

0x02 改造whatweb请求头 

0x03 Whatweb插件编写规则细节

0x04 实战开发spring-boot Whitelabel页面匹配

0x05 总结与下载

0x00 选择whatweb的原因

以前写过一篇文字,在windows上安装whatweb和ruby。为什么这么多指纹识别工具,我还要选择whatweb呢?随着工具的增多,我们需要对手上常用的渗透工具对比选择。我对比的主要方向是维护更新、扫描思路、批量支持、扩展修改性、阶段专业性等。PS:如果以后有机会做基础讲解的话,会分析下各阶段工具。

Whatweb指纹分析工具优缺点分析优点:1、综合指纹判断,输出信息全面,2、插件结构完善,插件编写简单3、CMD支持,GUI扩展,4、多目标,IP地址范围支持,多线程,5、代理支持,报头自定义缺点:1、由ruby开发,win下需要配置额外开发环境 2、结果输出复杂,需要额外进行结果解析。3、国际化工具,需要适应国情的插件配置缺点解决办法:1、将whatweb打包成exe运行。【已实现】2、编写脚本,对结果进行自定义解析。【已实现】3、编写脚本,批量实现国内插件转whatweb插件格式

最终还是选择了Whatweb作为我的基础指纹识别工具。PS:文章末尾会附修改及打包好的whatweb0.5.5.1下载地址。

0x01 简述whatweb打包EXE

测试了一下kali下的ruby打包exe工具,发现打包whatweb失败,最终在github找到一个可行的新项目:ruby-packer其打包原理类似python,是将所有的文件打包成一个自解压可执行文件,支持windows、linux、macos平台安装。

pmq20/ruby-packer: https://github.com/pmq20/ruby-packer

Windows下Ruby-packer安装:

首先安装预备环境:1、Visual Studio,所有版本,包括社区版(记得在安装过程中选择"Common Tools for Visual C++"功能)。2、SquashFS Tools::先百度安装巧克力(https://chocolatey.org/),然后执行choco install squashfs3、Ruby:安装ruby环境(https://rubyinstaller.org/)。4、perl:安装perl环境http://strawberryperl.com/。5、Netwide Assembler:安装nasm,并将以上环境可执行文件加入环境变量。6、测试rubyc.exe下载rubyc(https://github.com/pmq20/ruby-packer#unstable-pre-release)打开Visual Studio 的 "VS20XX x64 Native Tools Command Prompt"最终执行:\rubyc路径\rubyc.exe --help建议:将以上环境可执行文件加入环境变量。7、配置cacert.pem 下载cacert.pem放到任意目录下(如C:\cacert)并新增SSL_CERT_FILE环境变量,值为C:\cacert\cacert.pem。(如果没有证书,会显示gems https访问失败。)(下载地址:http://curl.haxx.se/ca/cacert.pem)8、最终打包cd whatweb目录rubyc.exe whatweb\whatweb

#亲测打包环境安装不是很复杂,但是比较费时#rubyc 将程序打包后可以通过upx等进行再次压缩。#WhatWeb初步打包为17M,upx压缩后为12M。#WhatWeb.exe启动时会有1s-2s延迟。#rubyc 打包的exe可以直接通过zip进行解压。如果找到一个可以原样编辑的EXE压缩包的程序,更新程序就不需要再次打包了。(坐等大家的推荐)

0x02 改造whatweb请求头

在内网用了一下whatweb扫描目标服务器,被防火墙直接拦截,分析流量发现其特征很明显。默认whatweb流量特征:

GET / HTTP/1.1User-Agent: WhatWeb/0.5.5.1      Accept-Encoding: gzip, deflateAccept: */*       Connection: close#User-Agent 必需修改,否则会被防火墙标记#Accept     建议修改,否则返回值可能是Json模式#不同的请求头可能会造成不同的请求结果,建议使用Burp代理进行流量记录。

whatweb修改:添加动态refer和host 和其他默认头经过分析,发现在WhatWeb\lib\target.rb文件中动态修改是最通用的办法,且不会对其他的命令行参数进行影响。主要是修改refer、host、user-agent等请求头。

\WhatWeb\lib\target.rb  行267############################################editor@host = @uri.host  #editor@refer =@uri.to_s  #editor    #puts @refer############################################editor\WhatWeb\lib\target.rb  行296############################################editor#根据输入参数动态设置host$CUSTOM_HEADERS["HOST"]  = "#@host"  #根据输入参数动态设置refer$CUSTOM_HEADERS["Refer"] = "#@refer" #增加随机user-agent列表@user_agent_list = Array["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36 Edg/89.0.774.48","Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0","..............","Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A366 Safari/600.1.4","Mozilla/5.0 (iPod; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3",]#启用随机user-agent列表,未启用,感觉固定的就够#@user_agent = @user_agent_list[rand(@user_agent_list.length)] #Open random user-agent#增加固定user-agent列表@user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36 Edg/89.0.774.48"  #editor#设置默认accept头@accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"#设置默认accept-encodind 头@accept_encodind = "gzip, deflate"#设置默认accept-language 头@accept_language = "zh-CN,zh;q=0.9"#判断发送前报头中是否存在指定请求头,#没有就新增报头,有就替换或者不处理。if $CUSTOM_HEADERS["User-Agent"].downcase.include?"whatweb" then $CUSTOM_HEADERS["User-Agent"] = @user_agent end;if $CUSTOM_HEADERS.has_key?("Accept") == false then $CUSTOM_HEADERS["Accept"] = @accept end;if $CUSTOM_HEADERS.has_key?("Accept-Encoding") == false then $CUSTOM_HEADERS["Accept-Encoding"] = @accept_encoding end;if $CUSTOM_HEADERS.has_key?("Accept-Language") == false then $CUSTOM_HEADERS["Accept-Language"] = @accept_language end;#puts $CUSTOM_HEADERS ############################################editor

修改后的whatweb流量特征:

GET / HTTP/1.1User_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36 Edg/89.0.774.48Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateConnection: closeHost: XXXX

0x03 Whatweb插件编写规则

官方的插件示例在my-plugins/文件夹中,编写前可以进行参考

https://github.com/urbanadventurer/WhatWeb/wiki在wiki有更多的开发思路和资源

基本匹配示例:

# 搜索一个文本字符串。{ :text => "This page was generated by <b>Generic CMS</b>" },# 搜索正则表达式。注意斜杠是转义。{ :regexp => /This page was generated by <a href="http:\/\/www.genericcms.com\/en\/products\/generic-cms\/">Generic CMS<\/a>/ },# #从Mega generator标签中提取通用CMS的版本。{ :name => "Meta generator",  :version => /<meta name="generator" content="Generic CMS version ([a-z0-9])+/ }# HTTP服务器头信息# 检测HTTP服务器报头中的文本“GenericServer”{ :search => "headers[server]",:regexp => /^GenericServer / },# HTTP服务器报头 # 从HTTP服务器报头中提取GenericServer的版本{ :search => "headers[server]",:version => /^GenericServer V([^\s]+)/,},#从Mega generator标签中提取通用CMS的版本。{ :name => "Meta generator",  :version => /<meta name="generator" content="Generic CMS version ([a-z0-9])+/ },#检测通用CMS cookie。注意:search被设置为"headers[set-cookie]"{ :search => "headers[set-cookie]", :regexp => /genericcms=[^;]+;/ },#检测headers的CMScookie的__genericwafuid cookie #猜测作用{ :search => "headers[set-cookie]", :regexp => /__genericwafuid/, :name=>"__genericwafuid cookie" },# 检查图像的MD5sum哈希值来检测准确的版本# 在野蛮模式3中,只有这个插件已经匹配,这些才会被检查# 在侵略模式4,这些将被检查# :model作用不知道干嘛的{ :model => 'gsl2540b', :md5 => "d076eed06cafe1e4a74f83c7fdfe2e67", :url => '/generic/images/gsl2540b.jpg' },{ :model => 'gsl2640b', :md5 => "01aa666a65a72bb4ab0deadbeef525f4", :url => '/generic/images/gsl2640b.jpg' },#搜索引擎搜索关键字dorks ['"Generic CMS login"','Generic login register linkname',]

细节匹配规则:

## 模式匹配### :regexp        #Ruby格式的正则表达式   # :text      #不分大小写的文本# :ghdb     #谷歌Hack数据库格式。这支持使用intitle:、inurl:和minus。# :md5            #HTTP响应正文的MD5和哈希值# :tagpattern    #HTML标记名称列表。##在哪里搜索### :search    #可以是"body"(默认),"all","headers"或"headers[x]"为一个特定的HTTP头#插件名称匹配### :name          #您可以选择命名匹配。此名称将在详细输出中显示。## 返回数据 ### 这些符号可以是一个正则表达式或文本。## :version        #版本# :account      #用户帐号名# :module       #一个模块名称# :make         #制造商,例如NetGear# :model            #模型,例如SpeedErr# :firmware        #固件,例如6.14.14# :filepath       这些可以显示在错误消息中# :string        #这是为了返回上面的符号没有涵盖的数据。例如,电子邮件地址。###模式确定性# ## :certainty         #这次匹配确定性。100是确定的(默认),75是可能的,25是可能的##限制匹配到URL路径或HTTP状态### :url          #您可以将其与其他变量结合使用,也可以单独使用# :status       #响应的HTTP状态#你可以在插件中编写定制的Ruby代码来获得更多的控制#支持有被动功能和主动功能。#被动函数将始终执行

高级匹配示例:

Plugin.define doname "Plugin-Tutorial-6"    #插件名称authors [                            #插件作者"Your preferred name <email@address>", # v0.1 # 2019-01-01 # Created plugin]version "0.1"                   #插件版本description "Describe plugin"   #插件描述website "http://example.com/"   #对应网站#搜索引擎关键字dorks [ '"Generic CMS login"','Generic login register linkname',]#基本匹配列表matches [# 搜索一个文本字符{ :text => "Generic CMS" },] #可以在插件中编写定制的Ruby代码来获得更多的控制匹配选项#插件支持被动功能和主动功能。#被动函数将始终执行# 插件中可用的变量#    @body       #响应体#    @headers    #响应头#    @cookies    #响应Cookie#    @status     #响应状态码#    @base_uri   #请求URI#    @md5sum         #文件MD5值#    @tagpattern     #标签匹配#    @ip             #响应IP##被动匹配passive do# 创建一个匹配数组m = []# 如果HTTP状态是302,重定向位置是/admin/genericcms.php,那么匹配if @status.to_s =~ /^302$/ and @headers["location"] =~ /^\/admin\/genericcms\.php$/m << { :name => "302 redirection to /admin/genericcms.php" }end#你可以添加调试和检查变量的值# pp @status  #输出status# pp @headers #输出headers# #返回匹配数组,即使它是空的mend### 主动性函数只会有时执行# 在主动级别3中,如果找到匹配,则执行主动函数# #在主动级别4,主动函数总是执行#主动匹配aggressive do  @variables[:my_var] += 1# 创建一个匹配数组。这将返回相当于上面的matches[]块的内容m = []# 返回匹配数组,即使它是空的mend## 很少有插件需要启动和关闭功能# 当插件第一次加载时执行def startup@variables = {my_var: 1}end# 当插件在web关闭时执行def shutdown# puts("my_var is #{@variables[:my_var]}")endend

其他参考:

网站指纹识别 whatweb - 知乎https://zhuanlan.zhihu.com/p/28017554#感觉好像也写的很模糊

0x04 实战开发spring-boot Whitelabel页面匹配

简单的规则只需要在matches[]数组中进行简单的添加即可实现。更复杂的匹配需要一些ruby语法基础,花半天看看就能够熟悉该语法。通过匹配返回报文中的Whitelabel Error Page来进行spring-boot框架的匹配。

Plugin.define doname "Spring-Boot"authors ["WINEZER0", ]version "0.1"description "Spring is an open source application framework for the Java platform."website "http://www.springsource.org/"# Matches #匹配规则matches [#在响应包中查看Whitelabel Error Page匹配。{ :text=>"Whitelabel Error Page" },#扩展:通过主动访问错误url判断,需要攻击级别 == 4 #1级. 每个目标发送一个HTTP请求遵循重定向。#3级. 如果一个1级插件匹配,附加URL请求将会被提出。#4级. 对每个目标发送大量HTTP请求。将从所有插件尝试URL。#通过访问指定URL,并通过正则匹配Whitelabel Error Page{ :url => "/xxx/xxx/xxx/xxx", :text=>"Whitelabel Error Page"}, ]end

0x05 总结

目前whatweb最新版本是0.5.5 (20210530)获取修改版whatweb0.5.5.1及打包好的EXENOVASEC百度云盘共享地址
链接:https://pan.baidu.com/s/1YL0QTYaui-U1n2uGH8lGIg 
提取码:bs7c WhatWeb的插件开发中文资料还是不够详细。很多关键字不知道具体含义,不过即使是这样也能够将常见的规则转换为whatweb内置规则了。等有时间会写一个PY脚本,进行批量的指纹的转换。如果需要更高级的定制,菜鸟教程支持ruby语法进行简单学习。PS:rubyc 打包的exe可以直接通过zip进行解压。如果找到一个可以原样编辑的EXE压缩包的程序,更新程序就不需要再次打包了。(坐等大家的推荐)

# web安全 # web指纹识别 # whatweb
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录