Telnet 实战与排错 — 明文抓包、端口探测与安全禁用

Wireshark 还原 Telnet 明文口令、telnet/nc 端口探测、手工调试文本协议与彻底禁用 Telnet / 应用层 / TCP 23

这篇你能学到

  • 如何用 Wireshark / tshark 把 Telnet 的明文口令和会话一键还原出来(安全教学实验)。
  • 如何用 telnet / nc / Test-NetConnection 做端口连通性探测,并正确解读"连上 / refused / timeout"。
  • 如何从零禁用 Telnet(Linux / Windows / 网络设备),以及老设备只能 Telnet 时的过渡方案与常见故障排错。

1. 抓包观察

1.1 Wireshark 显示过滤式

这组过滤式能干什么:快速从海量包里只挑出 Telnet 流量、只看协商命令、或只抓"字符模式的单字节按键包 / Ctrl+C 的紧急包",定位登录阶段与登录口令位置。

1
2
3
4
5
6
7
8
9
telnet # Telnet 解析器
tcp.port == 23 # 标准端口
telnet.data # 只看数据字节(Wireshark 会译出可读文本)
telnet.cmd # IAC 命令
telnet.cmd == 251 || telnet.cmd == 253 # WILL / DO 协商
telnet.subcmd # 子协商内容(终端类型、NAWS)
telnet.option # 选项码:1=ECHO 3=SGA 24=TTYPE 31=NAWS
tcp.port == 23 && tcp.len == 1 # 字符模式的单字节按键包
tcp.port == 23 && tcp.flags.urg == 1 # Synch(Ctrl+C)

1.2 一键还原明文口令(安全教学实验)

这组命令能干什么:在隔离实验环境里抓一份 Telnet 会话的包,再用 Wireshark 或 tshark 把明文口令和命令还原,直观感受"明文"有多危险。

你自己拥有的隔离实验环境中做一次,直观感受风险:

1
2
3
4
# 抓包端
sudo tcpdump -i any -nn 'tcp port 23' -w telnet.pcap
# 另一终端登录
telnet 192.168.56.10

Wireshark 中:右键任一 Telnet 包 → Follow → TCP Stream,可看到类似:

1
2
3
4
5
6
login: aallssiiccee ← 每个字符出现两次:客户端发送 + 服务端回显
Password:
P@ssw0rd ← 口令只出现一次(服务端 WON'T ECHO)
Last login: Mon Aug 3 10:12:33
$ cat /etc/shadow
root:$6$xxxxxxxx... ← 输出同样明文可读

命令行等价:

1
2
3
tshark -r telnet.pcap -qz follow,tcp,ascii,0
# 只提取客户端发出的字符(口令重建)
tshark -r telnet.pcap -Y 'telnet && ip.src==192.168.56.1' -T fields -e telnet.data | tr -d '\n'

1.3 典型字段说明

观察点现象判读
连接开始连续多个 IAC DO/WILL 三字节包选项协商阶段;看 telnet.option 判断进入哪种模式
IAC WILL ECHO(FF FB 01)服务端要求远端回显进入字符模式,后续每键一包
IAC WON'T ECHO(FF FC 01)服务端临时关回显马上就是口令输入,抓包重点位置
IAC SB 18 00 ... IAC SE终端类型子协商可看到 xterm/vt100 字符串
IAC SB 1F ...NAWS4 字节即列数与行数
大量 tcp.len == 1字符模式效率低但交互好;行模式则为整行
tcp.flags.urg == 1 + FF F2Synch用户按了 Ctrl+C
明文可读的 ASCII所有内容这就是必须淘汰 Telnet 的全部理由

2. 常用命令 / 配置

2.1 端口连通性探测(今天 Telnet 的主要用途)

这组命令能干什么:用 telnet 本身或更好的替代工具(nc、bash /dev/tcp、nmap、Test-NetConnection)探测"某 IP 的某 TCP 端口是否开放"。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Linux / macOS
telnet 192.168.1.10 3306 # 连上 = 端口开放;Connection refused = 端口关闭
telnet 192.168.1.10 80
# 退出 telnet:先按 Ctrl + ] 再输入 quit

# 更推荐的替代工具
nc -zv 192.168.1.10 3306 # netcat,专业且脚本友好
nc -zv -w 3 192.168.1.10 80-90 # 端口范围扫描 + 3 秒超时
timeout 3 bash -c '</dev/tcp/192.168.1.10/3306' && echo OPEN || echo CLOSED # 纯 bash,无需装包
nmap -Pn -p 3306 192.168.1.10 # 最完整
1
2
3
4
5
6
7
# Windows:telnet 客户端默认未安装
Test-NetConnection 192.168.1.10 -Port 3389 # 推荐,输出 TcpTestSucceeded
tnc 192.168.1.10 -Port 443 -InformationLevel Detailed
# 若确实需要 telnet 客户端
dism /online /Enable-Feature /FeatureName:TelnetClient
# 或
Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient

2.2 用 Telnet 手工调试文本协议

这段能干什么:Telnet 是"裸 TCP + 文本",正好用来手工发 HTTP/SMTP/POP3/Redis 请求,验证服务端是否按协议返回。

HTTP/1.1

1
2
3
4
5
telnet example.com 80
# 连上后逐行输入(末尾必须多敲一个空行)
GET / HTTP/1.1
Host: example.com
Connection: close

SMTP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
telnet mail.example.com 25
EHLO test.local
MAIL FROM:<a@test.local>
RCPT TO:<b@example.com>
DATA
Subject: hello

test body
.
QUIT

POP3

1
2
3
4
5
6
7
telnet mail.example.com 110
USER alice
PASS secret
STAT
LIST
RETR 1
QUIT

Redis

1
2
3
4
telnet 127.0.0.1 6379
PING
INFO server
QUIT

调 TLS 端口(443/465/993)时 telnet 无能为力,改用: openssl s_client -connect example.com:443 -servername example.com

2.3 Telnet 客户端内部命令

这张表能干什么:连接后按 Ctrl + ] 进入命令模式,可做断开、看状态、调试协商、切回显、发中断等——排错时常用 toggle options 看协商过程。

连接后按 Ctrl + ] 进入命令模式:

命令作用
quit / q断开并退出
close关闭当前连接但保留 telnet 提示符
status显示连接状态与协商结果
toggle options打印选项协商过程(排错神器
set echo切换本地回显
send ip发送 IAC IP(中断)
send ayt发送 Are You There 探活
mode line / mode character切换行/字符模式
open host port建立新连接
?帮助

调试协商过程:

1
2
telnet -d 192.168.1.10 # 开启调试
# 或连接后:Ctrl+] → toggle options → 回车继续

2.4 服务端:检查与彻底禁用(Linux)

这段配置能干什么:查 telnetd 是否在监听,然后用 systemd / xinetd 停掉并屏蔽它,卸载软件包,再用防火墙兜底,最后验证端口已关闭。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 是否在监听
sudo ss -tlnp | grep ':23'
sudo systemctl status telnet.socket inetd xinetd 2>/dev/null

# systemd socket 方式(Debian/Ubuntu telnetd)
sudo systemctl stop telnet.socket
sudo systemctl disable telnet.socket
sudo systemctl mask telnet.socket # mask 防止被依赖拉起

# xinetd 方式(老 RHEL)
sudo sed -i 's/disable.*=.*no/disable = yes/' /etc/xinetd.d/telnet
sudo systemctl restart xinetd

# 卸载服务端软件包
sudo apt purge telnetd inetutils-telnetd -y # Debian/Ubuntu
sudo yum remove telnet-server -y # RHEL/CentOS

# 防火墙兜底
sudo ufw deny 23/tcp
sudo firewall-cmd --permanent --remove-service=telnet && sudo firewall-cmd --reload
sudo iptables -A INPUT -p tcp --dport 23 -j DROP

# 验证已关闭
nc -zv localhost 23 # 应返回 Connection refused

2.5 Windows 禁用 Telnet 服务端

这段 PowerShell 能干什么:停止并禁用 Windows 的 Telnet 服务,并建议把客户端也一并移除,减少攻击者可用的横向移动工具。

1
2
3
4
5
6
Get-Service TlntSvr -ErrorAction SilentlyContinue
Stop-Service TlntSvr -Force
Set-Service TlntSvr -StartupType Disabled
Disable-WindowsOptionalFeature -Online -FeatureName TelnetServer
# 客户端也建议移除(减少横向移动工具)
Disable-WindowsOptionalFeature -Online -FeatureName TelnetClient

2.6 网络设备:从 Telnet 切到 SSH

这段配置能干什么:在 Cisco / 华为设备上关掉 Telnet、只开 SSH,从带外管理层面消除明文风险。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
! Cisco IOS
crypto key generate rsa modulus 2048
ip domain-name example.com
username admin privilege 15 secret <StrongPass>
line vty 0 15
 transport input ssh ! 只允许 SSH,禁掉 telnet
 login local
 exec-timeout 5 0
!
ip ssh version 2
ip ssh time-out 60
ip ssh authentication-retries 3
1
2
3
4
5
6
# 华为 VRP
stelnet server enable
undo telnet server enable
user-interface vty 0 4
 authentication-mode aaa
 protocol inbound ssh

2.7 合规扫描:找出网内还开着 Telnet 的设备

这组命令能干什么:用 nmap / masscan 扫全网的 23 端口,产出"还在跑 Telnet 的资产清单"作为合规基线。

1
2
3
nmap -Pn -p 23 --open 10.0.0.0/24 -oG telnet-hosts.txt
nmap -Pn -p 23 --script telnet-encryption,banner 10.0.0.0/24
masscan -p23 10.0.0.0/8 --rate 1000 # 大网段快速扫(需授权)

3. 常见故障与排错

3.1 telnet: command not found

先记住结论:这不是 Telnet 服务的问题,而是本地客户端没装——现代系统默认不再带 telnet 客户端,装一个或用 nc/Test-NetConnection 替代即可。

系统安装
Ubuntu/Debiansudo apt install telnet
RHEL/CentOS/Rockysudo yum install telnet
Alpineapk add busybox-extrasbusybox-extras telnet
macOSbrew install telnet(系统自 High Sierra 起移除)
Windowsdism /online /Enable-Feature /FeatureName:TelnetClient

更好的选择:直接用 ncTest-NetConnection</dev/tcp/host/port,无需安装。

3.2 探测结果如何解读

先记住结论:三种结果对应三种网络语义——Connected = 端口开;refused = 主机在但端口没人听(RST);timeout = 包被吃掉、根本没回应。前者说明防火墙放行了只是服务没起,后者说明包在路上被丢了。

输出含义后续动作
Connected to host. + 光标闪烁端口开放且 TCP 可达正常
Connection refused主机可达但端口无监听(收到 RST)检查服务是否启动、监听地址是否 127.0.0.1
长时间挂起后 Connection timed out报文被丢弃(防火墙 DROP / 路由不通 / 主机不存在)查安全组、iptables、路由
No route to host本地路由或 ARP 层不通ip routeping 网关
Unable to connect to remote host通用连接失败结合 tcpdump 看有无 SYN 发出

关键区分:refused = 有人拒接(RST)timeout = 电话打不通(无响应)。前者说明防火墙放行了但服务没开,后者说明包在路上被吃了。

3.3 连上后无响应 / 乱码

先记住结论:连上却一片空白或乱码,多半是对端根本不是文本协议(MySQL/SSH/TLS),或被 NVT 当 ASCII 解释了二进制——换对工具或协商 BINARY 即可,不要怀疑网络。

现象原因处理
连上后一片空白对端是二进制协议(如 MySQL、SSH、TLS),不是文本协议ncopenssl s_client 或专用客户端
满屏乱码二进制数据被 NVT 当 ASCII 解释同上;或 telnet -8/协商 BINARY
输入无回显服务端未发 WILL ECHOCtrl+]set echo 打开本地回显
每个字符显示两遍本地回显 + 远端回显同时开Ctrl+]set echo 关掉本地
退格键变成 ^H^?终端 erase 字符与远端不匹配stty erase ^H 或登录后 export TERM=vt100
中文乱码NVT 是 7 位,未协商 BINARYtelnet -8,或改用 SSH

