开发目的

解决漏洞扫描器的痛点

第一就是扫描量太大,对一个站点扫描了大量的无用 POC,浪费时间

指纹识别后还需要根据对应的指纹去进行 payload 扫描,非常的麻烦

开发思路

我们的思路分为大体分为指纹+POC+扫描

所以思路大概从这几个方面入手

首先就是 POC,我们得寻找一直在更新的 POC,而且是实时更新的,因为自己写的话有点太费时间了

但是这 POC 的决定是根据我们扫描器来的,因为世面上已经有许多不错的扫描器了,目前打算使用的是 nuclei 扫描器

https://github.com/projectdiscovery/nuclei

Nuclei 是一种现代、高性能的漏洞扫描程序,它利用基于 YAML 的简单模板。它使您能够设计自定义漏洞检测场景,以模拟真实世界的条件,从而实现零误报。

目前也在不断维护更新,当然还有 Xray,Goby 等工具也是不错的选择

然后回到指纹识别技术,这个需要大量的指纹样本,但是世面上的各种工具已经可以做得很好了

指纹识别

这里就的学习一下指纹识别的技术

首先我们需要知道收集指纹目前大概有哪些方法

指纹识别方式

特定文件

比如举一个例子,我们通常是如何判断一个框架是 thinkphp 呢?

我们随便找几个 thinkphp 的网站

特征就是它的图标是非常明显的

可以看到图标都是一样的,目前 fofa 和 hunter 已经有这种查找的方法了,一般都是把我们的图标换算为我们的 hash 值

这个就是我们的 favicon.ico 图标

一般网站是通过在路径后加入 favicon.ico 比如
http://xxxxxx/favicon.ico

然后就能获取这个图标了,而在 fofa 中可以直接拖动查询了,可以直接算出 hash 值

比如 thinkphp 的

然后再次查询

全是 tp 的网站
参考https://github.com/TideSec/TideFinger/blob/master/Web%E6%8C%87%E7%BA%B9%E8%AF%86%E5%88%AB%E6%8A%80%E6%9C%AF%E7%A0%94%E7%A9%B6%E4%B8%8E%E4%BC%98%E5%8C%96%E5%AE%9E%E7%8E%B0.md

当然除了我们的 ico 文件,还有其他很多的文件

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

一些网站的特定图片文件、js 文件、CSS 等静态文件,如 favicon.ico、css、logo.ico、js 等文件一般不会修改,通过爬虫对这些文件进行抓取并比对 md5 值,如果和规则库中的 Md5 一致则说明是同一 CMS。这种方式速度比较快,误报率相对低一些,但也不排除有些二次开发的 CMS 会修改这些文件。

页面关键字

比如 tp 的错误页面大多数都是

我们 body 就可以包含这个关键字了

或者可以构造错误页面,根据报错信息来判断使用的 CMS 或者中间件信息,比较常见的如 tomcat 和 spring 的报错页面。
根据 response header 一般有以下几种识别方式:

请求头关键字

根据网站 response 返回头信息进行关键字匹配,这个一般是 ningx 这种

能够识别我们的服务器

URL 路径

根据总结
wordpress 默认存在 wp-includes 和 wp-admin 目录,织梦默认管理后台为 dede 目录,solr 平台可能使用/solr 目录,weblogic 可能使用 wls-wsat 目录等。

大部分还是根据我们的 body

然后点一个进去

可以看到都是我们的 wordPress 的站点

指纹识别方法

有了我们上面的识别技术,那么我们大概是如何来识别一个指纹的呢

首先使用 python 简单举一个实现

首先就是需要一个配置文件,这个配置文件就需要包含我们的大体指纹和验证方法

- name: ThinkPHP
matchers:- type: headerrule: X-Powered-Bykeyword: ThinkPHP- type: bodykeyword: "http://www.thinkphp.cn"- type: bannerkeyword: thinkphp- type: pathpath: /thinkphp/library/think/keyword: class- type: favicon_hashhash: 1165838194

然后就是我们的后端处理逻辑了

