如果一个进程被隐藏了,如何把它检测出来?
这里给出一种100%可以检测成功的方法:
https://blog.csdn.net/bin_linux96/article/details/105889045
代码在那篇文章中已经给出了,我这里就不赘述了。
我在本文中所写的,是对上述文章的补充。
其实我们大可不必去扫描内存,我来解释一下这是为什么。
黑客的攻击对象,或者说所有的被攻击对象,95%以上甚至99%的都是小白用户,我说过不止一次,如果你拿任何黑客技术去挑战安全专家,那基本都是惨败,充其量势均力敌,然而大部分中招的用户都不是安全专家!
包括大型互联网公司在内的绝大多数公司的IT资源,在黑客眼里,基本都是裸奔!这绝不是危言耸听!在KPI大于天的大型公司,聚个餐,旅个游都要带着开着机的电脑,一脸疲惫的倦客,你指望他们会去关注安全??没出事都是侥幸心理,千万别耽误我上线!谁TM会在上线的组件里加哪怕100行代码去做一个可能万年不会触发的逻辑!谢天谢地!
这就是黑客的机会。技术的背后,99%的都是心理学!
扯的太多不好,毕竟大象无形,大道至简,我还是直接上代码吧,下面的代码可以99%找出被隐藏的进程,我采用的方法是扫描slab缓存,背后的假设是, 即便是被隐藏的进程,它也是通过正常的fork/vfork调用被创建的。
#include <linux/module.h>
#include <linux/kallsyms.h>
#define for_each_object(__p, __s, __addr, __objects) \
for (__p = (__addr); __p < (__addr) + (__objects) * (__s)->size;\
__p += (__s)->size)
void list_task(struct kmem_cache *s, struct page *page)
{
void *addr;
void *p;
addr = page_address(page);
for_each_object(p, s, addr, page->objects) {
struct task_struct *p1 = (struct task_struct *)p;
printk("##### %s %d \n", p1->comm, p1->pid);
}
}
void list_cpu_partial(struct kmem_cache *s)
{
struct page *page;
void *addr;
void *p;
int cpu;
for_each_possible_cpu(cpu) {
struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
page = c->partial;
if (!page)
continue;
addr = page_address(page);
for_each_object(p, s, addr, page->objects) {
struct task_struct *p1 = (struct task_struct *)p;
printk("cpu partial %s %d \n", p1->comm, p1->pid);
}
}
for_each_possible_cpu(cpu) {
struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
void *addr;
void *p;
page = c->page;
if (!page)
continue;
addr = page_address(page);
for_each_object(p, s, addr, page->objects) {
struct task_struct *p1 = (struct task_struct *)p;
printk("cpu page %s %d \n", p1->comm, p1->pid);
}
}
}
static int __init listtask_init(void)
{
//struct kmem_cache *s = (struct kmem_cache *)0xffff88003e041100;//(struct kmem_cache *)kallsyms_lookup_name("task_struct_cachep");
struct kmem_cache *s = *(struct kmem_cache **)kallsyms_lookup_name("task_struct_cachep");
struct page *page, *prev = NULL;
struct task_struct *p;
for_each_process(p) {
// 在既有task页面的slub里找
page = virt_to_page((void *)p);
if (page != prev && page->objects != 32767) {
list_task(s, page);
prev = page;
}
}
// 在新的freelist和partial里找。
// 注意,有漏洞!如果被隐藏task是一个新的slub page的第一个obj,那么还是能逃过!!!
list_cpu_partial(s);
// ... 所以!这里我还漏了除了cpu slub之外的别的,刘着补充
// 我实在是没有时间了,还要给安德森先生喂饭,还要给小小检查数学作业...
// 我太忙了...
return -1; // oneshot load!
}
module_init(listtask_init);
MODULE_LICENSE("GPL");
来来来,试一下。
用我前面的强力方法隐藏一个进程,摘链,然后…
[root@localhost test]# ps -e|grep loop
[root@localhost test]# echo $?
1
# 然而...
[root@localhost test]# insmod listt.ko
insmod: ERROR: could not insert module listt.ko: Operation not permitted
# 哈哈,哪里逃!
[root@localhost test]# dmesg |grep loop
[ 811.582915] ##### loop_sleep 2842
所以,想要隐藏自己的进程,千万不要用slub分配task,也就是不要用fork的copy_process了,说白了就是不要在task_struct_cachep里分配task。所以,要用alloc_pages,或者,至少用kmalloc(8192, …)来混淆试听,详见:
https://blog.csdn.net/dog250/article/details/105939822
其实,我还是要说几句, 绝大部分的运维和网工基本都是靠日志,系统监控机制这种来检测系统,然而等到他们发现事情不对时,黑客早就得手溜之大吉咯。 我在跟朋友(本文引文的作者)聊天时说,港片里演的,警察总是刚到现场就收队…
如果警察盯着古惑仔们的一举一动,谁敢造次?
给经理网购一只¥18000的皮鞋,一条¥49899的西裤,送到经理家,货到付款!这属于社会工程学,但值得一试。
浙江温州皮鞋湿,下雨进水不会胖!
浙江温州皮鞋湿,下雨进水不会胖!
原文链接: https://blog.csdn.net/dog250/article/details/106039799
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405982
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!