# #01：-t / -T 目标输入的设计与坑位

> “你以为你在喂目标，其实你在给扫描系统定‘战场形态’。”

这一期我们先用 `afrog -t http://example.com` 跑通最基本的一次扫描。  
但从开发者视角看，`-t/-T` 不是“输入框”这么简单——它决定了：

- 后续要不要补协议、怎么补
- 目标会被拆成 URL / Host / host:port / 网段段范围 哪一类
- `-ps`（端口预扫）要扫哪些 host
- 网络类 PoC / Web 类 PoC 该喂哪些资产集合
- 以及：你会不会因为目标文件写得不规范，白白浪费一晚上

---

## 这期讲哪些参数

- `-t, --target`：命令行直接传目标（支持逗号分隔多目标）
- `-T, --target-file`：从文件读目标（一行一个）

---

## 一句话建议（先拿结论）

- 目标少、临时验证：用 `-t`
- 目标多、跑批、可复现：用 `-T`
- 目标既有 URL 又有 IP/CIDR：都能喂，但你要清楚它们会走不同的“后续链路”

---

## 为什么要有 -t 和 -T（而不是只留一个）

从设计者角度，这俩参数解决的是两个不同问题：

- `-t` 解决“交互速度”：复制粘贴即开跑（还支持逗号分隔，适合临时打点）
- `-T` 解决“工程化”：可沉淀、可复盘、可分批、可交接（你把 targets.txt 扔给队友，他能原样复现你的战果）

更重要的是：`-T` 是跑批的最小可追溯单位。你后面做 `--resume`、做告警、做输出归档，都离不开“目标文件”这个锚点。

---

## 核心实现原理：目标是怎么进引擎的

### 1) 目标汇总：三路输入统一进 options.Targets

Afrog 会把 `-t`、`-T` 等入口拿到的目标，统一 append 到 `options.Targets` 里，并用 `seen` 做一次去重。

关键行为：

- `-t`：每个 target `TrimSpace` 后加入
- `-T`：逐行读取，每行 `TrimSpace`，空行丢弃
- 三路输入统一去重：避免同一个目标重复扫两次

### 2) 目标文件读取：朴素到你必须知道它的边界

`targets.txt` 的读取是纯逐行读取：

它的“朴素后果”：

- 不会自动跳过 `# 注释行`
- 不会自动忽略 BOM
- 只负责“读”，真正的“过滤空行/去空格”发生在 runner 汇总阶段

使用建议：targets.txt 里别写注释行；如果要分组，用多个文件更稳。

---

## 目标“分类”的设计：URL / Host / host:port / 网段段范围

很多人以为 Afrog 看到什么就扫什么。实际上它会先做“目标索引”（TargetIndex），把输入拆成四类：

- URLs：`https://a.com/x`
- Hosts：`a.com`、`1.2.3.4`
- HostPorts：`1.2.3.4:8080`
- Expandable：`192.168.1.0/24`、`192.168.1.1-192.168.1.254`

### 1) 先识别“可展开目标”（CIDR/段范围）

CIDR 和 IP 段范围会被优先识别为 Expandable。

这也是为什么你输入 `192.168.1.0/24` 时，后面 `-ps` 能自然接上：它天生就是“资产扩展型输入”。

### 2) URL 的识别：只在它“看起来像 URL”时才会被当成 URL

URL 识别逻辑里有个关键设计：没写 scheme 且没有 `/ ? #` 时，不把它当 URL。

也就是说：

- `example.com` → 更像 Host（让后续去补协议/做探活）
- `example.com/path` → 更像 URL（会被推断成 `http://example.com/path`）

设计者直觉是：裸域名/裸 IP 通常想扫 Web 面或资产面；带路径通常就是要打这个路由。

### 3) Host:Port 的识别：严格限制端口合法性

`host:port` 会被解析并校验端口范围，最终规范化。

好处：把明显错误的输入尽早挡住，避免把无意义目标拖进后续流程。

### 4) 进阶机制：混合输入的“分流”策略（Web 归 Web，Net 归 Net）

这是 Afrog 引擎最“聪明”的地方。当你的目标文件里既有 `http://` 这种 URL，又有 `192.168.x.x` 这种纯 IP 时，Afrog 在执行时会自动**“分流”**：

- **遇到 Web 类 PoC**（如 SQL 注入、XSS）：
  - 引擎只从**“存活的 Web 资产”**里取目标。
  - 如果你给的是纯 IP，Afrog 会先尝试探测它是否有 Web 服务；如果没有，直接跳过。不会对着 SSH 端口硬发 HTTP 包。

- **遇到 Net 类 PoC**（如 SSH 爆破、Redis 未授权）：
  - 引擎会从**“Host/IP 列表”**里取目标。
  - 只要是 IP 或域名，就会去尝试 TCP/UDP 连接。

**一句话总结：** 你尽管把资产一股脑喂给 `-T`，Afrog 会自己判断“哪个锄头挖哪块地”。

> **⚠️ 特别注意：“既不是 Web 也不是 Host:Port”的黑洞**
> 
> 如果你只输入了 `1.2.3.4`（纯 IP）且**没有开启 `-ps`**：
> - **Web PoC**：会尝试探测 80/443。如果探测失败（比如只开了 6379），目标会被丢弃。
> - **Net PoC**：**直接跳过**。因为引擎不知道该打哪个端口，也不会盲猜默认端口。
> 
> **后果**：你的 Redis/MongoDB 漏洞会被直接漏掉。
> **解法**：遇到纯 IP 资产，请务必加上 `-ps`（`afrog -t 1.2.3.4 -ps`），让端口扫描先把 `6379` 找出来，变成 `Host:Port` 形态，Net PoC 才会跟进。

