黑客与宕机

简介: 宕机问题有一种比较少见的pattern,就是看起来完全不相关的机器同时出现宕机。处理这个pattern的问题,我们需要找到,在这些机器上能同时触发问题的条件。 通常,这些机器要么几乎在同一时间点出现问题,要么从某一个时间点开始,相继出现问题。

宕机问题有一种比较少见的pattern,就是看起来完全不相关的机器同时出现宕机。处理这个pattern的问题,我们需要找到,在这些机器上能同时触发问题的条件。

通常,这些机器要么几乎在同一时间点出现问题,要么从某一个时间点开始,相继出现问题。对于前一种情况,比较常见的情形是,物理机故障导致运行在其上的所以虚拟机宕机,或者一个远程管理软件同时杀死了所有被管理的系统里的关键进程;对于后一种情况,可能的一个原因是,用户在所有实例上部署了同一个有问题的模块(软件、驱动)。

而实例被大范围的hack,则是另一个常见的原因。在WannaCry病毒肆虐的时候,经常出现一些公司,或者一些部门的机器全部蓝屏的情形。今天跟大家分享一例这样的问题。

坏掉的内核栈

使用crash工具sys命令,我们可以看到系统的一些基本信息,和宕机的直接原因。对于这个问题来说,宕机的直接原因是"Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffffa02987eb"。关于这条信息,我们必须逐字解读。"Kernel panic - not syncing:"这部分内容在内核函数panic里输出,凡是调用到panic函数,必然会有这一部分输出,所以这一部分内容和问题没有直接关系。而"stack-protector: Kernel stack is corrupted in:"这部分内容,在内核函数__stack_chk_fail,这个函数是一个堆栈检查函数,它会检查堆栈,同时在发现问题的时候调用panic函数产生core dump报告问题。而它报告的问题是堆栈损坏。关于这个函数,后续我们会跟进一步分析。
d67a97d54e5ea127575203dd3e7e9a30e65812c0
而ffffffffa02987eb这个地址,是函数__builtin_return_address(0)的返回值。当这个函数的参数是0的时候,这个函数的输出值是调用它的函数的返回地址。这句话现在有点绕,但是后续分析完调用栈,会很清楚。

函数调用栈

分析宕机问题的核心,就是分析panic的调用栈。下边的调用栈,乍看起来是system_call_fastpath调用了__stack_chk_fail,然后__stack_chk_fail调用了panic,报告了堆栈损坏的问题。但是稍微和类似的堆栈做一点比较的话,就会发现,事实并非这么简单。
b3ca37db8a7985d926e6366417f489049611a673
下边是一个类似的,以system_call_fastpath函数开始的调用栈,不知道大家有没有看出来这个调用栈和上边调用栈的不同。实际上,以system_call_fastpath函数开始的调用栈,表示这是一次系统调用(system call)的内核调用栈。下图中的调用栈,表示用户模式的进程,有一次epoll的系统调用,然后这个调用进入了内核模式。而上图中的调用栈显然是有问题的,因为我们就算查遍所有的文档,也不会找到一个系统调用,会对应于内核__stack_chk_fail函数。
5bbb1deb2cab3847046ee0e31474dc14007bccdd
提示:这边引出另外一个,在分析core dump的时候需要注意的问题,就是用bt打印出来的调用栈有的时候是错误的。

Raw stack

所谓的调用栈,其实不是一种数据结构。用bt打印出来的调用栈,其实是从真正的数据结构,线程(内核)堆栈中,根据一定的算法重构出来的。而这个重构过程,其实是函数调用过程的一个逆向工程。相信大家都知道堆栈的特性,先进后出。关于函数调用,以及堆栈的使用,可以参考一下下边这张图。大家可以看到,每个函数调用,都会在堆栈上分配到一定的空间。而CPU执行每个函数调用指令(call),都会顺便把这条call指令的下一条指令压栈。这些“下一条指令”,就是所谓的函数返回地址。
35cb5f4c6ce21eb56aaf0e26381a90aa8ccbb85e
这个时候,我们再回头看Panic的直接原因那一部分,函数__builtin_return_address(0)的返回值。这个返回值,其实就是调用__stack_chk_fail的call指令的下一条指令,这条指令属于调用者函数。这条指令地址被记录为ffffffffa02987eb。我们用sym命令查看这个地址临近的函数名,显然这个地址不属于函数system_call_fastpath,也不属于内核任何函数。这也再次验证了,panic调用栈是错误的这个结论。
5dd11af2785cfbeedc00942f32653af09f0c0940
关于raw stack,我们可以用bt -r命令来查看。因为raw stack往往有几个页面,这里只截图和__stack_chk_fail相关的这一部分内容。
a352affae36645207f80e86c3b339593d637eef3
这部分内容,有三个重点数据需要注意,panic调用__crash_kexec函数的返回值,这个值是panic函数的一条指令的地址;__stack_chk_fail调用panic函数的返回值,同样的,它是__stack_chk_fail函数的一条指令的地址;ffffffffa02987eb这个指令地址,属于另外一个未知函数,这个函数调用了__stack_chk_fail。

Syscall number & Syscall table

因为带有system_call_fastpath函数的调用栈,对应着一次系统调用,而panic的调用栈是坏的,所以这个时候我们自然而然会疑问,到底这个调用栈对应的是什么系统调用。在linux操作系统实现中,系统调用被实现为异常。而操作系统通过这次异常,把系统调用相关的参数,通过寄存器传递到内核。在我们使用bt命令打印出调用栈的时候,我们同时会输出,发生在这个调用栈上的异常上下文,也就是保存下来的,异常发生的时候,寄存器的值。对于系统调用(异常),关键的寄存器是RAX,它保存的是系统调用号。我们先找一个正常的调用栈验证一下这个结论。0xe8是十进制的232。
872193cd4e392c1de1560312346e14bef4338f03
使用crash工具,sys -c命令可以查看内核系统调用表。我们可以看到,232对应的系统调用号,就是epoll。
a045a18309bdf445f8f8cb5e7d54700c6d5a2f34
这个时候我们再回头看“函数调用栈”这节的插图,我们会发现异常上下文中RAX是0。正常情况下这个系统调用号对应read函数,如下图。
52ae282e637a316ecc0da7b767f3d1c13517173b

