Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> firewall Unix через перехват системных функций, Необходимо реализовать фильтрацию 
:(
    Опции темы
sena
Дата 6.5.2011, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.11.2009

Репутация: нет
Всего: нет



У меня имеется клиент СУБД Postgresql на Windows, сервер на Red Hat. При обращении клиента с запросом select       lpad('xxxxx',39842342929,'yyyyyyyyyyyyyyy'); происходит переполнение буфера и жёсткое зависание сервера.
Мне необходимо реализовать защиту от этой атаки. Я вижу выход в перехвате на стороне сервера системной функции    recv(sock,char*buf,sizebuff,flags) которая содержит указатель на буфер данных *buf.
Но так как функция recv это то же что и функция sys_socketcall(int call, unsigned long __user *args) , где call=10, а args является указателем
на параметры recv:
sock=args[0];
buf=&args[1];
и т.д. Начинаю перебором искать сочетание 'select lpad' но ничего не находит.
Подскажите пожалуйста как можно найти это сочетание или вообще другие альтернативные пути решения
PM MAIL   Вверх
MAKCim
Дата 6.5.2011, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



например, в recv лежат закодированные данные, поэтому нужный шаблон не находится

попробуйте протрассировать серверный процесс через strace -s 4096 (или больше)
если select есть в "чистом" виде, он будет виден в логе


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
sena
Дата 7.5.2011, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.11.2009

Репутация: нет
Всего: нет



трассировка выдаёт:
strace -p 1370
recv(10,"Q\0\0\0\35....select lpad(\'x\',5\,'y\');\0",8192,0)=29
и если посчитать все символы без слешей, то получается ровно 29 байт.
Я даже не могу сделать вывод этого буфера символов в файл или на экран,
использую для перехвата функций подгружаемые модули ядра LKM код такой:

Код

#include <linux/module.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <fcntl.h>
int i;
int *fd;
char* data;
extern void* system_call_table[];//импортирую таблицу системных вызовов
int(* orig_socketcall)(int call, unsigned long __user *args);//определяю указатель на оригинальный вызов
int own_socketcall(int call, unsigned long __user *args);//свой обработчик
{
    if(call==10)//то есть если это именно функция recv
      {
     fd = open("/root/test.txt",O_WRONLY);
     write(fd,&args[1],8192);
     close(fd);
     data=&args[1];
               for(i=0;i<8191;i++)
                          {
                   if(data[i]=='s')
                             if(data[i+1]=='e')                            
                                     if(data[i+2]=='l')
                                             if(data[i+3]=='e')
                                                   if(data[i+4]=='c')
                                                           if(data[i+5]=='t')
                                   return 0;
                            }   
       }
    else
      {
    return orig_socketcall(call,args);
       }
}
int init_module()
{
orig_socketcall = sys_call_table[SYS_socketcall];
sys_call_table[SYS_socketcall] = own_socketcall;
return 0;
}
void cleanup_module()
{
sys_call_table[SYS_socketcall] = orig_socketcall;
}


и в итоге пишет что функции open write close не определены, хотя если написать отдельную программку:
Код

#include <fcntl.h>
int main(void)
{
     char* buf = "ffopijrmofoaherifhaerif";
     int fd;
     fd = open("/root/test.txt",O_WRONLY);
     write(fd,buf,30);
     close(fd);
     return 0;
}

то всё прекрасно выводится в файл

Это сообщение отредактировал(а) Олег2005 - 10.5.2011, 00:22
PM MAIL   Вверх
MAKCim
Дата 7.5.2011, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



sena, 

M
MAKCim
Модератор: пользуйтесь тегом код!


Код

ssize_t (*_recvmsg)(int sockfd, struct msghdr *msg, int flags);
ssize_t (*_recvfrom)(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t (*_recv)(int sockfd, void *buf, size_t len, int flags);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
    ssize_t error;
    error = _recvmsg(sockfd, msg, flags);
    if (error > 0)
    {
        size_t i;
        struct iovec *iovec;
        for (i = 0; i < msg->msg_iovlen; ++i)
        {
            iovec = &msg->msg_iov[i];
            if (check_buffer(iovec->iov_base, iovec->iov_len))
            {
                errno = EPERM;
                error = -1;
            }
        }
    }
    return error;
}

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
    ssize_t error;
    error = _recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
    if (error > 0 && check_buffer(buf, len))
    {
        errno = EPERM;
        error = -1;
    }
    return error;
}

ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
    ssize_t error;
    error = _recv(sockfd, buf, len, flags);
    if (error > 0 && check_buffer(buf, len))
    {
        errno = EPERM;
        error = -1;
    }
    return error;
}

