应急响应
应急响应概述
Windows入侵排查
Windows日志分析
Linux入侵排查
Linux日志分析
Windows入侵排查【详细版】
Linux入侵排查【详细版】
蚁剑流量分析
冰蝎流量分析
中国菜刀流量分析
Webshell管理工具流量特征
-
+
首页
Linux入侵排查【详细版】
### 1.1 系统信息搜集 #### 1.1.1 系统内核信息 系统信息获取:在命令行输入uname-a,即可知道当前操作系统的内核版本,为下一步应急推论做铺垫。如果存在相关提权漏洞,那么一定是和操作系统内核有关系。 ```bash [root@localhost ~]# uname -a [+] Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@localhost ~]# uname -r [+] 3.10.0-693.el7.x86_64 # 打印内核版本信息 [root@localhost ~]# uname -n [+] localhost.localdomain # 系统主机名字 [root@localhost ~]# uname -m [+] x86_64 # 系统架构 ``` 通过文件或者其它命令也可以查看关于系统的信息 ```bash [root@localhost ~]# cat /proc/version #内核信息 [root@localhost ~]# cat /proc/cpuinfo #CPU信息 [root@localhost ~]# cat /etc/*-release #查看发布信息 [root@localhost ~]# cat /etc/issue #查看发布信息 ``` #### 1.1.2 系统时间确认 在登录到失陷系统的时候,我们需要确认系统的时间,若当前系统的时间和本地时间不匹配,便需要注意之后的系统日志、应用日志等都需要重新计算。EDT美国东部夏令时(UT-4时区),该时区比CST中国标准时间(UT+8时区)晚12小时。 ```bash [root@localhost ~]# date 2020年 07月 27日 星期一 13:32:41 CST [root@localhost ~]# uptime 17:08:13 up 6:21, 1 user, load average: 0.00, 0.01, 0.05 ``` ### 1.2 进程分析 #### 1.2.1 进程前置知识 恶意木马执行后,必然出现一个恶意进程。恶意进程可以通过这四个特征判断: 1. 进程对cpu,内存的占用异常高。 2. 进程运行时间,开始时间,差异化明显 3. 进程路径,使用命令参数异常 4. 多数病毒会替换系统命令 进程信息获取 ```bash #快速查看进程,并查看cpu的占用率 [root@localhost ~]# top -c #查看进程的关联 [root@localhost ~]# ps -aux #查看和某个进程PID,相关联的文件 [root@localhost ~]# cat /proc/<PID>/maps #只管展现子进程和父进程之间的关系 [root@localhost ~]# pstree #输出某个进程所打开的文件,默认情况下Centos7不会安装该命令 [root@localhost ~]# lsof -p <pid> ```  #### 1.2.2 进程隐藏手法:偷梁换柱 进程隐藏是恶意软件隐藏自身痕迹逃避系统管理人员发现的常用伎俩之一,当然,安全防护人员有时候也会使用到,比如隐藏蜜罐中的监控进程而不被入侵者觉察等。标题中所指的偷梁换柱指的是修改top、ps以及lsof这一类命令的输出结果,能够输出原本内容的同时,过滤掉恶意进程的内容。 实验思路:以top命令为例,当执行某一个恶意脚本后,该脚步会讲原本正常的top命令移动到一个另一个隐蔽的路径下,然后创建一个和top命令同名的bash脚本在相同的路径下。其内容就类似以下部分 ```bash #!/bin/bash /root/python_to_ping/top | grep -v python # 整体的构成:命令被移动的路径 | 通过grep -v筛选掉恶意的进程 # 注意需要赋予该top脚本可执行的权限。 ``` 排查思路:在后续的命令排查方法中,我们会讲到可以查看命令的修改、更改时间来判断该命令是否被更改,还可以对比可疑命令和正常命令的MD5值是否相同。 #### 1.2.3 进程隐藏手法:HooK系统调用型 在讲什么是HooK之前,我们需要讲明PS、Top这一类进程查看工具的工作原理。我们知道/proc是一个虚拟文件系统,是VFS的一个实现形式,/proc中包含了内核信息,硬件信息,进程信息等,ps等工具就是通过分析/proc文件系统中进程相关目录的信息获取进程信息汇总。 PS的工作流程:PS首先会调用openat 系统函数获取/proc目录的文件句柄,然后调用系统函数 getdents 递归获取/proc目录下所有文件信息(包括子目录),然后开始open函数打开/proc/进程pid/stat,/proc/进程pid/status, /proc/进程pid/cmdline 文件开始获取进程信息,然后打印给你看。 HooK的原理:HooK系统调用型的进程隐藏方式都是通过拦截或者迷惑ps等工具从/proc获取分析结果的过程,而不是针对/proc/文件系统生成本身。比起劫持修改getdents之类的函数,最简单的方法就是利用环境变量LD_PRELOAD或者配置ld.so.preload文件以使恶意的动态库先于系统标准库加载,最终实现对特定进程的隐藏。 ```bash # 下载的恶意的动态库文件 $ git clone https://github.com/gianlucaborello/libprocesshider.git 正克隆到 'libprocesshider'... remote: Enumerating objects: 30, done. remote: Total 30 (delta 0), reused 0 (delta 0), pack-reused 30 Unpacking objects: 100% (30/30), done. $ cd libprocesshider/ $ ls evil_script.py Makefile processhider.c README.md # 编译动态库文件,注意操作系统需要拥有gcc的编译环境 $ make gcc -Wall -fPIC -shared -o libprocesshider.so processhider.c -ldl $ ls evil_script.py libprocesshider.so Makefile processhider.c README.md # 移动文件libprocesshider.so到/usr/local/lib文件夹下 $ mv libprocesshider.so /usr/local/lib # 把它加载到全局动态连接库 $ echo /usr/local/lib/libprocesshider.so >> /etc/ld.so.preload ``` 在正常情况下的ps的显示内容 ```bash # 创建一个用于测试的attack.py $ vim attack.py #!/bin/python import os os.system("ping www.baidu.com") # 执行这个attack.py文件 $ python attack.py PING www.a.shifen.com (112.80.248.76) 56(84) bytes of data. 64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=1 ttl=128 time=20.1 ms 64 bytes from 112.80.248.76 (112.80.248.76): icmp_seq=2 ttl=128 time=27.6 ms # 在另一个控制台下查看相应的进程 $ ps -ef | grep "ping\|python" root 9061 7328 0 09:30 pts/0 00:00:00 ping www.baidu.com root 9241 7328 0 10:23 pts/0 00:00:00 python attack.py ``` 以上的内容中如果说我们要设置隐藏自己的进程,就需要在编译器前修改processhider.c文件内容。 ```bash # 我们只需要修改processhider.c中的下面这部分内容。 static const char* process_to_filter = "python"; # 在这里可以设置隐藏的进程,注意这里面我写的是python,因为我的attack.py脚步通过python attack.py # 的方式执行。如果说赋予attack.py可执行的权限,并且直接通过./attack.py的方式执行,则我们可以将上面 # 的命令修改为:static const char* process_to_filter = "attack.py"; # 在修改完以上的内容后重复编译-> 移动 -> 链接 # 如果在某些情况下编译程序不通过则: # 1.删除最后两行中的其中一行 DECLARE_READDIR(dirent64, readdir64); DECLARE_READDIR(dirent, readdir); # 2. 添加环境变量 vi /etc/profile export LD_PRELOAD=/usr/local/lib/libprocesshider.so ``` 此后一个命令行下执行attack.py脚本,一个命令行下通过ps查看。 ```bash # 输出的结果中没有含有运行的测试脚本 [root@localhost libprocesshider]# ps -ef | grep "attack.py\|ping" root 9061 7328 0 09:30 pts/0 00:00:00 ping www.baidu.com root 9349 9348 0 10:40 pts/0 00:00:00 ping www.baidu.com ``` 排查思路:上文也提到这种HooK系统调用函数的进程隐藏方式只是hook了ps等工具从/proc 获取信息的过程,而没有修改/proc/文件系统本身,其实相关进程信息的内核映射还在/proc中。可以通过自动化工具一一检索/proc目录下的文件夹。 - 检查LD_PRELOAD环境变量是否存在异常 - 检查ld.so.preload等配置文件是否有异常 - 通过python小工具,直接读取/proc中的内容。对比ps的内容,若存在出入则可能进程被劫持。 - 安装rthunter进程查杀[📎rkhunter-1.4.6.tar.gz](https://www.yuque.com/attachments/yuque/0/2021/gz/1543119/1611134301696-e67061b3-d59f-44d8-a5c1-fb59cd039e59.gz) #### 1.2.4 进程隐藏手法:伪造进程名 在攻击脚本编写方面,尽量取一些具有迷惑性的名字。也可以通过exec的方式重命名进程名。 ```bash $ exec -a bash python ./attack.py # exec -a 更换后的进程名 原来的执行命令 [root@localhost ~]# ps -ef | grep bash root 93508 93492 0 14:06 pts/1 00:00:00 bash attack.py root 93565 93549 0 14:07 pts/2 00:00:00 -bash ``` 排查思路:如果说本身的恶意进程不需要附带命令而直接执行,则非常具有迷惑性。我们可以判断进程所附带的命令来判断可以进程,或者查看/proc目录下的文件夹,exe所指向的真实文件位置。  #### 1.2.5 进程隐藏手法:挂载隐藏 利用mount —bind 将另外一个目录挂载覆盖至/proc/目录下指定进程ID的目录,我们知道ps、top等工具会读取/proc目录下获取进程信息,如果将进程ID的目录信息覆盖,则原来的进程信息将从ps的输出结果中隐匿。 ```bash $ ps -ef | grep attack root 94602 94572 0 14:27 pts/1 00:00:00 /bin/python ./attack.py $ setenforce 0 $ mount -o bind /root/empty/ /proc/94602/ $ ps -ef | grep attack # 注意我们需要将setenforce关闭,然后再使用挂载命令进行挂载。挂载完毕之后该进程的信息就被隐藏。 ``` 排查思路:通过命令可以对挂载记录进行查看,同时使用umount命令进行卸载 ```bash # 查看是否有利用mount —bind 将其他目录或文件挂载至/proc下的进程目录的行为 $ cat /proc/$$/mountinfo 251 19 253:0 /root/empty /proc/94602 rw,relatime shared:1 - xfs /dev/mapper/centos-root rw,seclabel,attr2,inode64,noquota $ cat /proc/mounts /dev/mapper/centos-root /proc/94602 xfs rw,seclabel,relatime,attr2,inode64,noquota 0 0 # 使用umount命令进行卸载 $ umount /proc/94602/ $ ps -ef | grep attack root 94602 94572 0 14:27 pts/1 00:00:00 /bin/python ./attack.py ``` ### 1.3 网络及端口分析 #### 1.3.1 网络信息排查 ```bash [root@localhost ~]# ifconfig #查看网络接口的配置信息 [root@localhost ~]# netstat -pantu #查看当前端口开放情况 [root@localhost ~]# netstat -an | grep tcp |awk '{print $5}' [+] 192.168.222.1:8419 [+] 192.168.222.1:8420 #格式化输出netstat的tcp输出,只输出第五个参数的内容,即目标IP。 [root@localhost ~]# netstat -an |grep syn |awk '{print $5}' #格式化输出netstat的syn输出,只输出第五个参数的内容,即目标IP。 ``` #### 1.3.2 风险端口列表 | 端口 | 服务 | 渗透测试要点 | | ------------------------------------ | ------------------------------------- | ------------------------------------------------------------ | | tcp 20,21 | FTP(文件传输协议) | 允许匿名的上传下载、爆破、嗅探、win 提权、远程执行 (proftpd 1.3.5)、各类后门 (proftpd,vsftp 2.3.4) | | tcp 22 | SSH(安全外壳协议) | 可根据已搜集到的信息尝试爆破,v1 版本可中间人,ssh 隧道及内网代理转发、文件传输等 | | tcp 23 | Telnet(远程终端协议) | 爆破、嗅探,一般常用于路由、交换登陆,可尝试弱口令 | | tcp 25 | SMTP(简单邮件传输协议) | 邮件伪造,vrfy/expn 查询邮件用户信息,可使用 smtp-user-enum 工具来自动跑 | | tcp/udp 53 | DNS(域名系统) | 允许区域传送、dns 劫持、缓存投毒、欺骗以及各种基于 dns 隧道的远控 | | tcp/udp 69 | TFTP(简单文件传送协议) | 尝试下载目标及其的各类重要配置文件 | | tcp 80-89、443、8440-8450、8080-8089 | 各种常用的 Web 服务 | 可尝试经典的 topn、vpn、owa、webmail、目标 oa、各类 Java 控制台、各类服务器 Web 管理面板、各类 Web 中间件漏洞利用、各类 Web 框架漏洞利用等 | | tcp 110 | POP3(邮局协议版本 3) | 可尝试爆破、嗅探 | | tcp 111,2049 | NFS(网络文件系统) | 权限配置不当 | | tcp 137,139,445 | SMB(NETBIOS 协议) | 可尝试爆破以及 smb 自身的各种远程执行类漏洞利用(如 ms08-067,ms17-010)、嗅探等 | | tcp 143 | IMAP(邮件访问协议) | 可尝试爆破 | | udp 161 | SNMP(简单网络管理协议) | 爆破默认团队字符串,搜集目标内网信息 | | tcp 389 | LDAP(轻量目录访问协议) | ldap 注入、允许匿名访问、弱口令 | | tcp 512,513,514 | Linux rexec(远程登录) | 可爆破、rlogin 登陆 | | tcp 873 | Rsync(数据镜像备份工具) | 匿名访问、文件上传 | | tcp 1194 | OpenVPN(虚拟专用通道) | 想办法钓 VPN 账号,进内网 | | tcp 1352 | Lotus(Lotus 软件) | 弱口令、信息泄漏、爆破 | | tcp 1433 | SQL Server(数据库管理系统) | 注入、提权、sa 弱口令、爆破 | | tcp 1521 | Oracle(甲骨文数据库) | tns 爆破、注入、弹 shell | | tcp 1500 | ISPmanager(主机控制面板) | 弱口令 | | tcp 1723 | PPTP(点对点隧道协议) | 爆破、想办法钓 VPN 账号,进内网 | | tcp 2082,2083 | cPanel(虚拟机控制系统) | 弱口令 | | tcp 2181 | ZooKeeper(分布式系统的可靠协调系统) | 未授权访问 | | tcp 2601,2604 | Zebra(zebra 路由) | 默认密码 zerbra | | tcp 3128 | Squid(代理缓存服务器) | 弱口令 | | tcp 3312,3311 | kangle(web 服务器) | 弱口令 | | tcp 3306 | MySQL(数据库) | 注入、提权、爆破 | | tcp 3389 | Windows rdp(桌面协议) | shift 后门 [需要 03 以下的系统]、爆破、ms12-020 | | tcp 3690 | SVN(开放源代码的版本控制系统) | svn 泄露、未授权访问 | | tcp 4848 | GlassFish(应用服务器) | 弱口令 | | tcp 5000 | Sybase/DB2(数据库) | 爆破、注入 | | tcp 5432 | PostgreSQL(数据库) | 爆破、注入、弱口令 | | tcp 5900、5901,5902 | VNC(虚拟网络控制台,远控) | 弱口令爆破 | | tcp 5984 | CouchDB(数据库) | 未授权导致的任意指令执行 | | tcp 6379 | Redis(数据库) | 可尝试未授权访问、弱口令爆破 | | tcp 7001,7002 | WebLogic(WEB 应用系统) | Java 反序列化、弱口令 | | tcp 7778 | Kloxo(虚拟主机管理系统) | 主机面板登录 | | tcp 8000 | Ajenti(Linux 服务器管理面板) | 弱口令 | | tcp 8443 | Plesk(虚拟主机管理面板) | 弱口令 | | tcp 8069 | Zabbix(系统网络监视) | 远程执行、SQL 注入 | | tcp 8080-8089 | Jenkins,JBoss(应用服务器) | 反序列化、控制台弱口令 | | tcp 9080-9081、9090 | WebSphere(应用服务器) | Java 反序列化 / 弱口令 | | tcp 9200,9300 | ElasticSearch(Lucene 的搜索服务器) | 远程执行 | | tcp 11211 | Memcached(缓存系统) | 未授权访问 | | tcp 27017,27018 | MongoDB(数据库) | 爆破、未授权访问 | | tcp 50070,50030 | Hadoop(分布式文件系统) | 默认端口未授权访问 | ### 1.4 启动项分析 #### 1.4.1 服务信息排查 在应急响应的过程中,我们必须明白service以及systemctl对应启动脚本的关系。 CentOS6中服务Service启动脚本都放在/etc/rc.d/init.d/下,/etc/init.d/是/etc/rc.d/init.d/的软链接;但是在Centos7中Service命令会被重定向到Systemctl的脚本中,/etc/init.d以及/etc/rc.d/init.d是开机启动脚本的存放位置,需要通过chkconfig命令来添加,不过这个内容是后话。 ```bash [root@localhost ~]# ll /etc/init.d/ -rw-r--r--. 1 root root 17500 5月 3 2017 functions -rwxr-xr-x. 1 root root 4334 5月 3 2017 netconsole -rwxr-xr-x. 1 root root 7293 5月 3 2017 network -rw-r--r--. 1 root root 1160 5月 12 23:45 README [root@localhost ~]# service sshd start Redirecting to /bin/systemctl start sshd.service #Centos7可以发现init.d下没有sshd的服务,使用service命令被重定向到了systemctl命令中。 ``` CentOS7的服务systemctl脚本存放在:/usr/lib/systemd/下,并且有着user和system的区分,就像在windows中有着系统启动以及用户登录之分。像需要开机不登陆就能运行的程序,即:/usr/lib/systemd/system目录下。 ```bash [root@localhost ~]# ll /usr/lib/systemd/system | grep sshd -rw-r--r--. 1 root root 313 8月 7 2017 sshd-keygen.service -rw-r--r--. 1 root root 373 7月 24 16:34 sshd.service -rw-r--r--. 1 root root 260 8月 7 2017 sshd@.service -rw-r--r--. 1 root root 181 8月 7 2017 sshd.socket #例如刚刚的sshd是系统启动就会运行的服务,在/usr/lib/systemd/system下就可以找到。 ``` Linux 7种运行级别:runlevel查看当前运行级别;init[0~6]切换运行级别 - 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动 - 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆 - 运行级别2:多用户状态(没有NFS) - 运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式 - 运行级别4:系统未使用,保留 - 运行级别5:X11控制台,登陆后进入图形GUI模式 - 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动 Linux系统" /etc/rc.d/rc[0~6].d "的7种运行级别启动脚本文件夹,这些文件夹分别包含每个运行等级对应的init脚本。 在实际使用中,它们一般通过符号链接到/etc/init.d文件夹下的实际文件。S(start) 、 K(kill) 或 D(disable) ```bash [root@localhost ~]# ll /etc/rc.d/rc1.d/ lrwxrwxrwx. 1 root root 20 5月 20 20:25 K50netconsole -> ../init.d/netconsole lrwxrwxrwx. 1 root root 17 5月 20 20:25 K90network -> ../init.d/network ``` 自己创建" .service "文件然后配置开机启动," .service "文件分为三个部分[Unit]、[Service]和[Install] multi-user.target.wants该目录下存放着开机启动的服务软连接,是一个排查点。 ```bash [root@localhost ~]# vim attack.service ---------------------------------------------------------------------------------------- [Unit] Description=attack test # 描述部分 After=network.target [Service] User=root Type=simple Type=oneshot RemainAfterExit=yes ExecStart=/root/linux.elf ExecStop=/bin/kill -s HUP $MIANPID ExecReload=/bin/kill -s QUIT $MAINPID # Type启动类型为立即启动,ExecStart启动命令[启动后门文件],ExecStop停止命令,ExecReload重启命令 [Install] WanteBy=multi-user.target # 多用户使用 ##更多选项可以见 https://www.jb51.net/article/157144.htm ---------------------------------------------------------------------------------------- [root@localhost ~]# mv attack.service /usr/lib/systemd/system/attack.service [root@localhost ~]# systemctl daemon-reload # 重新加载所有服务 [root@localhost ~]# systemctl start attack.service # 开启服务启动后门脚本 [root@localhost ~]# systemctl enable attack # 将一个服务设置为开机启动 [root@localhost ~]# systemctl is-enabled attack.service # 检查一个服务是否存在开机启动,若返回的值是enabled则表明开机启动,若返回的值为static则表示需要手动启动 ##### # 如果说使用enable命令没有办法创建开机自启,则手动在以下目录中添加服务的软连接 [root@localhost ~]# ln -s '/usr/lib/systemd/system/attack.service' '/usr/lib/systemd/system/multi-user.target.wants/attack.service' ##### [root@localhost ~]# systemctl list-unit-files | grep enable # 通过Systemctl查看所有开启的服务 ``` #### 1.4.2 启动脚本排查 > 排查方向一:rc.local CentOS7中启动脚本命令放在了" /etc/rc.d "目录下的" rc.local "文件中,该脚本在正常情况下是没有可执行权限的[644],在这种情况下若向文件中添加启动命令也不会执行。那么若黑客对失陷的CentOS服务器配置了脚本开机启动,则该文件的权限为[755]。 ```bash [root@localhost rc.d]# chmod +x rc.local [root@localhost rc.d]# ll -rwxr-xr-x. 1 root root 495 7月 24 17:16 rc.local [root@localhost ~]# cat /etc/rc.d/rc.local /root/linux.elf #以上例子,若该脚本中含有elf格式的后门文件则会在系统启动时运行。 ``` > 排查方向二:chkconfig 通过chkconfig的方式添加" .sh "启动脚本,chkconfig主要包括5个原始功能:为系统管理增加新的服务、为系统管理移除服务、列出单签服务的启动信息、改变服务的启动信息和检查特殊服务的启动状态。当单独运行chkconfig命令而不加任何参数时,他将显示服务的使用信息。 - --add:开启指定的服务程序 - --del:关闭指定的服务程序 - --list:列出chkconfig所知道的所有服务 - --level \<number>:设置服务程序的等级代号,它是一串0~7的数字,如“-level35”代表指定运行等级3和5 - --help:显示帮助信息 - version:显示版本信息 ```bash [root@localhost ~]# vim /etc/rc.d/init.d/linux_ln.sh ------------------------------------- #!/bin/sh #chkconfig:2345 10 90 #decription:backdoor /root/linux.elf ------------------------------------- Explanation: #chkconfig:[2345]设置该脚本的启动级别,[10]为启动优先级,[90]为关闭优先级,[1~100]越小越优 #decription:描述信息 #最后就是需要执行的命令 [root@localhost ~]# cd /etc/rc.d/init.d/ [root@localhost init.d]# chkconfig --add linux_ln.sh [root@localhost init.d]# chkconfig --level 2 linux_ln.sh on ###注意启动脚本我们需要给定可执行权限,包括对应的恶意脚本### #可以通过指定级别的方式,打开或者关闭特定级别下的脚本 [root@localhost ~]# chkconfig --list linux_ln.sh 0:关 1:关 2:开 3:开 4:开 5:开 6:关 [root@localhost ~]# ll /etc/init.d/ -rwxrwxrwx. 1 root root 69 7月 27 10:42 linux_ln.sh [root@localhost ~]# ll /etc/rc.d/rc3.d/ lrwxrwxrwx. 1 root root 21 7月 27 11:27 S10linux_ln.sh -> ../init.d/linux_ln.sh #我们可以看到相对应的目录以及级别下都会出现我们刚刚创建的脚本文件软连接。 ``` #### 1.4.3 计划任务排查 crond 是linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。 ```bash [root@localhost tmp]# systemctl stop crond.service [root@localhost tmp]# systemctl start crond.service [root@localhost tmp]# systemctl enable crond.service [root@localhost tmp]# systemctl reload crond.service # 停止、启动、开机自启、重新载入crond服务 [root@localhost ~]# crontab -u attack -e # 编辑attack用户的计划任务,格式如下: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed # Crontab案例详见:https://www.cnblogs.com/jierong12/p/8384964.html [root@localhost ~]# vim /etc/crontab #也可以通过直接编辑crontab文件的方式来创建 [root@localhost ~]# crontab -u attack -l [+] */3 * * * * ls >> /tmp/2020test # 查看attack用户下的计划任务 [root@localhost ~]# crontab -u attack -r # 删除attack用户的计划任务 ``` 快速查看所有用户的计划任务 ```bash [root@localhost ~]# cat /etc/passwd | cut -f 1 -d : |xargs -I {} crontab -l -u {} no crontab for root no crontab for bin no crontab for daemon no crontab for adm no crontab for lp no crontab for sync no crontab for shutdown no crontab for halt no crontab for mail no crontab for operator no crontab for games no crontab for ftp no crontab for nobody no crontab for systemd-network no crontab for dbus no crontab for polkitd no crontab for postfix no crontab for sshd no crontab for chrony no crontab for mysql no crontab for apache ``` ### 1.5 命令替换检查 #### 1.5.1 文件修改检查 当在检查linux 服务器的时候需要用stat 或者 ls 进行确认服务器本身的命令没有被替换掉(ps命令和netstat命令),看modify 改变时间是否和事发时间是否存在关联性,那么一般来讲" /bin "下面的命令文件mtime通常不会是最信的。 案例:https://blog.csdn.net/feloxx/article/details/49273997 - 当读取文件时,access time改变,而modify,change time不会改变。 - 当修改文件时,access, modify,change time都会跟着改变。 - 当修改属性时,change time改变,而access,modify time不变。 - more、less、cat.、nl、tail、 tac等命令会更改atime。 - Is、stat命令不会修改文件的atime。 - 修改时间,修改时间是文件内容最后一次被修改时间。比如: vi后保存文件。 - 状态改动时间,是该文件的i节点最后一次被修改的时间,所谓的i节点说白了就是文件信息。 - 通过chmod. chown修改文件属性,会更新ctime。 touch则会更改atime,ctime,mtime。 命令路径 - bin:bin为binary的简写主要放置一些系统的必备执行命令 - /usr/bin:主要放置一些应用软体工具的必备执行命令 - /sbin:主要放置一些系统管理的必备命令 - /usr/sbin:放置一些网路管理的必备命令 ```bash [root@localhost ~]# stat linux.elf 文件:"linux.elf" 大小:250 块:8 IO 块:4096 普通文件 设备:fd00h/64768d Inode:67144925 硬链接:1 权限:(0777/-rwxrwxrwx) Uid:( 0/ root) Gid:( 0/ root) 环境:unconfined_u:object_r:admin_home_t:s0 最近访问(atime):2020-07-27 10:19:57.406590550 +0800 最近更改(mtime):2020-07-27 09:59:38.585130033 +0800 最近改动(ctime):2020-07-27 10:15:25.427789695 +0800 创建时间:- #stat命令的详细使用方式可以详见:https://www.cnblogs.com/machangwei-8/p/10350895.html ---------------------------------------------------------------------- [root@localhost ~]# ls -l linux.elf -rwxrwxrwx. 1 root root 250 7月 27 09:59 linux.elf #最后修改时间,mtime(modify time) [root@localhost ~]# ls -lc linux.elf -rwxrwxrwx. 1 root root 250 7月 27 10:15 linux.elf #最后更改时间,ctime(change time) [root@localhost ~]# ls -lu linux.elf -rwxrwxrwx. 1 root root 250 7月 27 10:19 linux.elf #最后访问时间,atime(access time) [root@localhost ~]# find /sbin/ -mtime 0 [root@localhost ~]# find /bin/ -mtime 0 #通过find命令查看一天内修改的命令文件,-1为一小时以内修改的文件,+1为一小时之前修改的文件。 ``` 如果不能确定该命令是否被替换,可对该文件进行md5 对比校验,找一台相同版本的Linux 系统,对比md5 值,若md5 值不一致,那么该命令则已经被替换了,需要我们自行传新的干净的命令文件去相关出事服务器进行排查。 ```bash [root@localhost ~]# md5sum /bin/ps [+] 8f71c85b9cc1809af7e7612c6144c527 /bin/ps ``` 文件保护检查 ```bash $ chattr +i /etc/passwd # 若设置了该参数,则用户将无法通过命令创建用户 a:让文件或目录仅供附加用途。 b:不更新文件或目录的最后存取时间。 c:将文件或目录压缩后存放。 d:将文件或目录排除在倾倒操作之外。 i:不得任意更动文件或目录。 s:保密性删除文件或目录。 S:即时更新文件或目录。 u:预防意外删除。 $ lsattr /etc/passwd # 恢复文件 $ chattr +a /var/log/messages # 让某个文件只能往里面追加数据,但不能删除,适用于各种日志文件 ``` 文件修改时间检查 当我们的linux操作系统被恶意入侵的时候,攻击者往往会在一些重要的目录下修改部分文件或者创建文件,就例如开机启动项、启动脚本等。那么如果需要快速的查找特定时间内被修改的文件,则可以通过以下几种方法来进行。 ```bash #第一种方法: $find -type f -mtime -1 # 通过指定查找时间的种类[mtime、atime、ctime]并加上时间参数即可以查找固定时间内被修改或创建的文件 # -1表示24小时之内的时间范围; # 1表示24小时外48小时内的时间范围; # +1表示48之外的时间范围。 #第二种方法: $ find / -type f -newermt '2020-08-17 00:00' -a -not -newermt '2020-08-18 23:59' # 通过-newermt参数来指定查找时间的范围,通过-a -not来连接两个时间。mt指的是mtime,也可以是ct和at。 ``` SUID可疑文件或命令排查 SUID:当你运行一个文件的时候,会打开一个进程,那么这个进程的属主为发起者。当运行一个带有SUID的二进制文件时,那么这个进程的属主为文件的创建者。但是SUID只作用在二进制程序文件中(如作用在普通文件中没有任何意义)。那么一般来讲我们所使用的命令属于二进制文件,若某个命令被赋予了SUID权限,则任意用户在使用该命令的时候都会以该命令创建者运行,一般来讲就是ROOT权限。 ```bash [attack@localhost ~]$ ll [+] -rwxr-xr-x. 1 root root 54080 7月 29 14:18 cat [+] ----------. 1 root root 18 7月 29 14:25 test [attack@localhost ~]$ ./cat test [+] ./cat: test: 权限不够 # 以上使用cat命令查看test文件,该cat的运行者为attack,故权限不足。 # 对于"----------"的文件只有root可以查看 [root@localhost attack]# chmod u+s cat [root@localhost attack]# ll [+] -rwsr-xr-x. 1 root root 54080 7月 29 14:18 cat [attack@localhost ~]$ ./cat test this is suid test # 此时通过" chmod u+s "给cat命令添加SUID权限,则虽然是attack用户中进行操作,但是运行者为root,故拥有权限。 [root@localhost attack]# find / -perm -004000 -f # 通过find命令查看所有s权限的可执行文件 ``` #### 1.5.2 Find命令检查绕过 find命令检索的是文件的mtime或者ctime,那么我们只要将时间修改为一个很久之前或者文件原来的时间点,那么就可以轻松的绕过find命令的检索。 ```txt [root@localhost ~]# stat attack.sh File: ‘attack.sh’ Access: 2021-03-15 14:34:32.614734195 +0800 Modify: 2021-03-15 14:34:32.614734195 +0800 Change: 2021-03-15 14:34:38.358908431 +0800 # touch -r命令可以将一个文件的时间信息赋值给另一个文件 # 但是需要注意的是Change时间不会被更改 [root@localhost ~]# touch -r /bin/ps ps psed psfaddtable psfgettable psfstriptable psfxtable pstruct [root@localhost ~]# touch -r /bin/ps attack.sh [root@localhost ~]# stat attack.sh File: ‘attack.sh’ Access: 2021-03-12 10:40:54.041630451 +0800 Modify: 2017-08-04 19:12:27.000000000 +0800 Change: 2021-03-15 14:35:01.533862615 +0800 # touch -a 表示只修改一个文件的访问时间。 # touch -m 表示只修改一个文件的修改时间。 # touch -t 表示用[[CC]YY]MMDDhhmm[.ss]这种时间格式来指定时间属性的修改值 # touch -c 如果文件不存在则不修改文件 [root@localhost ~]# touch -at 202111111112.59 attack.sh [root@localhost ~]# stat attack.sh File: ‘attack.sh’ Access: 2021-11-11 11:12:59.000000000 +0800 Modify: 2017-08-04 19:12:27.000000000 +0800 Change: 2021-03-15 14:47:47.949361407 +0800 # touch -d 以字符串的形式修改时间 [root@localhost ~]# touch -d "20121111 18:11:11" attack.sh [root@localhost ~]# stat attack.sh File: ‘attack.sh’ Access: 2012-11-11 18:11:11.000000000 +0800 Modify: 2012-11-11 18:11:11.000000000 +0800 Change: 2021-03-15 14:50:30.612867023 +0800 #################NP Date################# date -s 02/03/1999 >> DeepMountains.exe # 可以直接修改MT和CT ``` ### 1.6 可疑用户排查 #### 1.6.1 当前登录用户 " w "命令是显示系统中正在登录的用户信息的命令,这个命令查看的痕迹日志是 " /var/run/utmp "。 ```bash [root@localhost bin]# w 09:21:59 up 22:35, 1 user, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.222.1 Mon10 1:43 0.34s 0.34s -bash # " up 22:33 " 表示系统运行时间 # " lOGIN@ " 登录时间 # " IDLE " 用户闲置时间 # " JCPU " 所有进程的占用CPU时间 # " PCUP " 当前进程占用CPU的时间 # " WHAT " 当前用户执行的进程和选项 [root@localhost bin]# who root pts/0 2020-07-27 10:48 (192.168.222.1) # " who " 查看当前登录用户、连接方式、登录时间 [root@localhost bin]# users root # " users " 查看当前连接用户的用户名 [root@localhost bin]# uptime 09:24:10 up 22:37, 1 user, load average: 0.00, 0.01, 0.05 # " uptime " 查看登陆多久、多少用户,负载 ``` #### 1.6.2 异常用户排查 用户信息文件:/etc/passwd,利用/etc/passwd可以查看当前系统中存在的所有用户,排查是否有异常新建用户、用户弱口令、是否拥有shell。需要注意/etc/passwd默认权限为644,其最小权限为444。 ```bash [root@localhost ~]# cat /etc/passwd |grep root [+] root:x:0:0:root:/root:/bin/bash # account:password:UID:GID:GECOS:directory:shell [root@localhost ~]# awk -F: '$3==0{print $1}' /etc/passwd [+] root # 查询所有uid 为0的特权用户 ``` 红队攻击命令:创建超级用户 ```bash useradd attack;echo 'attack:123456'|chpasswd #chpasswd更改用户的密码必须是系统中存在的用户,所以首先需要添加该用户 #chpasswd < user.pass可以批量更改用户密码 useradd -p "$(openssl passwd 123456)" guest #创建guest用户并设置通过openssl命令加密的密码123456,这个密码在shadows里查看的时候是显示加密的 useradd -p "$(openssl passwd 123456)" -u 0 -o -g root -G root -d /usr/bin/guest guest #创建guest用户并设置UID为0,-o表示允许重复的UID,-g表示主组的名称,-G表示附加组列表,-d设置用户的主目录 #基本组:如果没有指定用户组,创建用户的时候系统会默认同时创建一个和这个用户名同名的组,这个组就是基本组,不可以把用户从基本组中删除。在创建文件时,文件的所属组就是用户的基本组。 #附加组:除了基本组之外,用户所在的其他组,都是附加组。用户是可以从附加组中被删除的。 #用户不管在基本组中还是附加组中,就会拥有该组的权限。一个用户可以属于多个附加组,但有且只能有一个基本组。 [*] 普通用户添加root权限 echo "guest:x:0:0::/:/bin/sh" >> /etc/passwd [*] 若要删除UID=0的用户则讲UID修改成正常用户的UID ``` 蓝队防守命令:删除或禁用用户 ```bash usermod -L user # 禁用帐号,帐号无法登录,/etc/shadow第二栏为!开头 userdel user # 删除user用户 userdel -r user # 将删除user用户,并且将/home目录下的user目录一并删除 ``` 密码文件:/etc/shadow,需要注意/etc/shadow默认权限为600,最小权限为400。 ```bash [root@localhost ~]# cat /etc/shadow |grep root [+] root:$6$Yt8rp8fmHYrLl2dJ$ziIjeEzcGk3K33AuSAAWQxBftN7iO8H38UvWE9QBh6tETOUtzBXSfWL6mU/Z6eXWobrgYmjaX/u/w3LXfHbt9/::0:99999:7::: # 用户名:加密密码:密码最后一次修改日期:两次密码的修改时间间隔:密码有效期:密码修改到期到的警告天数:密码过期之后的宽限天数:账号失效时间:保留 [root@localhost ~]# awk '/\$1|\$6/{print $1}' /etc/shadow [+] root:$6$Yt8rp8fmHYrLl2dJ$ziIjeEzcGk3K33AuSAAWQxBftN7iO8H38UvWE9QBh6tETOUtzBXSfWL6mU/Z6eXWobrgYmjaX/u/w3LXfHbt9/::0:99999:7::: [+] attack:$6$xTCPrKysj$F9ZthjmaxZ0M/VHP5u9ZHiELISHbFWkym/.24hqKwbz9rtG7mFOeL9Dj0Y7FEhHF.cBzuuOlEMZaPsS5TtaiK0:18471:0:99999:7::: # " / / "为代码块 # " \$1|\$6 "为转译后的字符串"$1或者$6",输出的字符串中满足其一则输出字段1 # 但是shadow文件中只有一个字段,即所有内容都连在一起。 # awk的详细使用方法详见:https://blog.csdn.net/zhangshenghang/article/details/85065598 ``` sudo配置文件:" /etc/sudoers "是" sudo "命令的配置文件,规定了系统中的用户是否可以执行sudo命令,以及通过sudo可以执行哪些命令。 - 排查除root帐号外,其他帐号是否存在sudo权限。 - 如非管理需要,普通帐号应删除sudo权限。 - 正常情况下/etc/sudoers开放的权限只有440,仅可读。若发现sudoers文件具有可写权限,则需要警惕。 ```bash [root@localhost ~]# chmod 744 /etc/sudoers [root@localhost ~]# ll /etc/sudoers -rwxr--r--. 1 root root 3938 6月 7 2017 /etc/sudoers [root@localhost ~]# more /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)" root ALL=(ALL) ALL attack ALL=(ALL) ALL %wheel ALL=(ALL) ALL # 以上输出的结果中,root、attack以及wheel组中的所有用户都可以通过sudo来执行所有命令 # 第一个 "ALL" 指示允许从任何终端、机器访问"sudo" # 第二个 "(ALL)" 指示"sudo"命令被允许以任何用户身份执行 # 第三个 "ALL" 表示所有命令都可以作为"root"执行 ``` 用户组文件排查:" /etc/group "文件是用户组配置文件,即用户组的所有信息都存放在此文件中。排查是否有用户被添加到了root组中。 ```bash [root@localhost ~]# cat /etc/group |grep root [+] root:x:0: # 组名:组密码:GID:该用户组中的用户列表(初始用户不会显示在组用户中) ``` #### 1.6.3 历史登录信息 ```bash [root@localhost ~]# last # " /var/log/wtmp "永久记录所有用户的登录、注销信息,同时记录系统的启动、重启、关机事件。 # 同样这个文件也是一个二进制文件,不能直接vi,而需要使用last命令来查看。 [root@localhost ~]# lastb # " /var/log/btmp "是记录错误登录的日志,这个文件是二进制文件,不能直接vi查看,而要使用lastb命令查看。 [root@localhost ~]# lastlog # " /var/log/lastlog "是记录系统中所有用户最后一次登录时间的日志,这个文件是二进制文件,不能直接vi,而要使 用lastlog命令查看。 ``` ### 1.7 日志分析 #### 1.7.1 历史命令排查 ```bash [root@localhost ~]# cat .bash_history # 每个用户下面都有1个隐藏的.bash_history ``` #### 1.7.2 登录信息检查 linux将日志信息存放在了/cat/log的目录下。 ```bash [root@localhost ~]# cat /var/log/secure* # 登录信息,包含验证和授权方面的信息,sshd会将所有信息都记录其中,包括登录失败的信息。 [root@localhost ~]# lastlog # /var/log/lastlog记录每个用户最后的登录信息,需要使用lastlog命令查看 [root@localhost ~]# last -f /var/log/wtmp # 该日志文件永久记录每个用户登录、注销及系统的启动、停机事件,需要使用last命令查看 [root@localhost ~]# last -f /var/run/utmp # 该日志文件记录有关当前登录的每个用户的信息,需要使用last命令查看。who、w、users就需要访问这个日志文件。 [root@localhost ~]# last -f /var/log/btmp |more # 记录所有失败登录信息,需要使用last命令查看,或者直接使用lastb。 ``` #### 1.7.3 系统服务日志 ```bash [root@localhost ~]# cat /var/log/cron # crontab日志 [root@localhost ~]# cat /var/log/mail # mail日志 [root@localhost ~]# cat /var/log/mysqld.log # mysql日志 [root@localhost ~]# cat ~/.mysql_history # mysql的历史记录 [root@localhost ~]# cat /var/log/mariadb/mariadb.log # mariadb日志 [root@localhost ~]# cat /var/log/yum.log # 记录yum的安装日志 [root@localhost ~]# car /var/log/syslog # 它只记录警告信息,常常是系统出问题的信息,所以更应该关注该文件 [root@localhost ~]# car /var/log/xferlog # 日志文件记录FTP会话 [root@localhost ~]# cat /var/log/user.log # 记录所有等级用户信息的日志 [root@localhost ~]# cat /var/log/boot.log # 每次主机引导启动时加载的内容。 [root@localhost ~]# cat /var/log/messages # 存放的是系统的日志信息,它记录了各种事件,基本上什么应用都能往里写日志。 ``` #### 1.7.4 Apache日志查看 apache日志的存放目录:cat /var/log/apache2/access.log ```txt 当前WEB服务器中联接次数最多的ip地址:netstat -ntu |awk '{print $5}' |sort | uniq -c| sort -nr 查看日志中访问次数最多的前10个IP: cat access_log |cut -d ' ' -f 1 |sort |uniq -c | sort -nr | awk '{print $0 }' | head -n 10 |less 查看日志中出现100次以上的IP: cat access_log |cut -d ' ' -f 1 |sort |uniq -c | awk '{if ($1 > 100) print $0}'|sort -nr |less 查看最近访问量最高的文件: cat access_log |tail -10000|awk '{print $7}'|sort|uniq -c|sort -nr|less 查看日志中访问超过100次的页面: cat access_log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less 统计某url,一天的访问次数: cat access_log|grep '12/Aug/2009'|grep '/images/index/e1.gif'|wc|awk '{print $1}' 前五天的访问次数最多的网页: cat access_log|awk '{print $7}'|uniq -c |sort -n -r|head -20 从日志里查看该ip在干嘛: cat access_log | grep 218.66.36.119| awk '{print $1"\t"$7}' | sort | uniq -c | sort -nr | less 列出传输时间超过 30 秒的文件: cat access_log|awk '($NF > 30){print $7}' |sort -n|uniq -c|sort -nr|head -20 列出最最耗时的页面(超过60秒的) cat access_log |awk '($NF > 60 && $7~/\.php/){print $7}' |sort -n|uniq -c|sort -nr|head -100 ``` #### 1.7.5 日志信息发送 在Centos7中自带rsyslog的服务,可以用于将特定级别的日志信息发送至日志服务器,具体配置的方法是修改/etc/rsyslog.conf配置文件,内容如下: ```bash # remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional #*.* @@remote-host:514 # ### end of the forwarding rule ### *.info;*notice @192.168.31.75:514 ``` 日志的级别 ```bash debug ##有调式信息的,日志信息最多 info ##一般信息的日志,最常用 notice ##最具有重要性的普通条件的信息 warning ##警告级别 err ##错误级别,阻止某个功能或者模块不能正常工作的信息 crit ##严重级别,阻止整个系统或软件不能正常工作的信息 alert ##需要立刻修改的信息 emerg ##内核崩溃等严重信息 none ##什么都不记录 ``` 日志的类型 ```bash auth ##pam产生的日志 suthpriv ##ssh,ftp等登陆信息的验证信息 cron ##时间任务相关 kern ##内核 lpr ##打印 mail ##邮件 mark(syslog)-rlog ##服务内部的信息,时间标识 news ##新闻组 user ##用户程序产生的相关信息 uucp ##unix to unix copy,unix主机之间相关的通讯 local 1~7 ##自定义的日志设备 ``` 日志举例 ```bash vim /etc/rsyslog.conf cron.info @192.168.31.75:514 #记录计划任务的一般日志信息发送至目标日志服务器 systemctl restart rsyslog ```  ### 1.8 常用的linux扫描工具 #### 1.8.1 lynis 项目地址:https://github.com/CISOfy/lynis ```bash [root@localhost ~]# cd lynis; [root@localhost ~]# ./lynis audit systema ```  #### 1.8.2 Linux_check.sh脚本 可以对linux进行快速扫描 附件:[📎linux_check.sh](https://www.yuque.com/attachments/yuque/0/2021/sh/1543119/1611134301825-571aeed6-dc1f-41da-88c8-296fe3bd078c.sh)
毛林
2025年11月1日 14:29
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码