Go语言实现指纹识别

S1gn·2024-04-14 18:45·204 次阅读

Go语言实现指纹识别

指纹识别

指纹识别是一种用于识别网络设备、操作系统、应用程序或用户的技术。它通过收集和分析目标系统的特征信息,如网络协议、端口号、操作系统版本、应用程序版本等,来确定系统的身份或特征。指纹识别可以用于多种用途,包括网络侦察、入侵检测、安全审计等。

常用的指纹识别方法:

  1. 特定文件的MD5值:一些CMS的特定的静态资源:图片favicon.ico logo.ico之类的、js文件、css文件一般是不会修改的。通过爬虫对这些文件进行抓取并比对 md5 值,如果和规则库中的 Md5 一致则说明是同一 CMS。这种方式速度比较快,误报率相对低一些,但也不排除有些二次开发的 CMS 会修改这些文件。
  2. 正常页面或错误页面中包含的关键字:先访问首页或特定页面如 robots.txt 等,通过正则的方式去匹配某些关键字,如 Powered by Discuz、dedecms 等。或者可以构造错误页面,根据报错信息来判断使用的 CMS 或者中间件信息,比较常见的如 tomcat 的报错页面。
  3. 请求头关键字信息的匹配:根据网站 response 返回头信息进行关键字匹配,whatweb 和 Wappalyzer 就是通过 banner 信息来快速识别指纹,之前 fofa 的 web 指纹库很多都是使用的这种方法,效率非常高,基本请求一次就可以,但搜集这些规则可能会耗时很长。而且这些 banner 信息有些很容易被改掉。

根据 response header 一般有以下几种识别方式:

  • 查看 http 响应报头的 X-Powered-By 字段来识别;
  • 根据 Cookies 来进行判断,比如一些 waf 会在返回头中包含一些信息,如 360wzws、Safedog、yunsuo 等;
  • 根据 header 中的 Server 信息来判断,如 DVRDVS-Webs、yunjiasu-nginx、Mod_Security、nginx-wallarm 等;
  • 根据 WWW-Authenticate 进行判断,一些路由交换设备可能存在这个字段,如 NETCORE、huawei、h3c 等设备。
  1. 部分URL中包含的关键字:比如 wp-includes、dede 等 URL 关键特征。通过规则库去探测是否有相应目录,或者根据爬虫结果对链接 url 进行分析,或者对 robots.txt 文件中目录进行检测等等方式,通过 url 地址来判别是否使用了某 CMS,比如 wordpress 默认存在 wp-includes 和 wp-admin 目录,织梦默认管理后台为 dede 目录,solr 平台可能使用 /solr 目录,weblogic 可能使用 wls-wsat 目录等。
  2. 开发语言的识别:php?jsp?aspx?asp?
    主要方式:
  • 通过爬虫获取动态链接直接判断
  • 通过 X-Powered-By :常见的有 X-Powered-By: ASP.NET 或者 X-Powered-By: PHP/7.1.8
  • 通过 Set-Cookie 进行识别:Set-Cookie 中包含 PHPSSIONID 说明是 php、包含 JSESSIONID 说明是 java、包含 ASP.NET_SessionId 说明是 aspx 等

Goland,启动!

参考:https://github.com/newbe3three/gotoscan

选定指纹识别方式#

对比文件md5值和页面中关键字

解析json文件 parsecms.go#

首先分析json文件

Copy
"gowinsoft_jw": [{ "path": "/web/web/web/images/4bt1.jpg", "option": "md5", "content": "ef1ee9c8708cde1bd25a90054de85690" }, { ... }], "maticsoftsns": [{ "path": "/msgbox/images/gb_tip_layer.png", "option": "md5", "content": "c8cb16e8b61bc549ebd339858e66fa5c" }, { ... }], .....

可以看见cms对应特征有三个内容:path、option、content,我们需要将其解析成Go结构体。通常将json数据解析成map[][],然后借助encoding/json 包的方法实现对json文件的解析。因此定义:

Copy
//对应CMS特征的内容 type CmsFeature struct { Path string `json:"path"` Option string `json:"option"` Content string `json:"content"` } //通过map来对应json形式的数据,k就是cms名,v就是对应的特征切片。 map[string][]CmsFeature

发起请求 request.go#

先对服务器发起head请求,状态码为200再发起get请求。先发起head请求主要是由于其响应头和get是完全一样的,但是服务器不会返回请求的实体数据,避免了传输请求、响应体的数据浪费。head请求时非常快的。

首先会定义一个代理池,然后随机选择一个代理头。文件中除此之外就是两个处理url的函数

Copy
func HeadReq(url string) (resp *http.Response, err error) { // 创建了自定义的http.Transport 结构体 tranCfg := &http.Transport{ // 设置了 TLSClientConfig 字段,将 InsecureSkipVerify 设置为 true // 这表示跳过对服务器证书的验证,用于处理不安全的 HTTPS 连接 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } // 创建http.Client结构体,设置超时时间为10s client := &http.Client{ Timeout: 10 * time.Second, Transport: tranCfg, } req, err := http.NewRequest("HEAD", url, nil) if err != nil { return nil, err } req.Header.Add("User_Agent", get_random_ua()) //resp, err2 := // 返回响应和可能的错误 return client.Do(req) } func GetReq(url string) (content []byte, err error) { tranCfg := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{ Timeout: 10 * time.Second, Transport: tranCfg, } req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // 读取http响应体标准用法 bytes, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } return bytes, nil }

作者这儿的处理还是蛮简单的

实现测试 scancms.go#

扫描部分重要的是并发————同时扫描多台主机;同时扫描多个cms
Go语言的并发是易得的,只需要再你想要的并发的函数前面加上关键字go就实现了简单的并发操作。

Copy
//对多个host的并发操作 func HostWorker(hosts []string, cmslist map[string][]CmsFeature, sortList CmsSortList) []string { // 创建通道 hostsChan := make(chan string) resultChan := make(chan string) var resultList []string // 根据获取到的目标数量开启并发 for i := 0; i < len(hosts); i++ { go cmsWorker(hostsChan, cmslist, sortList, resultChan) } for _, host := range hosts { hostsChan <- host } // 使用通道获取线程 for i := 0; i < len(hosts); i++ { // 程序会在这里阻塞直到有数据传入通道 result := <-resultChan resultList = append(resultList, result) } close(hostsChan) close(resultChan) return resultList }
Copy
//对多个cms的并发操作 func cmsWorker(hosts chan string, cmslist map[string][]CmsFeature, sortList CmsSortList, resultChan chan string) { for host := range hosts { var scanStatus bool = false cmsListChan := make(chan map[string][]CmsFeature, 10) var wg sync.WaitGroup// 用来控制线程 for i := 0; i < cap(cmsListChan); i++ { go featureWorker(host, cmsListChan, &wg, &scanStatus, resultChan) } // 如果匹配到了直接return,没匹配到计数器+1 for _, data := range sortList { if !scanStatus { wg.Add(1) cmsListChan <- map[string][]CmsFeature{data.Name: cmslist[data.Name]} } else { //wg1.Done() return } } wg.Wait() // 扫描完所有特征都没匹配到,向结果通道添加一条数据,也就是所谓发起和接收要一样。 // 每个host都应该有一个扫描结果 resultChan <- fmt.Sprintf("The host: %s has no matching results", host) close(cmsListChan) } }

TODO

开发一个自己的指纹识别插件

参考文章

https://www.cnblogs.com/newbe3three/p/15767076.html

posted @   smile_2233  阅读(204)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示
目录