Откуда берутся шелл-коды Степан Ильин (step@gameland.ru) Хакер, номер #085, стр. 085-050-2 Сразу хочу предупредить, что для полного понимания статьи необходимо иметь хотя бы минимальные знания ассемблера. Надеюсь, ты внимательно читал вводные статьи по теме в «Кодинге», так как в этом случае проблем не будет, и материал покажется простым и понятным. В качестве платформы для экспериментов мы выберем Linux на машине с 32-битным x86 процессором. Предвижу твой резонный вопрос: почему Linux? Да потому, что абсолютно большинство эксплойтов предназначено именно для Unix-сервисов, а значит, представляют больший интерес. Для работы нам также понадобятся несколько вспомогательных инструментов: Netwide Assembler (nasm), ndisasm и hexdump. В большинстве дистрибутивов они поставляются по умолчанию, но даже самостоятельная установка вряд ли вызовет затруднения. Ссылки на дистрибутивы ищи во врезке, хотя зачем? Все необходимое выложено на наш диск. [примера ради] Заготовки для шелл-кода обычно пишут на ассемблере. Однако мы построим процесс несколько иначе: сначала для лучшего понимания рассмотрим примеры на языке С, а уже потом - аналогичный код на ассемблере. Я намеренно рассмотрю два довольно простых примера, чтобы не грузить тебя громоздкими выкладками, от которых все равно не будет толку. Очень скоро ты поймешь, что процесс создания шелл-кода для более сложных действий по большому счету ничем не отличается. Итак, первый пример. Он самый простой и заключается в том, что наша небольшая программа откроет для записи файл /etc/passwd, добавит в конец строку «xakep:x:0:0::/:/bin/bash\n», после чего закроет его, сохранив результат. #include <stdio.h> #include <fcntl.h> main() { char *filename = "/etc/passwd"; char *line = "xakep:x:0:0::/:/bin/bash\n"; int f_open; f_open = open(filename,O_WRONLY|O_APPEND); write(f_open, line, strlen(line)); close(f_open); exit(0); } Приведенный код предельно прост и понятен, за исключением разве что функции open (открыть файл). Константа O_WRONLY|O_APPEND, которая передается ей в качестве параметра, указывает то, что файл открывает в режиме записи, а новые данные дописываются в его конец. Теперь рассмотрим более жизненный пример - запуск системного интерпретатора (шелла). Мудрить особо не будем: стандартного /bin/sh нам хватит сполна. #include <stdio.h> |