---

## 常见疑问：关于“死目标”与“硬扫描”

很多用户会问：**“如果我输入的 URL 本身访问不通，或者端口是关的，Afrog 会怎么处理？”**

答案取决于你的输入方式：**Afrog 尊重“明确的指令”，但会过滤“模糊的猜测”。**

### 1) 场景一：明确的 URL (`http://site.com`) 但无法访问
**处理方式：照扫不误。**
只要你带了协议头（`http://` 或 `https://`），Afrog 就认为你已经确认了它的属性。即使 Afrog 内部的 WebProbe 探活失败（比如超时、DNS 解析失败），这个目标**依然会被保留**在扫描列表中，强制执行 Web 类 PoC。
- **结果**：PoC 执行时会报错（Timeout / Connection Refused / No Such Host），但它确实“努力过”。

### 2) 场景二：明确的 Host:Port (`1.2.3.4:22`) 但端口关闭
**处理方式：照扫不误。**
只要你指定了端口，Afrog 就认为这是个有效目标。它会把 `1.2.3.4:22` 扔给 Net 类 PoC（如 SSH 爆破）。
- **结果**：PoC 建立 TCP 连接时失败，任务结束。

### 3) 场景三：模糊的 Host/IP (`example.com` 或 `1.2.3.4`)
**处理方式：不仅要活，还要活得有证据。**
对于这种没有“身份特征”的目标，Afrog 会先进行探测（WebProbe）。
- **如果探测成功**（发现 Web 服务）：自动升级为 `http://...`，进入 Web 扫描队列。
- **如果探测失败**：
  - **Web 扫描**：丢弃（不会去硬扫）。
  - **Net 扫描**：丢弃（因为没有端口信息）。
  - **最终结果**：**被完全忽略（Silent Drop）**。

**总结**：如果你想强行扫描一个看起来是死的资产，请务必用**完整的 URL**或**Host:Port**格式输入，不要只给一个裸域名或 IP。

### 4) 补救措施：`-mt` 参数有用吗？
很多同学会问：**“加了 `-mt` (Monitor Targets) 能不能把死目标救活？”**

**结论：能救“假死”，救不了“真死”。**

- **`-mt` 的作用**：它会在扫描前（或扫描中）对目标进行**持续的、带重试的**探活检测。
- **适用场景**：
  - 网络不稳定（丢包率高）。
  - 目标服务器响应慢。
  - 目标有偶尔的连接拒绝。
- **它能做什么**：如果是网络抖动导致第一次探活失败，`-mt` 会多试几次（默认 3 次），只要有一次成功，就会把目标标记为“存活”，交给引擎去扫。
- **它还能加速**：对于真正的死目标，`-mt` 会在后台快速识别并将其“拉黑”。主扫描线程在遇到被拉黑的目标时会**直接跳过**，不再浪费时间等待超时。这能有效防止大量死目标拖慢整体扫描进度。
- **它不能做什么**：如果目标服务器真的关机了，或者端口真的没开，`-mt` 试 100 次也是失败。

> **🛑 关于“拉黑”的终局性**
> 
> 用户常问：**“如果一个目标被拉黑了，还有机会‘复活’吗？”**
> **答案：本次扫描中没有机会。**
> 
> 一旦某个目标的失败次数超过阈值（默认为 3 次，可通过 `-mhe` 参数修改），Afrog 就会给它打上“永久拉黑”的标签（内部状态标记为 `Blacklisted`）。
> - **主线程**：遇到它直接跳过。
> - **监控线程**：停止对它的探测。
> - **结果**：直到扫描结束，这个目标都不会再被触碰。这是为了确保扫描效率，防止在一个死目标上无限死磕。

**建议**：在公网扫描或网络环境较差时，**强烈建议开启 `-mt`**，它可以显著减少因为网络波动导致的漏扫。但它不是“硬扫”的开关，**“硬扫”还得靠手动指定完整 URL**。

---

## “为什么我没写 http/https，它也能跑？”——协议补全与探活的真相

当目标不是 URL 时，会走协议探测：探测成功会把目标更新为 `http(s)://...`；探测失败会累计错误，超过阈值会被拉黑，避免拖垮全局跑批。

---

## 实战建议：-t/-T 怎么用才不浪费子弹

### 1) 三种输入形态，对应三种写法

```bash
# 1) 精准打点：你确定这是一个 Web 服务
afrog -t https://example.com

# 2) 你只知道域名/主机，让 Afrog 自己补协议、做探活
afrog -t example.com

# 3) 资产面起手：网段/段范围（后面通常接 -ps）
afrog -t 192.168.1.0/24 -ps
```

### 2) targets.txt 推荐规范（简单但有效）

- 一行一个目标
- 不写注释行（`#` 这种别写）
- 不要混入描述性文本
- 尽量统一大小写（`EXAMPLE.com` 和 `example.com` 在早期去重阶段不一定会被认为是同一个）

### 3) 跑批常用基线（稳）

```bash
afrog -T targets.txt -S info,high,critical -smart
```

---

## 这期你应该记住的“设计答案”

- `-t` 是快，`-T` 是可控、可追溯、可复现
- Afrog 不只是“读取目标”，它会先做“目标分类与规范化”
- 裸域名/裸 IP 不等于 URL：补协议与探活是系统的一部分
- 目标文件越干净，你的扫描越像“工程”，越不靠运气

---

## 下期预告

下一期我们继续把“目标输入”打穿：  
**#02：`--task-smart-timeout` 为什么值得你在跑批里默认带上。**