import yaml
import requests
import socket
import base64
import mmh3def get_http_response(url, path=""):try:full_url = url.rstrip("/") + pathreturn requests.get(full_url, timeout=5)except:return Nonedef get_tcp_banner(ip, port=80):try:with socket.create_connection((ip, port), timeout=5) as s:banner = s.recv(1024).decode(errors="ignore")return bannerexcept:return ""def get_favicon_hash(url):try:res = requests.get(url.rstrip("/") + "/favicon.ico", timeout=5)favicon = base64.encodebytes(res.content)return mmh3.hash(favicon.decode('utf-8'))except:return Nonedef load_fingerprints(path="fingerprints.yaml"):with open(path, "r", encoding="utf-8") as f:return yaml.safe_load(f)def match_fingerprint(url, ip=None):fingerprints = load_fingerprints()results = []res = get_http_response(url)banner = get_tcp_banner(ip or url.replace("http://", "").replace("https://", ""), 80)favicon_hash = get_favicon_hash(url)for fp in fingerprints:matched = Falsefor matcher in fp["matchers"]:if matcher["type"] == "header" and res:if matcher["rule"] in res.headers and matcher["keyword"].lower() in res.headers[matcher["rule"]].lower():matched = Trueelif matcher["type"] == "body" and res:if matcher["keyword"].lower() in res.text.lower():matched = Trueelif matcher["type"] == "banner":if matcher["keyword"].lower() in banner.lower():matched = Trueelif matcher["type"] == "path":res2 = get_http_response(url, matcher["path"])if res2 and matcher["keyword"].lower() in res2.text.lower():matched = Trueelif matcher["type"] == "favicon_hash":if favicon_hash == matcher["hash"]:matched = Trueif matched:results.append(fp["name"])return results# 示例使用
if __name__ == "__main__":target_url = "http://101.200.50.94:8009/"result = match_fingerprint(target_url)print("识别结果:", result)

大体逻辑就是这样了

首先就是 yaml 文件为我们的判断依据,对应不同的判断方法我们都有对应的后端处理

一个是对 body 的处理,一个是对 hash 文件的处理

然后再根据规则去匹配

匹配成功输出结果

当然这只是一个简单的逻辑,如果需要实现更高高效快捷第一就是指纹库,第二就是代码运行的速率,提高线程

最终识别代码

首先就是指纹库的获取,这个的话我们就不直接获取了,使用的是 EHole 的指纹库

我们大概看看部分代码

