freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

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

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
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录