如下图,有问题的系统调用表显然是被修改过的。修改系统调用表(system call table)这种事情,常见的有两种代码会做(这个相当辩证),一种是杀毒软件,而另外一种是hack程序。当然还有另外一种情况,就是某个蹩脚的内核驱动,无意识的改写了系统调用表。

f151564d12e20dea33380e97fb969f3bc8c2418e

另外我们可以看到,被改写过的函数的地址,显然和最初被__stack_chk_fail函数报出来的地址,是非常邻近的。这也可以证明,系统调用确实是走进了错误的read函数,最终踩到了__stack_chk_fail函数。

Raw data

基于上边的数据,来下结论,总归还是有点经验主义。更何况,我们甚至不能区分,问题是由杀毒软件导致的,还是木马导致的。这个时候我们花费了比较多的时间,尝试从core dump里挖掘出ffffffffa02987eb这个地址更多的信息。有一些最基本的尝试,比如尝试找出这个地址对应的内核模块等,但是都无功而返。这个地址既不属于任何内核模块,也不被已知的内核函数所引用。这个时候,我们做了一件事情,就是把这个地址前后连续的,所有已经落实(到物理页面)的页面,用rd命令打印出来,然后看看有没有什么奇怪的字符串可以用来作为特征串定位问题。

5d46eb66186531d078c52503563d2ea6fc274996

就这样,我们在邻近地址发现了下边这些字符串。很明显这些字符串应该是函数名。我们可以看到hack_open和hack_read这两个函数,对应被hacked的0和2号系统调用。还有函数像disable_write_protection等等。这些函数名,显然说明这是一段“不平凡”的代码。公网搜索这些函数会发现很多rootkit的示例。

后记

宕机问题的core dump分析,需要我们非常的耐心。我个人的一条经验是:every bit matters,就是不要放过任何一个bit的信息。core dump因为机制本身的原因,和生成过程中一些随机的因素,必然会有数据不一致的情况,所以很多时候,一个小的结论,需要从不同的角度去验证。

目录
相关文章
|
8天前
|
存储 监控 安全
服务器死机,数据丢失怎么办?
【10月更文挑战第27天】当服务器死机且数据丢失时,应先尝试重启服务器并检查硬件问题。随后,利用备份数据、数据恢复软件或专业服务恢复数据。为预防未来数据丢失,需定期备份数据,使用热备份和RAID技术,定期维护服务器,强化安全性,并建立监控和日志记录机制。
35 8
|
2月前
|
安全 数据安全/隐私保护
一个被挂木马的政府网站
一个被挂木马的政府网站
|
2月前
|
安全
又一个被挂木马的政府网站(第3版)
又一个被挂木马的政府网站(第3版)
|
6月前
|
SQL 监控 安全
如何发现服务器被入侵了,服务器被入侵了该如何处理?
如何发现服务器被入侵了,服务器被入侵了该如何处理?
|
安全 网络协议 网络安全
数据的心跳:心脏滴血漏洞
数据的心跳:心脏滴血漏洞
390 0
|
安全 JavaScript
怎么防止网站不被挂木马篡改
因为说这些脚本文件它都是一些静态的文件连接,那么既然是静态的,那就是说我们存放这个脚本的这个服务器,它只能放静态文件,不支持任何的脚本语言,那它也就不可能存在任何的后门,也不可能被篡改挂木马,上传脚本后门文件等等这些问题,所以说只要替换成静态的连接文件,那么说你网站从此以后没人能修改这些静态的脚本文件,他如果想给网站挂木马的话,那只有其他的办法,那就是说给你网页插入一个新的脚本文件,那么他给你插一个新的脚本文件的话,我想普通的站长一眼就能看到,所以不需要到处去找,直接就可以把它移除掉,或者是我们可以配合一些网站的检测一些程序,检测你网站是否存在未知的文件,配合这样一些东西去方便快速的锁定,这个
263 0
怎么防止网站不被挂木马篡改
|
监控 安全 算法
黑客与宕机
造成系统异常宕机(无响应、异常重启)的原因有很多种,最常见的是操作系统内部缺陷和设备驱动缺陷。本文作者将和大家分享内存转储分析的底层逻辑和方法论,并通过一个线上真实案例来展示从分析到得出结论的整个过程,希望对同学们处理此类问题和对系统的理解上有所帮助。
1441 0
黑客与宕机
|
安全
网站被主机攻击断网 871
网络攻击871是怎么回事?
2804 0
|
安全
警惕“搜房网”“凯业房园”等网站被挂马
据瑞星“云安全”系统统计, 上周末期间,共有5,556,431人次的网民遭到网页挂马攻击,瑞星共截获了748,911个挂马网址。 周末最流行木马病毒是 Worm.Win32.Autorun.gbn(U盘蠕虫下载器)“云安全”系统共收到100,754次用户上报。
1810 0
|
安全
愚人节黑客以身试法 人民法院被挂马
金山毒霸云安全中心监测,4月1日共截获国内挂马网站1619个。其中政府网站受害居多。 金山毒霸云安全中心监测到成都市武侯区人民法院被挂马,当日被挂马的其他重点网站: 中共青岛市委宣传部宣网 http://www.
1324 0