运维安全08 - 日志检测和 tcpdump (抓包) 的介绍以及使用
一、入侵检测
1.1 日志检测
在进行入侵检测时,首先我们需要认识到系统日志是我们的第一道防线。
它们记录了系统上发生的所有活动,包括但不限于用户登录、服务启动与停止、文件访问等。
通过仔细分析这些日志,我们可以识别出异常行为或潜在的安全威胁。
安全相关日志
对于入侵检测来说,重点关注的日志类型是 /var/log/secure。
这里记录了所有与认证相关的事件,如SSH登录尝试;
为了有效地使用这些日志进行入侵检测,我们可以通过特定关键词过滤日志内容,例如查找‘Failed password’来发现可能的暴力破解攻击,或是搜索‘Accepted password’确认成功登录的详情。
要查看 SSH 登录失败的日志,可以使用 grep
命令过滤包含Failed password关键字的日志条目:
grep -i "Failed password" /var/log/secure
示例输出:
[root@www ~]# grep -i "Failed password" /var/log/secure
Jun 24 16:27:53 www sshd[115131]: Failed password for root from 192.168.66.1 port 12801 ssh2
Jun 24 16:27:58 www sshd[115131]: Failed password for root from 192.168.66.1 port 12801 ssh2
这些日志显示了尝试登录失败的时间、来源 IP 地址和端口号等信息,可以帮助我们识别可能的暴力破解攻击。
同样地,查看 SSH 登录成功的日志可以帮助我们确认合法用户的活动情况:
grep -i "Accepted password" /var/log/secure
示例输出:
Oct 24 12:18:06 chao sshd[7086]: Accepted password for root from 172.16.130.91 port 41415 ssh2
假设我们怀疑有未经授权的用户试图访问服务器,我们可以首先检查/var/log/secure文件中是否有大量的‘Failed password’条目指向同一IP地址,这可能是暴力破解攻击的迹象。
接着,我们可以进一步查看该时间段内其他日志文件中的记录,寻找任何不寻常的行为模式,比如非正常工作时间内的活动或从未见过的新用户登录。
内容过滤
为了有效地进行入侵检测,日志内容过滤是一个关键步骤。
它可以帮助我们从大量的日志信息中提取出与安全相关的事件,从而更快地识别潜在的攻击行为。
下面是一些具体的策略和方法来实现日志内容过滤。
grep
示例:查找所有失败的 SSH 登录尝试
grep -E "Failed password|Invalid user" /var/log/secure
这条命令会返回包含Failed password或Invalid user的所有行,这通常代表了未经授权的登录尝试。
awk
对于需要更复杂处理的情况,awk
提供了一个灵活的环境来处理文本数据。
它可以基于多个条件筛选日志,并且可以对输出格式进行定制。
示例:仅显示SSH登录失败的来源IP地址
grep "Failed password" /var/log/secure | awk '{print $11}'
此命令将只打印失败尝试的第11个字段(通常是源IP地址)。
sed
有时候,日志格式可能不是最佳的,或者我们需要转换日志内容以更好地适应我们的分析需求。
sed
可以用来编辑和转换日志内容。
示例:删除所有包含特定字符串的日志条目
sed '/specific_string_to_remove/d' /var/log/secure > filtered_log.txt
这将创建一个新的日志文件,其中不包含任何含有specific_string_to_remove的条目。
应用案例
的服务器可能遭受了 SSH 暴力破解攻击,攻击者使用脚本不断尝试不同的用户名和密码进行登录。
需要从 /var/log/secure
中提取所有失败的登录尝试,并找出哪些 IP 地址发起的请求最多,从而判断是否存在异常行为。
-
提取所有失败的 SSH 登录尝试;
-
获取来源 IP 地址;
-
统计每个 IP 的失败次数;
-
按失败次数排序;
-
输出结果到屏幕并保存到文件以便后续分析。
grep "Failed password" /var/log/secure | \
awk '{print $11}' | \
sort | \
uniq -c | \
sort -nr > ssh_brute_force_attack.log && \
cat ssh_brute_force_attack.log
其他日志文件
除了 SSH 日志外,还有其他一些重要的日志文件可以帮助我们监控系统的安全状态:
系统事件日志
系统事件日志通常记录了内核和系统服务的各种事件,包括启动、停止、错误等信息。
-
/var/log/messages
例如,查看最近的系统事件:
tail -n 50 /var/log/messages
应用程序日志
应用程序日志记录了特定服务或应用的运行情况,如 Web 服务器(Apache/Nginx)、数据库(MySQL/MongoDB)等。
-
Apache:
/var/log/apache2/error.log
-
Nginx:
/var/log/nginx/error.log
-
MySQL:
/var/log/mysql/error.log
例如,查看 Apache 的错误日志:
tail -n 50 /var/log/apache2/error.log
1.2 last_cron_rc_local
在进行入侵检测时,检查系统中的一些关键配置和文件可以帮助识别潜在的安全威胁。
last
命令、cron
作业以及/etc/rc.local
脚本是三个重要的方面,
它们各自提供了关于用户登录活动、计划任务执行情况以及系统启动时运行的命令的信息。下
last
last
命令可以显示最近用户登录信息,包括登录时间、来源IP地址等。
这对于发现异常登录行为特别有用,比如从未知或不寻常位置发起的登录尝试。
last
这将列出所有用户的登录记录。查找不熟悉的IP地址或异常登录时间点,可能是入侵的迹象。
cron
定期检查cron
作业可以帮助我们了解是否有未经授权的定时任务被添加到系统中,这可能是攻击者用来维持访问权限的一种方式。
查看当前用户的cron作业:
crontab -l
查看系统级别的cron作业:
ls /etc/cron.d /etc/crontab /var/spool/cron/
注意任何不认识的或看起来可疑的任务。
/etc/rc.local
/etc/rc.local
是一个特殊的脚本,它会在系统启动过程中被执行。
如果该文件被篡改,可能会导致系统在每次重启时自动执行恶意代码。
检查/etc/rc.local
文件:
cat /etc/rc.local
审查文件内容,确保没有任何未知或不必要的命令。
正常情况下,这个文件可能包含注释或少量合法命令。
应用案例
某天发现服务器响应变慢,怀疑系统可能被入侵。
-
用户登录记录(使用
last
) -
定时任务(查看
cron
) -
系统启动脚本(检查
/etc/rc.local
)
检查用户登录历史 —— last
运行命令:
last
输出中出现如下可疑记录:
root pts/0 192.168.1.100 Mon Jun 24 03:15 - 03:20 (00:05)
reboot system boot 3.10.0-1160.el7.x Tue Jun 25 08:00 - 10:00 (2 days)
注意点:
root 用户在凌晨3点多登录过一次;
来源 IP 是
192.168.1.100
,这个地址不属于正常管理网络;这个时间点不记得有任何人操作过系统。
初步判断:可能存在未经授权的 root 登录行为。
检查定时任务 —— cron
查看所有用户的 cron 任务:
crontab -l 2>/dev/null || echo "No crontab for current user"
查看系统级 cron 任务:
ls /etc/cron.d/ /etc/crontab /var/spool/cron/
然后查看 /var/spool/cron/root
内容:
cat /var/spool/cron/root
发现可疑内容:
*/5 * * * * /tmp/exploit.sh > /dev/null 2>&1
注意点:
每5分钟执行一次
/tmp/exploit.sh
;该脚本路径非常可疑(通常攻击者会把恶意脚本放在临时目录);
脚本内容未显示,但重定向到空设备说明想隐藏输出。
判断:攻击者设置了定时任务以维持访问权限。
检查系统启动项 —— /etc/rc.local
查看文件内容:
cat /etc/rc.local
发现异常内容:
#!/bin/bash
/tmp/persistence.sh &
exit 0
注意点:
启动时执行
/tmp/persistence.sh
,可能是后门程序;使用
&
表示后台运行,隐蔽性高。判断:攻击者试图通过系统启动项实现持久化控制。
1.3 异常流量检测
在网络安全管理中,查看异常流量是识别潜在威胁、确保网络稳定运行的关键步骤。
异常流量可能由多种原因引起,包括但不限于恶意软件活动、DDoS攻击、未经授权的访问尝试等。
通过监测和分析网络流量,我们可以:
-
早期发现安全威胁:及时发现并响应潜在的安全漏洞或攻击行为。
-
优化网络性能:识别造成网络拥塞的应用或用户,进行合理调整以提升整体效率。
以下是几款广泛使用的流量监控工具,以及它们各自的特点和适用场景:
-
Wireshark
-
描述:Wireshark 是一款开源的网络协议分析器,能够详细地捕获并分析数据包。
-
应用场景:非常适合深入调查特定的网络问题或安全事件,提供详细的协议解析能力。
-
-
tcpdump
-
描述:命令行下的轻量级抓包工具,易于使用且功能强大。
-
应用场景:适用于快速获取网络接口上的流量样本,特别适合于远程服务器上的临时监控任务。
-
-
iftop
-
描述:实时显示网络连接及其带宽使用情况的工具,界面直观易懂。
-
应用场景:用于即时监控网卡接口的流量状况,帮助管理员迅速定位高流量消耗者。
-
-
Cacti
-
描述:基于Web的网络流量监控解决方案,支持历史数据分析和图形化展示。
-
应用场景:适用于长期监控网络设备的流量趋势,帮助企业规划网络资源分配。
-
-
Zabbix
-
描述:全面的企业级监控平台,不仅限于网络流量监控,还包括服务器健康状态、应用性能等多项指标。
-
应用场景:作为综合性的监控系统,Zabbix 可以为企业提供一站式的运维管理服务。
-
-
Prometheus + Grafana
-
描述:Prometheus 是一个强大的时间序列数据库,常与 Grafana 结合使用来创建定制化的仪表盘。
-
应用场景:适合构建自定义的监控体系,满足特定业务需求下的流量监控与报警需求。
-
iftop
iftop 是 Linux 系统一个免费的网卡实时流量监控工具,类似于 top 命令。
iftop 可以监控指定网卡的实时流量、端口连接信息、反向解析 IP 等,还可以精确显示本机网络流量及网络内各主机和本机相互通信的流量集合,非常适合于监控代理服务器或路由器的网络流量。
同时,iftop 对检测流量异常的主机非常有效,通过 iftop 的输出可以迅速定位主机流量异常的根源,这对于网络故障排查、网络安全检测是十分有用的。
缺点就是无报表功能,且必须以 root 身份才能运行。
能够帮助快速了解哪些主机正在消耗最多的带宽,并且可以用于检测异常流量或性能瓶颈。
需要确保系统已经安装了 EPEL(Extra Packages for Enterprise Linux)仓库,因为 iftop
不是默认包含在 CentOS 的基础仓库中。
安装 EPEL 仓库:
sudo yum install epel-release -y
安装 iftop
:
sudo yum install iftop -y
基本用法
要开始监控某个特定网卡的流量,只需运行 iftop
并指定网卡名称即可。
例如,如果想要监控名为 ens33
的网卡流量,可以使用以下命令:
sudo iftop -i ens33
-i 指定需要检测的网卡, 如果有多个网络接口,则需要注意网络接口的选择,如:# iftop -i eth1
-B 将输出以 byte 为单位显示网卡流量,默认是 bit
-n 将输出的主机信息都通过 IP 显示,不进行 DNS 解析
-N 只显示连接端口号,不显示端口对应的服务名称
-F 显示特定网段的网卡进出流量 如: iftop -F 192.168.85.0/24
-h 帮助,显示参数信息
-p 以混杂模式运行 iftop,此时 iftop 可以用作网络嗅探器
-P 显示主机以及端口信息
-m 设置输出界面中最上面的流量刻度最大值,流量刻度分 5 个大段显示 如:# iftop -m 100M
-f 使用筛选码选择数据包来计数 如 iftop -f filter code
-b 不显示流量图形条
-c 指定可选的配置文件,如:iftop -c config file
-t 使用不带 ncurses 的文本界面,
以下两个是只和 -t 一起用的:
-s num num 秒后打印一次文本输出然后退出,-t -s 60 组合使用,表示取 60 秒网络流量输出到终端
-L num 打印的行数
-f 参数支持 tcpdump 的语法,可以使用各种过滤条件。
交互操作
在 iftop
的实时监控界面中,还可以对输出结果进行交互式操作,用于对输出信息进行整理和过滤,在上图所示界面中,按键 h”
即可进入交互选项界面。
iftop
的交互功能和 Linux
下的 top
命令非常类似,交互参数主要分为 4
个部分,分别是一般参数、主机显示参数、端口显示参数和输出排序参数。
相关参数的含义如下表所示。
参数 含义
P 通过此键可切换暂停/继续显示
h 通过此键可在交互参数界面/状态输出界面之间来回切换
b 通过此键可切换是否显示平均流量图形条
B 通过此键可切换显示2秒、10秒、40秒内的平均流量
T 通过此键可切换是否显示每个连接的总流量
j/k 按j键或k键可以向上或向下滚动屏幕显示当前的连接信息
l 通过此键可打开iftop输出过滤功能,比如输入要显示的IP,按回车后,屏幕就只显示与这个IP相关的流量信息
L 通过此键可切换显示流量刻度范围,刻度不同,流量图形条会跟着变化
q 通过此键可退出iftop流量监控界面
n 通过此键可使iftop输出结果以IP或主机名的方式显示
s 通过此键可切换是否显示源主机信息
d 通过此键可切换是否显示远端目标主机信息
t 通过此键可切换iftop显示格式,连续按此键可依次显示:以两行显示发送接收流量、以一行显示发送接收流量、只显示发送流量/接收流量
N 通过此键可切换显示端口号/端口号对应服务名称
S 通过此键可切换是否显示本地源主机的端口信息
D 通过此键可切换是否显示远端目标主机的端口信息
p 通过此键可切换是否显示端口信息
1/2/3 根据最近 2 秒、10 秒、40 秒的平均网络流量排序
< 通过此键可根据左边的本地主机名或IP地址进行排序
> 通过此键可根据远端目标主机的主机名或IP地址进行排序
o 通过此键可切换是否固定显示当前的连接
操作案例
显示网卡 ens33 的信息,主机通过 ip 显示
$ iftop -i ens33 -n
显示端口号(添加 -P 参数,进入界面可通过 p 参数关闭)
$ iftop -i ens33 -n -P
显示将输出以 byte 为单位显示网卡流量,默认是 bit
$ iftop -i ens33 -n -B
显示流量进度条
## 进入界面后按下 L
$ iftop -i ens33 -n
显示每个连接的总流量
## 进入界面后按下 T
$ iftop -i ens33 -n
显示指定 ip 172.17.1.158 的流量
进入界面后按下 l 后,再输入 172.17.1.158 并回车)
$ iftop -i ens33 -n
实战
下面我们将通过找出最费流量的 IP 和端口号这一具体实例,来演示 iftop 强大的功能。
iftop -i ens33 -nNB -m 10M
-
-i 指定网卡,
-
-n 代表主机通过ip显示不走DNS
-
-N 只显示连接端口号,不显示端口对应的服务名称(不加会显示如ssh这样的服务名称,不便于排查)
-
-B 指定显示单位为Kb,默认是bit,太小!
-
-m 设置输出界面中最上面的流量刻度最大值,流量刻度分5个大段显示
按下 L 显示流量刻度,L 参数直接显示进度条,方便我们阅读。
按下 T 显示总量,有个总数统计,看着方便!
按下 3,根据最近 40s 统计排序,用平均值来统计最权威点.
按下 t,发送和接受合成一行
多按几次 B,查看最近 2s、10s、40s 的统计
图中的 172.17.1.158 就是我们找到的流量用得最多的 IP
筛选指定 IP 172.17.1.158,按下 l, 输入172.17.1.158,出现如下,这下就只看到这个 IP 的流量监控了
找到这个 IP 哪个端口流量用得最多,按下 p, 根据端口号显示
到这里,我们就学会了如何找出流量用得最多的 IP 和端口号。
二、tcpdump简介
大家都知道,网络上的流量、数据包,非常的多,因此要想抓到我们所需要的数据包,就需要我们定义一个精准的过滤器,把这些目标数据包,从巨大的数据包网络中抓取出来。
所以学习抓包工具,其实就是学习如何定义过滤器的过程。
而在 tcpdump 的世界里,过滤器的实现,都是通过一个又一个的参数组合起来,一个参数不够精准,那就再加一个,直到我们能过滤掉无用的数据包,只留下我们感兴趣的数据包。
安装tcpdump
sudo yum install tcpdump
用法解释
tcpdump 的参数非常的多,初学者在没有掌握 tcpdump 时,会对这个命令的众多参数产生很多的疑惑。
-
option 可选参数:将在后边解释。
-
proto 类过滤器:根据协议进行过滤,可识别的关键词有: tcp, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet
-
direction 类过滤器:根据数据流向进行过滤,可识别的关键字有:src, dst,同时你可以使用逻辑运算符进行组合,比如 src or dst
-
type 类过滤器:可识别的关键词有:host, net, port, portrange,这些词后边需要再接参数。
选项 | 含义 |
---|---|
-i <interface> | 指定监听的网络接口(如 ens33 、eth0 ) |
-nn | 不解析主机名和服务名,直接显示 IP 和端口号 |
-n | 不解析主机名(只显示 IP) |
-v / -vv / -vvv | 显示详细信息(越多越详细) |
-s snaplen | 设置抓包长度(默认是 68 或 262144),建议设为 0 表示完整抓包 |
-w <file> | 将抓包结果保存到文件(可用于 Wireshark 分析) |
-r <file> | 读取之前保存的 .pcap 文件内容 |
-c <count> | 抓指定数量的包后停止 |
-X | 显示数据内容的十六进制 + ASCII |
-XX | 同 -X ,并显示链路层头部 |
-x | 显示数据部分的十六进制 |
-A | 以 ASCII 显示数据内容(适合查看文本协议,如 HTTP) |
-S | 显示绝对序列号(Sequence Number) |
-q | 快速输出(更简洁) |
-t | 不显示时间戳 |
-T <type> | 强制将报文解释为特定类型(如 tcpdump -T rpc ... ) |
-D | 列出所有可用的网络接口 |
-l | 输出行缓冲模式(用于管道或实时查看) |
-U | 抓到包立即刷新输出(配合 -w 使用时更及时) |
-F <file> | 从文件中读取过滤表达式 |
-B <size> | 设置内核抓包缓冲区大小(单位 KB) |
输出内容结构
tcpdump 输出的内容虽然多,却很规律。
21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48
从上面的输出来看,可以总结出:
-
第一列:时分秒毫秒 21:26:49.013621
-
第二列:网络协议 IP
-
第三列:发送方的ip地址+端口号,其中172.20.20.1是 ip,而15605 是端口号
-
第四列:箭头 >, 表示数据流向
-
第五列:接收方的ip地址+端口号,其中 172.20.20.2 是 ip,而5920 是端口号
-
第六列:冒号
-
第七列:数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length,其中 [P.] 表示 PUSH 标志位为 1
Flags 标识符
使用 tcpdump 抓包后,会遇到的 TCP 报文 Flags,有以下几种:
-
[S]
: SYN(开始连接) -
[P]
: PSH(推送数据) -
[F]
: FIN (结束连接) -
[R]
: RST(重置连接) -
[.]
: 没有 Flag (意思是除上面四种类型外的其他情况,有可能是 ACK 也有可能是 URG)
标志 | 名称 | 含义 | 简单理解 |
---|---|---|---|
[S] | SYN | 开始连接 | 你好,我想连你” |
[P] | PSH | 推送数据 | 这是数据,快处理” |
[F] | FIN | 结束连接 | 我说完了,拜拜” |
[R] | RST | 强制断开连接 | 出错了,我不玩了” |
[.] | (ACK) | 数据确认 | 我收到了” |
如果你看到像 [S.]
或 [FP]
这样的组合,说明多个标志位同时被设置了。例如:
-
[S.]
= SYN + ACK(通常是三次握手的第二步) -
[FP]
= FIN + PSH(说完了还推了一把数据)
常规过滤规则
基于IP地址过滤:host
使用 host
就可以指定 host ip 进行过滤
$ tcpdump host 192.168.10.100
数据包的 ip 可以再细分为源ip和目标ip两种
# 根据源ip进行过滤
$ tcpdump -i eth2 src 192.168.10.100
# 根据目标ip进行过滤
$ tcpdump -i eth2 dst 192.168.10.200
基于网段进行过滤:net
若你的ip范围是一个网段,可以直接这样指定
$ tcpdump net 192.168.10.0/24
网段同样可以再细分为源网段和目标网段
# 根据源网段进行过滤
$ tcpdump src net 192.168
# 根据目标网段进行过滤
$ tcpdump dst net 192.168
基于端口进行过滤:port
使用 port
就可以指定特定端口进行过滤
$ tcpdump port 8088
端口同样可以再细分为源端口,目标端口
# 根据源端口进行过滤
$ tcpdump src port 8088
# 根据目标端口进行过滤
$ tcpdump dst port 8088
如果你想要同时指定两个端口你可以这样写
$ tcpdump port 80 or port 8088
但也可以简写成这样
$ tcpdump port 80 or 8088
如果你的想抓取的不再是一两个端口,而是一个范围,一个一个指定就非常麻烦了,此时你可以这样指定一个端口段。
$ tcpdump portrange 8000-8080
$ tcpdump src portrange 8000-8080
$ tcpdump dst portrange 8000-8080
对于一些常见协议的默认端口,我们还可以直接使用协议名,而不用具体的端口号
比如 http == 80,https == 443 等
$ tcpdump tcp port http
基于协议进行过滤:proto
常见的网络协议有:tcp, udp, icmp, http, ip,ipv6 等
若你只想查看 icmp 的包,可以直接这样写
$ tcpdump icmp
protocol 可选值:ip, ip6, arp, rarp, atalk, aarp, decnet, sca, lat, mopdl, moprc, iso, stp, ipx, or netbeui
过滤结果输出到文件
使用 tcpdump 工具抓到包后,往往需要再借助其他的工具进行分析,比如常见的 wireshark 。
而要使用wireshark ,我们得将 tcpdump 抓到的包数据生成到文件中,最后再使用 wireshark 打开它即可。
使用 -w
参数后接一个以 .pcap
后缀命令的文件名,就可以将 tcpdump 抓到的数据保存到文件中。
$ tcpdump icmp -w icmp.pcap
从文件中读取包数据
使用 -w
是写入数据到文件,而使用 -r
是从文件中读取数据。
读取后,我们照样可以使用上述的过滤器语法进行过滤分析。
$ tcpdump icmp -r all.pcap
过滤指定网卡的数据包
-
-i
:指定要过滤的网卡接口,如果要查看所有网卡,可以-i any
过滤特定流向的数据包#
-
-Q
: 选择是入方向还是出方向的数据包,可选项有:in, out, inout,也可以使用 --direction=[direction] 这种写法
tcpdump -Q in # 抓取进入本机的所有网络包
tcpdump -Q out # 抓取从本机发出的所有网络包
tcpdump -Q inout # 抓取进出本机的所有网络包(默认行为)
对输出内容进行控制的参数
-
-D
: 显示所有可用网络接口的列表 -
-e
: 每行的打印输出中将包括数据包的数据链路层头部信息 -
-E
: 揭秘IPSEC数据 -
-L
:列出指定网络接口所支持的数据链路层的类型后退出 -
-Z
:后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。 -
-d
:打印出易读的包匹配码 -
-dd
:以C语言的形式打印出包匹配码. -
-ddd
:以十进制数的形式打印出包匹配码
过滤规则组合
有编程基础的同学,对于下面三个逻辑运算符应该不陌生了吧
-
and:所有的条件都需要满足,也可以表示为
&&
-
or:只要有一个条件满足就可以,也可以表示为
||
-
not:取反,也可以使用
!
举个例子,我想需要抓一个来自10.5.2.3
,发往任意主机的3389端口的包
$ tcpdump src 10.5.2.3 and dst port 3389
当你在使用多个过滤器进行组合时,有可能需要用到括号,而括号在 shell 中是特殊符号,因为你需要使用引号将其包含。例子如下:
$ tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'
而在单个过滤器里,常常会判断一条件是否成立,这时候,就要使用下面两个符号
-
=
:判断二者相等 -
==
:判断二者相等 -
!=
:判断二者不相等
当你使用这两个符号时,tcpdump 还提供了一些关键字的接口来方便我们进行判断,比如
-
if:表示网卡接口名、
-
proc:表示进程名
-
pid:表示进程 id
-
svc:表示 service class
-
dir:表示方向,in 和 out
-
eproc:表示 effective process name
-
epid:表示 effective process ID
比如我现在要过滤来自进程名为 nc
发出的流经 en0 网卡的数据包,或者不流经 en0 的入方向数据包,可以这样子写
$ tcpdump "( if=en0 and proc =nc ) || (if != en0 and dir=in)"
实战应用
提取 HTTP 的 User-Agent
从 HTTP 请求头中提取 HTTP 的 User-Agent:
$ tcpdump -i ens33 -nn -A -s1500 -l | grep "User-Agent:"
通过 egrep
可以同时提取User-Agent 和主机名(或其他头文件):
$ tcpdump -nn -A -s1500 -l | egrep -i 'User-Agent:|Host:'
这个命令的作用是:
实时抓取网络流量,并过滤出包含
User-Agent:
的 HTTP 请求头信息,通常用于查看当前有哪些客户端(浏览器、爬虫等)在访问服务器。
GET /index.html HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xmlUser-Agent: Mozilla/5.0 ...
抓取 HTTP GET 和 POST 请求
抓取 HTTP GET 请求包:
$ tcpdump -i any -nn port 80 -A | grep -A 10 'GET /'
可以抓取 HTTP POST 请求包:
tcpdump -i any -nn port 80 -A | grep -E 'GET|POST'
找出发包数最多的 IP
找出一段时间内发包最多的 IP,或者从一堆报文中找出发包最多的 IP,可以使用下面的命令:
$ tcpdump -i ens33 -nnn -t -c 200 | cut -f 1,2,3,4 -d '.' | sort | uniq -c | sort -nr | head -n 20
-
cut -f 1,2,3,4 -d '.' : 以
.
为分隔符,打印出每行的前四列。即 IP 地址。 -
sort | uniq -c : 排序并计数
-
sort -nr : 按照数值大小逆向排序
抓取 200 个数据包;
提取出涉及的 IP 地址;
统计哪些 IP 出现得最多;
按频率排序,列出前 20 名。
抓取 DNS 请求和响应
DNS 的默认端口是 53,因此可以通过端口进行过滤
$ tcpdump -i any -s0 port 53
切割 pcap 文件
当抓取大量数据并写入文件时,可以自动切割为多个大小相同的文件。
例如,下面的命令表示每 3600 秒创建一个新文件 capture-(hour).pcap
,每个文件大小不超过 200*1000000
字节:
$ tcpdump -w /tmp/capture-%H.pcap -G 3600 -C 200
这些文件的命名为 capture-{1-24}.pcap
,24 小时之后,之前的文件就会被覆盖。
提取 HTTP GET 请求中的密码
从 HTTP GET 请求中提取密码和主机名:
tcpdump -i ens33 -s 0 -A -n -l | egrep -i "GET /|pwd=|passwd=|password=|Host:"
提取 HTTP 请求的 URL
提取 HTTP 请求的主机名和路径:
$ tcpdump -s 0 -v -n -l | egrep -i "GET /|GET /|Host:"
假设需要监控服务器上通过HTTP(默认端口80)或HTTPS(默认端口443)传输的数据包,以便检查是否有异常流量或者进行网络故障排查。
我们将使用 tcpdump
抓取这些特定端口的数据包,并将其保存到文件中以便后续分析。
具体步骤
-
确定网络接口名称
首先,需要知道服务器上使用的网络接口名称。可以使用以下命令查看:
ip link show
或者在某些系统中也可以使用:
ifconfig -a
这将列出所有可用的网络接口。假设主要网络接口名为 ens33
。
-
使用 tcpdump 抓取指定端口的数据包
现在,我们来编写一个 tcpdump
命令,用于捕获目标端口为 80 或 443 的数据包,并将它们保存到一个文件中。以下是具体命令:
sudo tcpdump -i ens33 port 80 or port 443 -w http_https_traffic.pcap
-
-i ens33
:指定监听的网络接口。 -
port 80 or port 443
:设置过滤条件,只捕获目标端口为80或443的数据包。 -
-w http_https_traffic.pcap
:将捕获的数据包写入到http_https_traffic.pcap
文件中。
-
分析捕获的数据包
当觉得已经收集了足够的数据后,可以按 Ctrl+C
停止 tcpdump
。之后,可以使用 Wireshark 打开 .pcap
文件来进行详细分析,或者直接用 tcpdump
来阅读:
tcpdump -r http_https_traffic.pcap
这将读取并显示之前捕获的数据包内容。
如果只想查看而不保存数据包,可以省略 -w
参数。例如,仅在终端打印出HTTP和HTTPS流量的信息:
sudo tcpdump -i ens33 port 80 or port 443
如果想限制捕获的数据包数量,比如只捕获前100个数据包,可以加上 -c 100
参数:
sudo tcpdump -c 100 -i ens33 port 80 or port 443 -w limited_http_https_traffic.pcap
这样做的好处是可以在不影响性能的情况下快速获取必要的信息,特别适用于初步排查问题时使用。
抓取网段
可以使用 tcpdump
的 CIDR 表示法 或 IP 范围 + 子网掩码 来过滤特定网段的数据包。
sudo tcpdump net <网段> mask <子网掩码>
或者更简洁地使用 CIDR 格式:
sudo tcpdump net <网段/CIDR>
假设正在排查一个局域网中的异常通信行为,怀疑是 192.168.1.0/24 网段中的某些主机发起的。
想使用 tcpdump
来捕获所有与该网段相关的流量(包括发送和接收),并保存到文件中用于后续分析。
步骤:
方法一:使用 CIDR 格式
sudo tcpdump net 192.168.1.0/24 -i ens33 -w lan_traffic.pcap
-
net 192.168.1.0/24
:表示匹配源或目的 IP 在该网段的所有数据包。 -
-i ens33
:监听的网卡接口(根据系统修改为 ens33、enp0s3 等)。 -
-w lan_traffic.pcap
:将捕获的数据包保存到文件中。
方法二:使用传统子网掩码格式
sudo tcpdump net 192.168.1.0 mask 255.255.255.0 -i ens33 -w lan_traffic.pcap
可以将指定网段”与其他条件组合起来,实现更精确的抓包。
示例1:只抓取从 192.168.1.0/24 发出的数据包
sudo tcpdump src net 192.168.1.0/24 -i ens33 -w outgoing_from_lan.pcap
示例2:抓取目标地址为 192.168.1.0/24 的数据包
sudo tcpdump dst net 192.168.1.0/24 -i ens33 -w incoming_to_lan.pcap
示例3:抓取 HTTP 流量且属于 192.168.1.0/24 网段的数据包
sudo tcpdump "net 192.168.1.0/24 and port 80" -i ens33 -w http_lan.pcap
抓取主机
可以通过 host
关键字来指定一个具体的 IP 地址,捕获所有与该主机相关的数据包(包括发送和接收)。
基本语法如下:
sudo tcpdump host <IP地址> -i <网卡名>
例如:
sudo tcpdump host 192.168.1.100 -i ens33
这条命令将捕获所有与 192.168.1.100
主机通信的数据包(即源地址或目标地址为该 IP 的数据包)。
怀疑某台服务器(IP 为 192.168.1.100
)正在被异常访问,想使用 tcpdump
抓取该主机的所有进出流量,并保存到文件中用于后续分析。
步骤:
方法一:抓取指定主机所有流量并保存到文件
sudo tcpdump host 192.168.1.100 -i ens33 -w host_192_168_1_100.pcap
-
host 192.168.1.100
:匹配源或目的地址为该主机的所有数据包。 -
-i ens33
:监听的网卡接口(根据系统修改为 ens33、enp0s3 等)。 -
-w host_192_168_1_100.pcap
:将捕获的数据包保存到文件中。
方法二:只抓取从该主机发出的流量(源地址)
sudo tcpdump src host 192.168.1.100 -i ens33 -w outgoing_from_192_168_1_100.pcap
方法三:只抓取发往该主机的流量(目标地址)
sudo tcpdump dst host 192.168.1.100 -i ens33 -w incoming_to_192_168_1_100.pcap
可以将指定主机”与其他条件组合起来,实现更精确的抓包。
示例1:抓取该主机的 HTTP 流量(端口 80)
sudo tcpdump "host 192.168.1.100 and port 80" -i ens33 -w http_host_192_168_1_100.pcap
示例2:抓取该主机的 DNS 查询流量(端口 53)
sudo tcpdump "host 192.168.1.100 and port 53" -i ens33 -w dns_host_192_168_1_100.pcap
示例3:抓取该主机前 100 个数据包后自动停止
sudo tcpdump -c 100 host 192.168.1.100 -i ens33 -w limited_host_traffic.pcap
当觉得已经收集了足够的数据后,可以按 Ctrl+C
停止抓包。
然后可以用以下方式查看捕获的内容:
查看内容(终端显示):
tcpdump -r host_192_168_1_100.pcap
使用 Wireshark 打开:
wireshark host_192_168_1_100.pcap
多条件抓包案例详解
案例1:抓取指定主机 + 指定端口的数据包
sudo tcpdump host 192.168.1.100 and port 80 -i ens33 -w web_192_168_1_100.pcap
-
解释:捕获所有与
192.168.1.100
主机通信,并且端口为80
(HTTP)的数据包。 -
应用场景:排查某台服务器的 HTTP 流量是否正常。
案例2:抓取指定网段访问指定端口的数据包
sudo tcpdump net 192.168.1.0/24 and port 22 -i ens33 -w ssh_from_lan.pcap
-
解释:捕获来自
192.168.1.0/24
网段,并访问22
端口(SSH)的数据包。 -
应用场景:监控局域网内是否有异常 SSH 登录尝试。
案例3:抓取源地址和目标地址都不是本地网段的流量
sudo tcpdump not src net 192.168.1.0/24 and not dst net 192.168.1.0/24 -i ens33
-
解释:排除掉本地网段的所有通信,只看外部到外部”的流量。
-
应用场景:检测是否存在 NAT 穿透或非法代理行为。
案例4:抓取非 DNS 流量(排除 DNS)
sudo tcpdump not port 53 -i ens33 -w no_dns.pcap
-
解释:排除所有 DNS 请求(端口 53),便于分析其他类型的流量。
-
应用场景:减少干扰,专注于非 DNS 类型的问题排查。
案例5:抓取 TCP SYN 包(用于检测扫描行为)
sudo tcpdump 'tcp[13] & 2 != 0' -i ens33 -w syn_packets.pcap
-
解释:TCP 标志位中的 SYN 位为 1 表示连接请求,常用于检测端口扫描行为。
-
更复杂的写法也可以结合 IP 地址或其他字段进一步限定。
案例6:组合多个条件(AND/OR)
sudo tcpdump '(src host 192.168.1.100 or src host 192.168.1.101) and dst port 443' -i ens33 -w https_from_two_hosts.pcap
-
解释:抓取从
192.168.1.100
或192.168.1.101
发出、目标端口为 HTTPS (443) 的流量。 -
应用场景:分析两个客户端对 HTTPS 服务的访问行为。
抓取 TCP 标志位(仅作了解)
tcpdump
提供了灵活的方法来过滤具有特定 TCP 标志的数据包。
可以通过检查 TCP 头部的第 13 字节(即偏移量为 13 的字节)中的标志位来进行过滤。
每个标志位对应一个比特位,因此可以使用按位操作来筛选。
-
抓取所有 SYN 包
要捕获所有设置了 SYN 标志的数据包(通常用于发现开放端口),可以使用以下命令:
sudo tcpdump 'tcp[13] & 2 != 0'
这里的
2
对应于 SYN 标志的位置。 -
抓取所有 RST 包
捕获所有设置了 RST 标志的数据包(常用于拒绝连接):
sudo tcpdump 'tcp[13] & 4 != 0'
4
是 RST 标志的位置。 -
抓取所有 FIN 包
捕获所有设置了 FIN 标志的数据包(用于正常关闭连接):
sudo tcpdump 'tcp[13] & 1 != 0'
1
是 FIN 标志的位置。 -
抓取 SYN-ACK 包
如果想捕获那些既设置了 SYN 又设置了 ACK 标志的数据包(这是对 SYN 请求的正常响应),可以这样做:
sudo tcpdump 'tcp[13] == 18'
在这里,
18
是因为 SYN (2
) 和 ACK (16
) 标志同时设置的结果:2 + 16 = 18
。 -
结合其他条件
例如,如果想只看来自特定 IP 地址的 SYN 包:
sudo tcpdump 'src host 192.168.1.100 and tcp[13] & 2 != 0'
或者保存到文件中以便后续分析:
sudo tcpdump -i ens33 'tcp[13] & 2 != 0' -w syn_packets.pcap
系统进程检测
使用 ps
命令
ps
命令可以列出当前系统上的所有进程。结合一些选项,可以获取更详细的信息。
-
查看所有进程(包括其他用户的进程):
ps aux
-
按 CPU 使用率排序查看前几位的进程:
ps aux --sort=-%cpu | head
使用 top
或 htop
top
和 htop
提供了动态的实时视图,显示了系统中各个进程的资源使用情况。
-
运行
top
:top
-
如果安装了
htop
,可以提供更友好的界面:htop
在这些工具中,注意那些 CPU 或内存使用异常高的进程,以及任何不认识的进程名称。
检查网络连接
可疑进程可能会尝试与外部地址建立连接。使用 netstat
或 ss
可以帮助发现这类活动。
-
使用
netstat
查看所有网络连接及其对应的进程ID(PID):sudo netstat -tulnp
-
或者使用
ss
:sudo ss -tulnp
查找任何看起来不寻常的外部连接,尤其是到未知或可疑IP地址的连接。
分析启动项和服务
有时,恶意软件会添加自己为服务或启动项,以便随系统启动而自动运行。
-
查看所有服务状态:
systemctl list-units --type=service --all
-
检查定时任务(crontab):
crontab -l
同样检查
/etc/cron*
目录下的文件。
文件完整性
文件完整性检查是通过对比文件的 哈希值(如 MD5、SHA256) 或其他特征信息来判断文件内容是否发生变化的过程。
如果发现某个关键系统文件的哈希值与原始值不一致,说明该文件可能已被修改,存在安全隐患。
常用方法和工具
方法1:使用 sha256sum
手动比对(适合少量文件)
-
生成原始哈希值文件列表
sha256sum /bin/ls /bin/cat /etc/passwd > baseline.sha256
这会为这些文件生成一个基准哈希值文件。
-
定期检查文件是否变化
sha256sum -c baseline.sha256
如果输出显示
OK
,表示未变化;如果出现FAILED
,说明文件被修改。
缺点:
-
需要手动维护文件清单。
-
不适合大规模监控。
方法2:使用 AIDE(Advanced Intrusion Detection Environment)
AIDE 是一个开源的基于主机的入侵检测系统(HIDS),通过记录关键系统文件的哈希值,并定期进行比对,来发现是否有文件被篡改。
它非常适合用于检测恶意软件、后门、rootkit 等攻击行为。
安装 AIDE
sudo yum install aide -y
初始化 AIDE 数据库
AIDE 需要一个初始数据库来记录当前系统中关键文件的状态。
-
初始化数据库:
sudo aide --init
这个命令会生成一个新的数据库文件:
/var/lib/aide/aide.db.new
-
将新数据库设置为当前数据库:
sudo cp /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
sudo aide --check
配置 AIDE 的监控规则(可选)
AIDE 的配置文件位于:
/etc/aide.conf
你可以根据需要修改哪些目录或文件要监控。
示例配置说明:
符号 | 含义 | 描述 |
---|---|---|
p | Permissions | 文件权限(如 -rw-r--r-- ) |
i | Inode number | inode 编号(唯一标识文件系统中的文件) |
n | Number of links | 硬链接数量 |
u | User ID (UID) | 文件拥有者的用户 ID |
g | Group ID (GID) | 文件所属组的组 ID |
s | Size | 文件大小(字节数) |
m | Last Modification time | 文件最后修改时间(mtime) |
c | Last Inode Change time | inode 最后更改时间(ctime) |
a | Last Access time | 文件最后访问时间(atime) |
acl | Access Control List | 访问控制列表(扩展权限) |
xattrs | Extended Attributes | 扩展属性(比如 SELinux 标签等) |
selinux | SELinux Context | SELinux 上下文信息(user:role:type) |
# 默认规则(所有属性都监控)
ALL = p+i+n+u+g+s+m+c+acl+xattrs+selinux
# 监控的关键目录
/bin/ ALL
/sbin/ ALL
/usr/bin/ ALL
/usr/sbin/ ALL
/etc/ ALL
# 忽略某些频繁变化的文件
!/var/log/
!/tmp/
!/dev/
!/proc/
!/sys/
!/run/
手动运行一次 AIDE 检查
sudo aide --check
如果没有任何异常,会输出:
Start timestamp: ... and everything looks good.
如果有文件变动,会列出详细的变化信息。
修改了配置文件,需要重新初始化并设置
(修改配置 → 初始化 → 替换数据库 → 检查)
将 AIDE 设置为定时任务自动检查
我们可以使用 cron
每天自动运行一次检查。
-
编辑 root 的 cron 任务:
sudo crontab -e
-
添加以下内容(每天凌晨 3:00 执行检查):
0 3 * * * /usr/sbin/aide --check | mail -s "AIDE Integrity Check Report" your_email@example.com
注意:
你需要先安装并配置好邮件服务(如 postfix 或 sendmail)才能发送邮件。
如果你不希望用邮件通知,也可以将日志保存到文件中。 以下是一些应重点关注的系统路径,建议加入完整性检查范围:
路径 | 说明 |
---|---|
/bin , /sbin , /usr/bin , /usr/sbin | 关键系统命令目录 |
/etc | 配置文件目录,如 passwd, shadow, sshd_config 等 |
/lib , /lib64 , /usr/lib | 系统库文件 |
/tmp , /dev/shm | 临时目录,常被攻击者利用 |
/root , /home/*/.ssh | 用户家目录和 SSH 密钥 |
/var/www/html | Web 目录,容易被挂马 |
模拟测试案例
假设想测试 /etc/passwd
文件是否被篡改:
-
使用
sha256sum
生成初始哈希:sha256sum /etc/passwd > /tmp/passwd.sha256
-
修改文件内容:
sudo echo "test:x:0:0:test:/root:/bin/bash" >> /etc/passwd
-
再次校验:
sha256sum -c /tmp/passwd.sha256
会看到类似输出:
/etc/passwd: FAILED
表示文件已被修改。