3.4 无法退出 Telnet

先记住结论:telnet 没有普通的 Ctrl+C 退出通道,必须用转义序列 Ctrl + ] 进入 telnet> 提示符再 quit;被占用就用 -e 换一个转义键。

转义序列Ctrl + ](Windows/Linux 默认),进入 telnet> 提示符后输入 quit

Ctrl+] 无效(被终端占用):

1
2
3
telnet -e ^X host port # 自定义转义字符为 Ctrl+X
# 或另开终端
pkill telnet

3.5 手工发 HTTP 请求得不到响应

先记住结论:手工发 HTTP 收不到响应,九成是"格式不对"——漏了结束空行、缺 Host 头、换行不是 CRLF,或对端其实是 HTTPS(TLS)而非明文 HTTP。

原因说明
忘了空行HTTP 头部结束必须是空行(多敲一次回车)
缺 Host 头HTTP/1.1 强制要求 Host:
换行不对严格来说需 CRLF;telnet 已按 NVT 发 CRLF,一般没问题;ncprintf 'GET / HTTP/1.1\r\nHost: x\r\n\r\n'
目标是 HTTPS443 是 TLS,telnet 无法握手 → 用 openssl s_client
输入太慢被超时服务端 keep-alive 超时;改用脚本一次性发送

3.6 老设备只能 Telnet 怎么办(过渡方案)

先记住结论:能升级就升级到 SSH;实在不能升级,就把设备圈进隔离管理网 + 跳板机 SSH 隧道,把"明文 Telnet"压缩到内网最后一跳,再配 ACL 白名单与审计。

优先级从高到低:

  1. 升级固件启用 SSH(多数设备近十年固件都支持)。
  2. 若不可升级:把设备置于独立管理 VLAN,禁止跨网段访问 23 端口。
  3. 通过跳板机 + SSH 隧道访问:
    1
    2
    
    ssh -N -L 2323:switch.mgmt:23 admin@jumphost
    telnet 127.0.0.1 2323 # Telnet 明文段仅存在于内网最后一跳
    
  4. ACL 限制源 IP 白名单 + 强制日志审计。
  5. 排入设备淘汰计划。

4. 与其他协议对比

维度TelnetSSHnetcat (nc)rlogin串口 Console
端口TCP 23TCP 22任意TCP 513无(物理口)
规范RFC 854/855RFC 4251~4254无标准RFC 1282RS-232
加密有(内建)无(ncat --ssl 可加)物理隔离
服务端认证主机密钥 TOFU/CA无(.rhosts 更危险)物理接触
客户端认证明文口令公钥/口令/2FA/证书主机信任,可免口令设备本地
终端协商(NVT + IAC 选项)有(pty-req)(裸管道)有(自动传 TERM)
文件传输scp/sftp支持(管道)rcpX/Y/ZMODEM
端口转发-L/-R/-D有限(-l 中继)
二进制安全需协商 BINARY原生支持原生支持一般支持
今日地位淘汰(仅探测/调试)事实标准网络瑞士军刀淘汰带外救援手段

探测场景选型:脚本化/二进制场景用 nc;交互调试文本协议用 telnet(NVT 处理换行更省心);全面扫描用 nmap;Windows 环境用 Test-NetConnection

5. 速查表 / 常见面试题

5.1 IAC 命令速查

命令命令
255IAC247EC 擦除字符
254DON’T246AYT 探活
253DO245AO 中止输出
252WON’T244IP 中断进程
251WILL243BRK
250SB 子协商开始242DM 数据标记
249GA241NOP
248EL 擦除行240SE 子协商结束

5.2 选项码速查

选项选项
0BINARY31NAWS 窗口大小
1ECHO32TERMINAL-SPEED
3SUPPRESS-GO-AHEAD34LINEMODE
5STATUS36/39ENVIRON / NEW-ENVIRON
24TERMINAL-TYPE37/38AUTHENTICATION / ENCRYPTION

5.3 操作速查