{
"fingerprint": [{"cms": "seeyon","method": "keyword","location": "body","keyword": ["/seeyon/USER-DATA/IMAGES/LOGIN/login.gif"]
}, {"cms": "seeyon","method": "keyword","location": "body","keyword": ["/seeyon/common/"]
}, {"cms": "Spring env","method": "keyword","location": "body","keyword": ["servletContextInitParams"]
}, {"cms": "微三云管理系统","method": "keyword","location": "body","keyword": ["WSY_logo","管理系统 MANAGEMENT SYSTEM"]
}, {"cms": "Spring env","method": "keyword","location": "body","keyword": ["logback"]
}, {"cms": "Weblogic","method": "keyword","location": "body","keyword": ["Error 404--Not Found"]
}, {"cms": "Weblogic","method": "keyword","location": "body","keyword": ["Error 403--"]
}{"cms": "Atlassian – JIRA","method": "faviconhash","location": "body","keyword": ["981867722"]
}, {"cms": "OpenStack","method": "faviconhash","location": "body","keyword": ["-923088984"]
}, {"cms": "Aplikasi","method": "faviconhash","location": "body","keyword": ["494866796"]
}, {"cms": "Ubiquiti Aircube","method": "faviconhash","location": "body","keyword": ["1249285083"]
}

简单看了一下逻辑可以发现和我们的指定方法应该差不多,逻辑就是首先根据 method 去选择方法,一个是 keyword 方法,一个是 faviconhash 方法,是一个大的判断,然乎下面就是根据具体的比如 body,title 等去识别了

代码如下

import json
import requests
import hashlib
import base64
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor, as_completed
import argparse# 加载指纹
def load_fingerprints(file='finger.json'):with open(file, 'r', encoding='utf-8') as f:data = json.load(f)if "fingerprint" in data:return data["fingerprint"]raise ValueError("指纹文件格式不正确,应包含 'fingerprint' 字段。")# 获取 HTTP 响应
def get_http_response(url):try:headers = {"User-Agent": "Mozilla/5.0"}return requests.get(url, headers=headers, timeout=8, verify=False)except:return None# 计算 favicon hash
def get_favicon_hash(url):try:favicon_url = urljoin(url, '/favicon.ico')res = requests.get(favicon_url, timeout=5, verify=False)if res.status_code == 200:m = hashlib.md5()b64 = base64.b64encode(res.content)m.update(b64)return int(m.hexdigest(), 16)except:return None# 匹配单条指纹
def match_one(fpr, res, fav_hash):method = fpr["method"]loc = fpr.get("location", "body").lower()kws = fpr["keyword"]if method == 'keyword':text_body = res.text or ""text_head = "\n".join(f"{k}: {v}" for k, v in res.headers.items())# 处理 title 和 header 等if loc == 'header':spaces = [text_head, text_body]elif loc == 'title':soup = BeautifulSoup(text_body, "html.parser")title = soup.title.string if soup.title and soup.title.string else ""spaces = [title, text_body]elif loc == 'body':spaces = [text_body]else:spaces = [text_body]for space in spaces:for kw in kws:if kw.lower() in space.lower():return Trueif method == 'faviconhash' and fav_hash is not None:for kw in kws:try:if fav_hash == int(kw):return Trueexcept:continuereturn False# 识别单个 URL 指纹
def match_fingerprint(url, fps=None):fps = fps or load_fingerprints()res = get_http_response(url)fav_hash = get_favicon_hash(url)matched = []for fpr in fps:if 'cms' not in fpr or 'method' not in fpr or 'keyword' not in fpr:continueif match_one(fpr, res, fav_hash):matched.append(fpr['cms'])print(f"[✓] {url} 指纹识别结果:{list(set(matched))}")return {url: list(set(matched))}# 多线程执行
def run_multithread(urls, threads):fps = load_fingerprints()results = []with ThreadPoolExecutor(max_workers=threads) as executor:future_to_url = {executor.submit(match_fingerprint, url, fps): url for url in urls}for future in as_completed(future_to_url):results.append(future.result())return results# 主程序入口
def main():parser = argparse.ArgumentParser(description="指纹识别脚本 - 支持多线程")group = parser.add_mutually_exclusive_group(required=True)group.add_argument("-u", "--url", help="单个目标 URL")group.add_argument("-f", "--file", help="包含多个 URL 的文件")parser.add_argument("-t", "--threads", type=int, default=10, help="线程数(默认10)")args = parser.parse_args()if args.url:match_fingerprint(args.url)elif args.file:with open(args.file, 'r', encoding='utf-8') as f:urls = [line.strip() for line in f if line.strip()]results = run_multithread(urls, args.threads)if __name__ == '__main__':main()

加入了支持多线程和支持多目标的思路

结合漏洞扫描

我们光目标识别后,还需要实现精准化打击,正好 Nuclei 引擎支持根据 tag 去寻找我们的目标,完美了

实现思路就是首先寻找我们的 tag,然后在漏洞库里面查询,把有 tag 的和没有 tag 的分别分开放好,然后根据有 tag 的去精准化识别运行,完成最后的精准化 POC 攻击

初步的代码如下

import json
import os
import threading
import time
import base64
import hashlib
import requests
import argparse
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor, as_completed
from queue import Queuerequests.packages.urllib3.disable_warnings()# ---------- 指纹识别部分 ----------def load_fingerprints(file='finger.json'):with open(file, 'r', encoding='utf-8') as f:data = json.load(f)return data["fingerprint"]def get_http_response(url):try:headers = {"User-Agent": "Mozilla/5.0"}return requests.get(url, headers=headers, timeout=8, verify=False)except:return Nonedef get_favicon_hash(url):try:favicon_url = urljoin(url, '/favicon.ico')res = requests.get(favicon_url, timeout=5, verify=False)if res.status_code == 200:m = hashlib.md5()b64 = base64.b64encode(res.content)m.update(b64)return int(m.hexdigest(), 16)except:return Nonedef match_one(fpr, res, fav_hash):method = fpr["method"]loc = fpr.get("location", "body").lower()kws = fpr["keyword"]if method == 'keyword':text_body = res.text or ""text_head = "\n".join(f"{k}: {v}" for k, v in res.headers.items())if loc == 'header':spaces = [text_head]elif loc == 'title':soup = BeautifulSoup(text_body, "html.parser")title = soup.title.string if soup.title and soup.title.string else ""spaces = [title]else:spaces = [text_body]for space in spaces:for kw in kws:if kw.lower() in space.lower():return Trueelif method == 'faviconhash' and fav_hash is not None:for kw in kws:try:if fav_hash == int(kw):return Trueexcept:continuereturn Falsedef match_fingerprint(url, fps):res = get_http_response(url)fav_hash = get_favicon_hash(url)matched = []for fpr in fps:if 'cms' not in fpr or 'method' not in fpr or 'keyword' not in fpr:continueif match_one(fpr, res, fav_hash):matched.append(fpr['cms'])print(f"[✓] {url} 指纹识别结果:{list(set(matched))}")return {"url": url, "cms": list(set(matched))[0] if matched else ""}def run_fingerprint_scan(urls, threads, output='res.json'):fps = load_fingerprints()results = []with ThreadPoolExecutor(max_workers=threads) as executor:future_to_url = {executor.submit(match_fingerprint, url, fps): url for url in urls}for future in as_completed(future_to_url):results.append(future.result())with open(output, 'w', encoding='utf-8') as f:json.dump(results, f, ensure_ascii=False, indent=2)# ---------- Nuclei 扫描部分 ----------class AutoNuclei:def __init__(self, res_file='res.json', tag_file='C:\\Users\\86135\\nuclei-templates\\TEMPLATES-STATS.json', thread_count=5):self.res_file = res_fileself.tag_file = tag_fileself.havetag_file = 'havetag.txt'self.notag_file = 'notag.txt'self.result_dir = 'result'self.thread_count = thread_countself.cms_targets = {}         # {cms: [url1, url2]}self.nuclei_tags = set()self.tagged_targets = {}      # {tag: [url1, url2]}self.untagged_targets = []self.task_queue = Queue()self.load_res_json()self.load_tags()self.classify_targets()self.save_targets()self.start_scan_threads()def load_res_json(self):with open(self.res_file, 'r', encoding='utf-8') as f:data = json.load(f)for entry in data:cms = entry.get("cms", "").lower()url = entry.get("url")if cms and url:self.cms_targets.setdefault(cms, []).append(url)def load_tags(self):with open(self.tag_file, 'r', encoding='utf-8') as f:tags_data = json.load(f)for item in tags_data.get("tags", []):if item["name"]:self.nuclei_tags.add(item["name"].lower())def classify_targets(self):for cms, urls in self.cms_targets.items():if cms in self.nuclei_tags:self.tagged_targets.setdefault(cms, []).extend(urls)else:self.untagged_targets.extend(urls)def save_targets(self):with open(self.havetag_file, 'w', encoding='utf-8') as f:for tag, urls in self.tagged_targets.items():for url in urls:f.write(f"{tag}||{url}\n")with open(self.notag_file, 'w', encoding='utf-8') as f:for url in self.untagged_targets:f.write(url + '\n')if not os.path.exists(self.result_dir):os.makedirs(self.result_dir)def scan_worker(self):while not self.task_queue.empty():try:tag, url = self.task_queue.get(timeout=1)target_file = f"temp_{int(time.time() * 1000)}.txt"with open(target_file, 'w', encoding='utf-8') as f:f.write(url)output_file = os.path.join(self.result_dir, f"{tag}_{int(time.time())}.txt")cmd = f"F:\\gj\\Vulnerability_Scanning\\nuclei\\nuclei.exe -l {target_file} -tags {tag} -o {output_file} -stats"print(f"[+] 扫描任务启动: {url} -> {tag}")os.system(cmd)os.remove(target_file)except Exception as e:print(f"[!] 线程错误: {e}")def start_scan_threads(self):for tag, urls in self.tagged_targets.items():for url in urls:self.task_queue.put((tag, url))threads = []for _ in range(self.thread_count):t = threading.Thread(target=self.scan_worker)t.start()threads.append(t)for t in threads:t.join()print("[✓] 所有扫描任务完成!")# ---------- 主程序入口 ----------def main():parser = argparse.ArgumentParser(description="指纹识别 + Nuclei自动化工具")group = parser.add_mutually_exclusive_group(required=True)group.add_argument("-u", "--url", help="目标 URL")group.add_argument("-f", "--file", help="URL列表文件")parser.add_argument("--fp-threads", type=int, default=10, help="指纹识别线程数")parser.add_argument("--scan-threads", type=int, default=5, help="Nuclei 扫描线程数")args = parser.parse_args()urls = []if args.url:urls = [args.url]elif args.file:with open(args.file, 'r', encoding='utf-8') as f:urls = [line.strip() for line in f if line.strip()]print("[*] 正在执行指纹识别...")run_fingerprint_scan(urls, threads=args.fp_threads, output='res.json')print("[*] 指纹识别完成,开始 Nuclei 扫描...")AutoNuclei(res_file='res.json',tag_file=os.path.join(os.environ['USERPROFILE'], 'nuclei-templates', 'TEMPLATES-STATS.json'),thread_count=args.scan_threads)if __name__ == '__main__':main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/82989.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/82989.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/82989.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Day40】

DAY 40 训练和测试的规范写法 知识点回顾: 彩色和灰度图片测试和训练的规范写法:封装在函数中展平操作:除第一个维度batchsize外全部展平dropout操作:训练阶段随机丢弃神经元,测试阶段eval模式关闭dropout 作业&#x…

【HTML-13】HTML表格合并技术详解:打造专业数据展示

表格是HTML中展示结构化数据的重要元素,而表格合并则是提升表格表现力的关键技术。本文将全面介绍HTML中的表格合并方法,帮助您创建更专业、更灵活的数据展示界面。 1. 表格合并基础概念 在HTML中,表格合并主要通过两个属性实现&#xff1a…

<uniapp><threejs>在uniapp中,怎么使用threejs来显示3D图形?

前言 本专栏是基于uniapp实现手机端各种小功能的程序,并且基于各种通讯协议如http、websocekt等,实现手机端作为客户端(或者是手持机、PDA等),与服务端进行数据通讯的实例开发。 发文平台 CSDN 环境配置 系统:windows 平台:visual studio code、HBuilderX(uniapp开…

如何制作全景VR图?

全景VR图,特别是720度全景VR,为观众提供一种沉浸式体验。 全景VR图能够捕捉场景的全貌,还能将多个角度的图片或视频无缝拼接成一个完整的全景视角,让观众在虚拟环境中自由探索。随着虚拟现实(VR)技术的飞速…

前端使用qrcode来生成二维码的时候中间添加logo图标

这个开源仓库可以让你在前端页面中生成二维码图片,并且支持调整前景色和背景色,但是有个问题,就是不能添加logo图片。issue: GitHub Where software is built 但是已经有解决方案了: add a logo picture Issue #21…

【C语言】函数指针及其应用

目录 1.1 函数指针的概念和应用 1.2 赋值与内存模型 1.3 调用方式与注意事项 二、函数指针的使用 2.1 函数指针的定义和访问 2.2 动态调度:用户输入驱动函数执行 2.3 函数指针数组进阶应用 2.4 函数作为参数的高阶抽象 三、回调函数 3.1 指针函数…

安装flash-attention失败的终极解决方案(WINDOWS环境)

想要看linux版本下安装问题的请走这里:安装flash-attention失败的终极解决方案(LINUX环境) 其实,现在的flash-attention不像 v2.3.2之前的版本,基本上不兼容WINDOWS环境。但是在WINDOWS环境安装总还是有那么一点不顺畅…

[C]基础16.数据在内存中的存储

博客主页:向不悔本篇专栏:[C]您的支持,是我的创作动力。 文章目录 0、总结1、整数在内存中的存储1.1 整数的二进制表示方法1.2 不同整数的表示方法1.3 内存中存储的是补码 2、大小端字节序和字节序判断2.1 什么是大小端2.2 为什么有大小端2.3…

Python 基于卷积神经网络手写数字识别

Ubuntu系统:22.04 python版本:3.9 安装依赖库: pip install tensorflow2.13 matplotlib numpy -i https://mirrors.aliyun.com/pypi/simple 代码实现: import tensorflow as tf from tensorflow.keras.models import Sequent…

ElectronBot复刻-电路测试篇

typec-16p 接口部分 USB1(Type - C 接口):这是通用的 USB Type - C 接口,具备供电和数据传输功能。 GND 引脚(如 A1、A12、B1、B12 等):接地引脚,用于提供电路的参考电位&#xff0…

ESP8266+STM32 AT驱动程序,心知天气API 记录时间: 2025年5月26日13:24:11

接线为 串口2 接入ESP8266 esp8266.c #include "stm32f10x.h"//8266预处理文件 #include "esp8266.h"//硬件驱动 #include "delay.h" #include "usart.h"//用得到的库 #include <string.h> #include <stdio.h> #include …

CDN安全加速:HTTPS加密最佳配置方案

CDN安全加速的HTTPS加密最佳配置方案需从证书管理、协议优化、安全策略到性能调优进行全链路设计&#xff0c;以下是核心实施步骤与注意事项&#xff1a; ​​一、证书配置与管理​​ ​​证书选择与格式​​ ​​证书类型​​&#xff1a;优先使用受信任CA机构颁发的DV/OV/EV证…

【前端】Twemoji(Twitter Emoji)

目录 注意使用Vue / React 项目 验证 Twemoji 的作用&#xff1a; Twemoji 会把你网页/应用中的 Emoji 字符&#xff08;如 &#x1f604;&#xff09;自动替换为 Twitter 风格的图片&#xff08;SVG/PNG&#xff09;&#xff1b; 它不依赖系统字体&#xff0c;因此在 Android、…

GCN图神经网络的光伏功率预测

一、GCN图神经网络的核心优势 图结构建模能力 GCN通过邻接矩阵&#xff08;表示节点间关系&#xff09;和节点特征矩阵&#xff08;如气象数据、历史功率&#xff09;进行特征传播&#xff0c;能够有效捕捉光伏电站间的空间相关性。其核心公式为&#xff1a; H ( l 1 ) σ (…

按照状态实现自定义排序的方法

方法一&#xff1a;使用 MyBatis-Plus 的 QueryWrapper 自定义排序 在查询时动态构建排序规则&#xff0c;通过 CASE WHEN 语句实现优先级排序&#xff1a; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Ser…

【计算机网络】IPv6和NAT网络地址转换

IPv6 IPv6协议使用由单/双冒号分隔一组数字和字母&#xff0c;例如2001:0db8:85a3:0000:0000:8a2e:0370:7334&#xff0c;分成8段。IPv6 使用 128 位互联网地址&#xff0c;有 2 128 2^{128} 2128个IP地址无状态地址自动配置&#xff0c;主机可以通过接口标识和网络前缀生成全…

【Redis】string

String 字符串 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 首先 Redis 中所有的键的类型都是字符串类型&#xff0c;而且其他几种数据结构也都是在字符串的基础上构建的。字符串类型的值实际可以是字符串&#xff0c;包含一般格式的…

基于ELK的分布式日志实时分析与可视化系统设计

目录 一、ELK平台介绍 1.ELK概述 2.Elasticsearch 3.Logstash 4.Kibana 二、部署ES群集 1.资源清单 2.基本配置 3.安装Elasticsearch&#xff08;elk1上、elk2上、elk3上&#xff09; 4.安装logstash&#xff08;elk1上&#xff09; 5.Filebeat 6.安装Kibana&#x…

电机控制选 STM32 还是 DSP?技术选型背后的现实博弈

现在搞电机控制&#xff0c;圈里人都门儿清 —— 主流方案早就被 STM32 这些 Cortex-M 单片机给拿捏了。可要是撞上系统里的老甲方&#xff0c;技术认知还停留在诺基亚砸核桃的年代&#xff0c;非揪着 DSP 不放&#xff0c;咱也只能赔笑脸&#xff1a;“您老说的对&#xff0c;…

【案例分享】蓝牙红外线影音遥控键盘:瑞昱RTL8752CJF

蓝牙红外线影音遥控键盘 Remotec的无线控制键盘采用瑞昱蓝牙RTL8752CJF解决方案&#xff0c;透过蓝牙5.0与手机配对后&#xff0c;连线至 Remotec 红外 code server 取得对应影音视觉设备的红外 code后&#xff0c;即可控制多达2个以上的影音视觉设备&#xff0c;像是智能电视…