int init_wrappers()
{
    void *ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvmsg")) == NULL)
    {
        fprintf(stderr, "dlsym() 1 failed");
        return -1;
    }
    _recvmsg = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvfrom")) == NULL)
    {
        fprintf(stderr, "dlsym() 2 failed");
        return -1;
    }
    _recvfrom = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recv")) == NULL)
    {
        fprintf(stderr, "dlsym() 3 failed");
        return -1;
    }
    _recv = ptr;
    return 0;
}

__attribute__((constructor))
void init()
{
    if (init_wrappers())
    {
        exit(-1);
    }
}


в check_buffer() вставляете проверку строки на нужный шаблон
компилируете это все в .so файл и загружаете вместе с серверной программой через LD_PRELOAD



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
sena
Дата 7.5.2011, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.11.2009

Репутация: нет
Всего: нет



Не могли бы вы пояснить немного? Я понял что эти три функции возвращают -1, т.е. имитация ошибки чтения, в моём случае это функция recv, тут понятно. 
1.Но какую функциональную нагрузку несёт init_wrappers(), __attribute__((constructor)), void init() можно ли это прокомментировать? 
2.А также какие библиотеки подключить чтобы были определены ssize_t, error, EPERM, dlsym, fprintf.
3.Как можно вставить проверку на шаблон в check_buffer(buf, len), если len - это длина?
4.Как загрузить my_file.so с программой, если программа запускается так: service postgresql start?
5. Я как понимаю это способ перехвата, не имеющий отношения к LKM? если да, то где можно об этом почитать?
PM MAIL   Вверх
MAKCim
Дата 7.5.2011, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(sena @  7.5.2011,  11:40 Найти цитируемый пост)
1.Но какую функциональную нагрузку несёт init_wrappers(), __attribute__((constructor)), void init() можно ли это прокомментировать? 

init_wrappers() получение адресов оригинальных функций
init() вызывается при загрузке .so файла (атрибут constructor), чтобы вызвать init_wrappers()


Цитата(sena @  7.5.2011,  11:40 Найти цитируемый пост)
2.А также какие библиотеки подключить чтобы были определены ssize_t, error, EPERM, dlsym, fprintf.

sys/types.h
sys/socket.h
errno.h
dlfcn.h
stdio.h


Цитата(sena @  7.5.2011,  11:40 Найти цитируемый пост)
3.Как можно вставить проверку на шаблон в check_buffer(buf, len), если len - это длина?

точно так же, как и в LKM


Цитата(sena @  7.5.2011,  11:40 Найти цитируемый пост)
4.Как загрузить my_file.so с программой, если программа запускается так: service postgresql start?

посмотреть, какой бинарник вызывается из /etc/init.d/postgresql
заменить его на скрипт с тем же именем, откуда вызывать оригинальную программу с LD_PRELOAD
Код

#!/bin/bash

LD_PRELOAD=<путь к библиотеке> exec <путь к оригинальной программе> $*




Цитата(sena @  7.5.2011,  11:40 Найти цитируемый пост)
5. Я как понимаю это способ перехвата, не имеющий отношения к LKM? если да, то где можно об этом почитать? 

не в курсе ;)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
sena
Дата 11.5.2011, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.11.2009

Репутация: нет
Всего: нет



при компиляции данного кода ( командой gcc -fPIC -c -Wall dll.c ) у меня ошибка:
dll.c: In function 'init_wrappers' :
dll.c:91 'RTLD_NEXT' undeclared (first use in this function)
dll.c:91 (Each undeclared identifier is reported only once 
dll.c:91 for each function it appears in.)
Код

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <dlfcn.h>
#include <stdio.h>
int j;
ssize_t (*_recvmsg)(int sockfd, struct msghdr *msg, int flags);
ssize_t (*_recvfrom)(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t (*_recv)(int sockfd, void *buf, size_t len, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
    ssize_t error;
    char* data;
    error = _recvmsg(sockfd, msg, flags);
    if (error > 0)
    {
        size_t i;
        struct iovec *iovec;
        for (i = 0; i < msg->msg_iovlen; ++i)
        {
            iovec = &msg->msg_iov[i];
        data = iovec->iov_base ;            
          for (j = 0; j < iovec->iov_len ; j++)
                     {
               if (data[i]=='l')
                    if (data[i+1]=='p')
                        if (data[i+2]=='a')
                            if (data[i+3]=='d')
                                 { errno = EPERM ; error = -1 ;}
                      }

//            if (check_buffer(iovec->iov_base, iovec->iov_len))
//            {
//                errno = EPERM;
//                error = -1;
//            }
        }
    }
    return error;
}
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
    ssize_t error;
    char* data;
    data = buf ;
    error = _recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
   if ( error > 0 )
       for ( j = 0 ; j < len ; j++ )
   {
       if (data[i]=='l')
           if (data[i+1]=='p')
               if (data[i+2]=='a')
                   if (data[i+3]=='d')
                       { errno = EPERM ; error = -1 ;}
    
    }
//    if (error > 0 && check_buffer(buf, len))
//    {
//        errno = EPERM;
//        error = -1;
//    }
    return error;
}
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
    ssize_t error;
    char* data;
    data = buf ;
    error = _recv(sockfd, buf, len, flags);
   if ( error > 0 )
       for ( j = 0 ; j < len ; j++ )
   {
       if (data[i]=='l')
           if (data[i+1]=='p')
               if (data[i+2]=='a')
                   if (data[i+3]=='d')
                       { errno = EPERM ; error = -1 ;}
    
    }

