扫描slab找出被隐藏的task_struct或者随便别的什么

如果一个进程被隐藏了,如何把它检测出来?

这里给出一种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大佬

    扫描slab找出被隐藏的task_struct或者随便别的什么

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405982

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午9:32
下一篇 2023年4月26日 上午9:33

相关推荐