# ncat 筆記
## 1. 簡介
`ncat` 是 Nmap 專案附帶的網路工具,可視為傳統 `netcat`(`nc`)的現代化重寫版本。目標是保留 netcat 的簡潔哲學(把資料在網路連線與 stdin/stdout 之間搬移),同時補上原版 netcat 長期缺少或分裂(BSD nc / GNU nc / 各發行版魔改版)的功能。
- 屬於 Nmap 套件的一部分,通常隨 `nmap` 一起安裝(`apt install ncat` 或 `apt install nmap`)
- 二進位檔名為 `ncat`,不會佔用 `nc` 這個名字,避免與系統既有的 netcat 衝突
- 支援 IPv4 / IPv6、SSL/TLS、Proxy(HTTP/SOCKS4/SOCKS5)、連線代理(connection brokering)等進階特性
## 2. 與傳統 netcat 的差異重點
| 特性 | 傳統 nc | ncat |
|---|---|---|
| SSL/TLS 加密連線 | 通常不支援 | 原生支援 `--ssl` |
| Proxy 支援 | 無 | 支援 HTTP/SOCKS4/SOCKS5 作為 client 或 server |
| 多連線 / broker 模式 | 無 | `--broker`、`--chat` 可讓多個 client 互相連線 |
| 執行外部程式 | `-e` 常被移除(安全考量) | `--exec` / `--sh-exec`,且可搭配 `--allow` 限制來源 |
| 存取控制 | 幾乎沒有 | `--allow` / `--deny`(IP 白名單/黑名單) |
| 連線逾時 | 陽春 | `--wait`、`-w`、`--idle-timeout` 較完整 |
| 跨平台一致性 | 各版本行為差異大(BSD/GNU/busybox) | 行為統一,Windows/Linux/macOS 一致 |
## 3. 基本語法
```bash
ncat [選項] 主機 埠號 # 作為 client
ncat -l [選項] [埠號] # 作為 server(監聽)
```
## 4. 常用選項
| 選項 | 說明 |
|---|---|
| `-l, --listen` | 進入監聽(server)模式 |
| `-p <port>` | 指定本地來源埠 |
| `-u, --udp` | 使用 UDP(預設 TCP) |
| `-k, --keep-open` | 監聽時允許多個連線輪流進入(不會斷線後就結束) |
| `-v, --verbose` | 顯示詳細訊息(可疊加 `-vv`) |
| `-w <time>` | 連線逾時,如 `-w 5s` |
| `--idle-timeout <time>` | 閒置多久後自動斷線 |
| `-e, --sh-exec <cmd>` | 連線建立後執行指令,並把 stdin/stdout 接到連線(需編譯時啟用) |
| `--ssl` | 啟用 TLS 加密(client 或 server 皆可用) |
| `--ssl-cert / --ssl-key` | server 端指定憑證與私鑰 |
| `--allow <hosts>` | 只允許指定來源連線 |
| `--deny <hosts>` | 拒絕指定來源連線 |
| `--broker` | 多連線互相轉送模式 |
| `--chat` | 簡易多人聊天室模式(broker 的特例) |
| `-o <file>` | 把連線的原始資料寫入檔案(含雙向) |
| `--proxy <host:port>` | 透過 proxy 連線 |
| `--proxy-type <http|socks4|socks5>` | 指定 proxy 類型 |
| `-C, --crlf` | 傳送時把 `\n` 轉成 `\r\n`(EOL 轉換) |
## 5. 常見使用情境
### 5.1 簡易 port 連通測試(取代 `telnet`)
```bash
ncat -v example.com 443
```
### 5.2 建立一次性 TCP server / client 傳檔
server 端:
```bash
ncat -l 9000 > received_file.tar.gz
```
client 端:
```bash
ncat 192.168.1.10 9000 < myfile.tar.gz
```
> 注意:這種方式沒有進度顯示、沒有校驗,適合臨時內網傳輸,正式用途建議 `rsync`/`scp`。
### 5.3 加上 `-k` 讓 server 可重複接受連線
```bash
ncat -lk 9000
```
沒有 `-k` 的話,server 處理完一個連線斷線後就會結束程序;`-k` 讓它持續監聽。
### 5.4 簡易 chat / 聊天測試
```bash
# 端 A
ncat -l 9000
# 端 B
ncat <A的IP> 9000
```
雙方輸入的文字會即時傳給對方,Ctrl+D 或 Ctrl+C 結束。
### 5.5 TLS 加密連線(自簽測試)
server:
```bash
ncat --ssl -l 9443 --ssl-cert cert.pem --ssl-key key.pem
```
client:
```bash
ncat --ssl target.host 9443
```
### 5.6 當作簡易 HTTP 探測工具
```bash
printf 'GET / HTTP/1.0\r\n\r\n' | ncat example.com 80
```
可以快速看到 HTTP response header,不用裝 curl。
### 5.7 UDP 模式
```bash
ncat -u -l 5000 # server
ncat -u 192.168.1.10 5000 # client
```
### 5.8 透過 proxy 連線
```bash
ncat --proxy proxyhost:1080 --proxy-type socks5 target.host 22
```
### 5.9 執行遠端指令(`--exec`,需注意安全性)
```bash
# server 端:任何連進來的人都會拿到一個 shell(極度不安全,僅限受控測試環境)
ncat -l 4444 --sh-exec /bin/bash
```
> 這是典型的「reverse shell / bind shell」測試手法,只能在自己授權的測試環境或滲透測試演練中使用,正式環境不應開放此類服務。搭配 `--allow` 限制來源可降低風險,但仍建議只在隔離環境操作。
### 5.10 Broker 模式:多個 client 互連
```bash
ncat --broker -l 9000
```
多個 client 連上同一個埠後,彼此的輸入輸出會互相轉送,等同一個簡易的訊息交換節點。
## 6. 除錯與觀察技巧
- `-v` / `-vv`:顯示連線建立、斷開、資料量等資訊,除錯必備
- `-o dump.raw`:把整段連線的原始 bytes 記錄下來,方便後續用 `xxd`/`hexdump` 分析協定
- 搭配 `--append-output` 可以累加寫入而非覆寫
- 想測試 TLS handshake 是否成功,可以加 `--ssl -v`,會印出憑證資訊
## 7. 安全注意事項
1. `--exec` / `--sh-exec` 會讓任何連進來的人執行指令,等同開後門,務必搭配 `--allow` 限制來源 IP,且只在受控環境(如自己的 lab、CTF)使用。
2. 監聽模式(`-l`)預設沒有身份驗證,公網環境不建議直接曝露。
3. 傳檔模式沒有完整性校驗,重要資料建議額外做 checksum(`sha256sum`)比對。
4. 在企業網路環境測試連通性時,注意防火牆/IDS 可能會把 ncat 流量標記為可疑(因為它也是滲透測試常用工具)。
## 8. 與現有工具鏈的關聯
- 可視為 `tmux` + `jq` + `vim` 這類可攜式靜態二進位工具箱的自然延伸:`ncat` 本身也有靜態編譯的發行版本,適合放進同一套 Alpine Docker build 流程裡打包。
- 比 `socat` 語法更直覺,但功能廣度(尤其是 fd 轉發、PTY 處理)不如 `socat`;日常連通測試、簡易傳檔、TLS 測試用 `ncat` 足夠,複雜的雙向管線轉接可以留給 `socat`。
- 在 k3s/K8s home lab 除錯情境中,`ncat` 很適合丟進一個臨時 debug pod 裡測 service/port 是否可達(例如 `kubectl run tmp --rm -it --image=alpine -- sh` 裝上 ncat 後測 `ncat -zv service-name 5432`)。
## 9. 快速備忘(Cheat Sheet)
```bash
# 測連通
ncat -v host port
# 開一個簡易 server
ncat -lk port
# TCP 傳檔(收)
ncat -l port > out.file
# TCP 傳檔(送)
ncat host port < in.file
# UDP
ncat -u -l port
ncat -u host port
# TLS
ncat --ssl -l port --ssl-cert c.pem --ssl-key k.pem
ncat --ssl host port
# 走 SOCKS5 proxy
ncat --proxy ph:1080 --proxy-type socks5 host port
```