//    if (error > 0 && check_buffer(buf, len))
//    {
//        errno = EPERM;
//        error = -1;
//    }
    return error;
}
int init_wrappers()
{
    void *ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvmsg")) == NULL)
    {
        fprintf(stderr, "dlsym() 1 failed");
        return -1;
    }
    _recvmsg = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvfrom")) == NULL)
    {
        fprintf(stderr, "dlsym() 2 failed");
        return -1;
    }
    _recvfrom = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recv")) == NULL)
    {
        fprintf(stderr, "dlsym() 3 failed");
        return -1;
    }
    _recv = ptr;
    return 0;
}
__attribute__((constructor))
void init()
{
    if (init_wrappers())
    {
        exit(-1);
    }
}


вроде необходимая библиотека подключена, почему он не видит RTLD_NEXT
PM MAIL   Вверх
sena
Дата 14.5.2011, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 27.11.2009

Репутация: нет
Всего: нет



с ошибкой сам разобрался, откомпилировал вот этот код:
Код

#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>

int j;
ssize_t (*_recvmsg)(int sockfd, struct msghdr *msg, int flags);
ssize_t (*_recvfrom)(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t (*_recv)(int sockfd, void *buf, size_t len, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
    ssize_t error;
    char* data;
    error = _recvmsg(sockfd, msg, flags);
    if (error > 0)
    {
        size_t i;
        struct iovec *iovec;
        for (i = 0; i < msg->msg_iovlen; ++i)
        {
            iovec = &msg->msg_iov[i];
        data = iovec->iov_base ;            
          for (j = 0; j < iovec->iov_len ; j++)
                     {
               if (data[i]=='l')
                    if (data[i+1]=='p')
                        if (data[i+2]=='a')
                            if (data[i+3]=='d')
                                 { errno = EPERM ; error = -1 ;}
                      }

//            if (check_buffer(iovec->iov_base, iovec->iov_len))
//            {
//                errno = EPERM;
//                error = -1;
//            }
        }
    }
    return error;
}
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
{
    ssize_t error;
    char* data;
    data = buf ;
    error = _recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
   if ( error > 0 )
       for ( j = 0 ; j < len ; j++ )
   {
       if (data[i]=='l')
           if (data[i+1]=='p')
               if (data[i+2]=='a')
                   if (data[i+3]=='d')
                       { errno = EPERM ; error = -1 ;}
    
    }
//    if (error > 0 && check_buffer(buf, len))
//    {
//        errno = EPERM;
//        error = -1;
//    }
    return error;
}
ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
    ssize_t error;
    char* data;
    data = buf ;
    error = _recv(sockfd, buf, len, flags);
   if ( error > 0 )
       for ( j = 0 ; j < len ; j++ )
   {
       if (data[i]=='l')
           if (data[i+1]=='p')
               if (data[i+2]=='a')
                   if (data[i+3]=='d')
                       { errno = EPERM ; error = -1 ;}
    
    }

//    if (error > 0 && check_buffer(buf, len))
//    {
//        errno = EPERM;
//        error = -1;
//    }
    return error;
}
int init_wrappers()
{
    void *ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvmsg")) == NULL)
    {
        fprintf(stderr, "dlsym() 1 failed");
        return -1;
    }
    _recvmsg = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recvfrom")) == NULL)
    {
        fprintf(stderr, "dlsym() 2 failed");
        re

turn -1;
    }
    _recvfrom = ptr;
    if ((ptr = dlsym(RTLD_NEXT, "recv")) == NULL)
    {
        fprintf(stderr, "dlsym() 3 failed");
        return -1;
    }
    _recv = ptr;
    return 0;
}
__attribute__((constructor))
void init()
{
    if (init_wrappers())
    {
        exit(-1);
    }
}

#gcc -fPIC -c dll.c
#gcc -shared -o dll.so dll.o
запускаю сервис командой:
LD_PRELOAD=/root/dll.so exec /etc/init.d/postgresql
после этого вылезает ошибка: id: symbol lookup error: /root/dll.so: undefined symbol: dlsym 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0562 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.