目标命令
探测端口telnet host port / nc -zv host port / Test-NetConnection host -Port n
退出 telnetCtrl + ]quit
自定义转义键telnet -e ^X host port
查看协商过程telnet -d hostCtrl+]toggle options
8 位模式telnet -8 host
抓明文tshark -r x.pcap -qz follow,tcp,ascii,0
关闭服务端systemctl disable --now telnet.socket + apt purge telnetd
设备切 SSHCisco transport input ssh / 华为 undo telnet server enable

5.4 高频面试题

Q1:Telnet 为什么不安全?列举至少三点。 A:① 用户名与口令明文传输,抓包即得;② 会话内容(命令与输出)全明文;③ 无服务端身份认证,无法防中间人;④ 无消息完整性保护,可被注入/劫持;⑤ 历史 telnetd 存在多个预认证远程漏洞;⑥ NEW-ENVIRON 等选项曾被用于认证绕过。

Q2:telnet host 80 能连上说明什么?连不上又说明什么? A:能连上说明 TCP 三次握手成功,即网络可达 + 目标端口有进程监听 + 中间无阻断Connection refused 说明主机可达但端口无监听(收到 RST);timed out 说明报文被防火墙 DROP 或路由不可达。注意:连上只证明 TCP 层通,不证明应用层服务健康。

Q3:什么是 NVT?为什么需要它? A:Network Virtual Terminal,网络虚拟终端。它定义了一套"最小公共分母"终端规范(7 位 ASCII、CR LF 换行、固定控制码集),使异构终端设备能互通——每端只需实现"本地终端 ↔ NVT"的转换,而不必两两适配。

Q4:IAC 是什么?如何在数据中传输字节 0xFF? A:IAC = Interpret As Command,值 255(0xFF),是 Telnet 的带内命令引导符。要在数据中传输一个字面量 0xFF,必须转义为 IAC IACFF FF)。

Q5:解释 WILL / WON’T / DO / DON’T 的语义差异。 A:WILL/WON'T 描述发送方自身是否启用某选项(“我要/我不要做”);DO/DON'T 描述对对方的要求(“你要/你别做”)。配对关系:WILLDO/DON'TDOWILL/WON'T。RFC 854 规定只在状态改变时发起请求、收到请求必须应答、应答不再触发新请求,以此避免无限循环。

Q6:Telnet 的字符模式是怎么形成的?有什么代价? A:服务端发 WILL ECHO + 双方 SUPPRESS-GO-AHEAD 后进入字符模式:客户端关闭本地回显,逐字符发送,由服务端回显。好处是支持 vi、Tab 补全等实时交互;代价是每个按键一个 TCP 包(40+ 字节头承载 1 字节数据),高延迟链路上体验差、包量大。

Q7:Telnet 和 SSH 的关系?SSH 继承了什么? A:SSH 是 Telnet 的安全替代品,保留了"远程终端"语义并结构化:终端类型、窗口大小、终端模式在 SSH 中变成 pty-req 通道请求(模式编号甚至沿用 Telnet 思路);同时新增了加密传输层、主机密钥认证、公钥认证、多通道复用与端口转发。

Q8:输入口令时屏幕不显示,是不是说明口令被加密了? A:不是。那只是服务端发送 IAC WON'T ECHO 让客户端停止回显,纯粹是显示层面的处理。口令字节在网络上依然是明文,抓包可直接读出。这是 Telnet 最容易被误解的一点。

Q9:生产环境如何彻底消除 Telnet 风险? A:① 服务端 systemctl disable --now telnet.socket 并卸载 telnetd 包;② 防火墙 DROP 23 端口;③ 网络设备改 transport input ssh / undo telnet server enable;④ 用 nmap 定期扫描全网 23 端口作为合规基线;⑤ 无法改造的老设备置于隔离管理 VLAN + 跳板机 SSH 隧道访问 + 源 IP 白名单;⑥ 客户端侧也建议移除,减少攻击者横向移动可用工具。

Q10:为什么调试 HTTPS 不能用 telnet? A:443 端口上跑的是 TLS,连接后服务端等待 ClientHello 二进制握手报文,telnet 发的是 NVT 明文,握手必然失败。应使用 openssl s_client -connect host:443 -servername hostcurl -v