From c10894fc7aef7014d74c36d12a4e28e1d3ffd8cc Mon Sep 17 00:00:00 2001 From: cn-kali-team Date: Mon, 10 Feb 2025 14:55:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0mode=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +++++ Cargo.lock | 2 +- README.md | 58 ++++++++++++++++++++-------------------- observer_ward/src/cli.rs | 2 +- observer_ward/src/lib.rs | 40 ++++++++++++++++++++------- 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1239f09..e51c5d97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log + +## [2025.2.10] - 2025.2.10 + +### Fixes + +- 添加mode参数,当目标没有协议的时候根据模式添加协议再尝试 + ## [2024.11.5] - 2024.11.5 ### Fixes diff --git a/Cargo.lock b/Cargo.lock index 5bc8b18e..289cb7a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1329,7 +1329,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom", "libredox", - "thiserror 2.0.9", + "thiserror 2.0.11", ] [[package]] diff --git a/README.md b/README.md index a6e89393..1c0b202b 100644 --- a/README.md +++ b/README.md @@ -175,36 +175,36 @@ Options: --help display usage information ``` -| 参数名 | 作用和描述 | -| ----------------------- | ------------------------------------------------------------------------------------------------ | -| -l,--list | 从文件中读取目标列表,一行一个目标 | -| -t,--target | 单个或者多个目标 | -| -p,--probe | json探针路径(如果和`--probe-dir`一起使用,该参数为转换json后的输出文件路径) | -| --probe-dir | yaml探针目录(如果和`--probe`一起使用,会读取该目录下的全部yaml文件转换为一个json文件) | -| --ua | 设置请求头 | -| --mode | 模式:safe和danger,safe只请求首页,dranger会请求特殊路径,容易被waf拦截 | -| --timeout | 请求和连接超时,单位为秒 | -| --thread | 同时识别的线程数,默认为cpu的核数 | -| --proxy | 设置代理服务器,支持http和socks5,例如:`https://username:password@your-proxy.com:port` | -| --ir | 在json结果中保存请求和响应,保存请求响应可能比较消耗内存 | -| --ic | 在json结果中保存证书数据 | -| --plugin | 指定nuclei插件路径,会开启nuclei验证漏洞,如果路径为`default`默认调用配置文件夹下的`plugins`目录 | -| -o,--output | 将结果保存到文件,如果文件后缀名是下面格式支持的可以省略`--format`参数 | -| --format | 输出格式:支持`json`,`csv`和`txt`,在保存文件的时候会根据文件后缀自动识别 | -| --no-color | 禁用颜色输出 | -| --nuclei-args | nuclei的额外参数,会按照空格分割追加到调用nuclei参数,例如:`-es info`,排除info插件 | -| --silent | 静默模式,不打印任何信息,常用在命令行管道作为输入源 | -| --debug | 开启调试模式,会输出更多信息,包括请求和响应,提取到的图标哈希,nuclei调用命令行等信息 | -| --config-dir | 指定配置文件夹,默认在用户配置文件夹下的`observer_ward`目录 | -| --update-self | 更新程序自身版本,也就是该项目的`defaultv4`发布标签 | -| -u,--update-fingerprint | 更新指纹到配置文件夹,会覆盖`web_fingerprint_v4.json`文件 | +| 参数名 | 作用和描述 | +|-------------------------|--------------------------------------------------------------------------| +| -l,--list | 从文件中读取目标列表,一行一个目标 | +| -t,--target | 单个或者多个目标 | +| -p,--probe | json探针路径(如果和`--probe-dir`一起使用,该参数为转换json后的输出文件路径) | +| --probe-dir | yaml探针目录(如果和`--probe`一起使用,会读取该目录下的全部yaml文件转换为一个json文件) | +| --ua | 设置请求头 | +| --mode | 识别模式:[tcp,http,all],默认http,也就是当目标没有协议的时候会尝试添加web协议再去识别 | +| --timeout | 请求和连接超时,单位为秒 | +| --thread | 同时识别的线程数,默认为cpu的核数 | +| --proxy | 设置代理服务器,支持http和socks5,例如:`https://username:password@your-proxy.com:port` | +| --ir | 在json结果中保存请求和响应,保存请求响应可能比较消耗内存 | +| --ic | 在json结果中保存证书数据 | +| --plugin | 指定nuclei插件路径,会开启nuclei验证漏洞,如果路径为`default`默认调用配置文件夹下的`plugins`目录 | +| -o,--output | 将结果保存到文件,如果文件后缀名是下面格式支持的可以省略`--format`参数 | +| --format | 输出格式:支持`json`,`csv`和`txt`,在保存文件的时候会根据文件后缀自动识别 | +| --no-color | 禁用颜色输出 | +| --nuclei-args | nuclei的额外参数,会按照空格分割追加到调用nuclei参数,例如:`-es info`,排除info插件 | +| --silent | 静默模式,不打印任何信息,常用在命令行管道作为输入源 | +| --debug | 开启调试模式,会输出更多信息,包括请求和响应,提取到的图标哈希,nuclei调用命令行等信息 | +| --config-dir | 指定配置文件夹,默认在用户配置文件夹下的`observer_ward`目录 | +| --update-self | 更新程序自身版本,也就是该项目的`defaultv4`发布标签 | +| -u,--update-fingerprint | 更新指纹到配置文件夹,会覆盖`web_fingerprint_v4.json`文件 | | --update-plugin | 更新社区nuclei插件到配置文件夹,会自动解压zip并且覆盖`plugins`目录 | -| --daemon | api服务后台运行,window不支持 | -| --token | api服务认证token | -| --webhook | 要将识别结果通过webhook发送到指定url | -| --webhook-auth | webhook的`AUTHORIZATION`认证 | -| --api-server | api监听地址的端口 | -| --help | 打印帮助信息 | +| --daemon | api服务后台运行,window不支持 | +| --token | api服务认证token | +| --webhook | 要将识别结果通过webhook发送到指定url | +| --webhook-auth | webhook的`AUTHORIZATION`认证 | +| --api-server | api监听地址的端口 | +| --help | 打印帮助信息 | ### 更新指纹库 diff --git a/observer_ward/src/cli.rs b/observer_ward/src/cli.rs index 5df4b5af..1dbd4ac9 100644 --- a/observer_ward/src/cli.rs +++ b/observer_ward/src/cli.rs @@ -49,8 +49,8 @@ impl FromStr for OutputFormat { #[derive(Debug, Clone, Default, PartialEq)] pub enum Mode { #[default] - ALL, HTTP, + ALL, TCP, } diff --git a/observer_ward/src/lib.rs b/observer_ward/src/lib.rs index 09d3cc17..39435173 100644 --- a/observer_ward/src/lib.rs +++ b/observer_ward/src/lib.rs @@ -1,4 +1,4 @@ -use crate::cli::ObserverWardConfig; +use crate::cli::{Mode, ObserverWardConfig}; use crate::error::new_io_error; use crate::nuclei::{gen_nuclei_tags, NucleiRunner}; use console::{style, Emoji}; @@ -509,15 +509,13 @@ impl ObserverWard { match target.scheme_str() { None => { // 如果没有协议尝试https和http - let schemes = vec!["https", "http"]; - for scheme in schemes { - if let Ok(http_target) = set_uri_scheme(scheme, &target) { - runner.target = http_target; - self.http(&mut runner); - if !runner.matched_result.is_empty() { - break; - } + match self.config.clone().mode.unwrap_or_default() { + Mode::ALL => { + self.handle_tcp_mode(&mut runner, &target); + self.handle_http_mode(&mut runner, &target); } + Mode::TCP => self.handle_tcp_mode(&mut runner, &target), + Mode::HTTP => self.handle_http_mode(&mut runner, &target), } } // 只跑web指纹 @@ -550,4 +548,28 @@ impl ObserverWard { debug!("{}: {}", Emoji("🔚", "end"), target); runner.matched_result } + fn handle_http_mode(&self, runner: &mut ClusterExecuteRunner, target: &Uri) { + let schemes = vec!["https", "http"]; + for scheme in schemes { + if let Ok(http_target) = set_uri_scheme(scheme, target) { + runner.target = http_target; + self.http(runner); + if !runner.matched_result.is_empty() { + break; + } + } + } + } + + fn handle_tcp_mode(&self, runner: &mut ClusterExecuteRunner, target: &Uri) { + if let Ok(tcp_target) = set_uri_scheme("tcp", target) { + runner.target = tcp_target; + if let Some(tcp) = &self.cluster_type.tcp_default { + if let Err(_err) = runner.tcp(&self.config, tcp) { + return; + } + } + self.tcp(runner); + } + } }