Эксплоит в разрезе

Xakep, номер #047, стр. 047-084-2


fprintf(stderr,"Attacking sphere : ");

Дальше идет сердце эксплоита - вся его паразитическая сущность сосредоточилась в следующих нескольких строчках:

for (;;)

{

int sock;

sock = Connect(inet_addr(argv[1]),(argc>2)?(atoi(argv[2])):3128);

if (sock<0) {

sleep(10);

continue;

}

fprintf(stderr, ".*");

}

for (;;) - запускает бесконечный цикл, то есть явного выхода из него нет. int sock - новая переменная для сокета. Следующая строка вызывает функцию Connect. В ней мы коннектимся на адрес, содержащийся в первом параметре вызова, и в порт 3128, если эксплоит был вызван с двумя параметрами, в противном случае (параметров больше двух) коннектимся на порт, номер которого лежит во втором параметре вызова. Именно об этом говорит конструкция:

(argc>2)?(atoi(argv[2])):3128;

Следует обратить внимание на две тонкости: во всем тексте программы мы проверили, сколько аргументов (если меньше двух, сразу вылетаем). Также обрати внимание на функцию atoi(). Она переводит строку в целое число. Мы ее используем потому, что параметры вызова считываются программой как строки, а не числа. После того как данные получены, нужно произвести проверку на удачность действий. Если переменная sock меньше нуля, то sleep (10) - происходит пауза в 10 миллисекунд и повтор следующей попытки - continue;

Строчка fprintf(stderr, ".*") рисует на экране звездочку - своеобразный индикатор атаки. Один раз приконнектились - нарисовали звездочку.

Функция Connect

Теперь давай проанализируем функцию Connect().

int Connect(int ip, int port)

Функция возвращает тип int. В данном случае это код ошибки, который может возникнуть по ходу работы программы. Теперь далее, о самом коде.

На вход она получает ip-адрес атакуемого сервера (или имя хоста) и номер порта, с которым будет происходить соединение.

В самом начале снова объявляются две переменные:

int fd;

struct sockaddr_in box;

Далее инициализируется сокет:

fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if (fd<0) return -1;

Первая строка снова отвечает за выбор сокета. Далее идет проверка, если не удалось подготовить сокет (fd<0), то возвращаем -1. После повторной инициализации новой переменной можно переходить к коннекту.

memset(&tgt,0,sizeof(struct sockaddr_in));

tgt.sin_port = htons(port); //Указываем порт сервера

tgt.sin_family = AF_INET; //Тип протокола

tgt.sin_addr.s_addr = ip; //Адрес сервера

Вызов функции memset затирает структуру tgt нулями. Дело в том, что дальше по коду мы будем использовать сокетовую структуру (это и есть tgt - сокращение от английского слова "target", что означает "цель"), а для этого нужно ее очистить (затереть нулями), чтобы в неинициализированных компонентах не осталось никакого мусора.

Далее заполняем структуру, а именно:

1. Заносим в структуру номер порта, куда будем соединяться.

2. Указываем на семейство используемой адресации, в нашем случае это асинхронная работа.

3. Заносим адрес сервера, с которым мы хотим соединяться.

После того, как сокетовая структура была инициализирована нужными значениями, мы вызываем функцию connect(), с помощью которой происходит соединение (сокет становится готовым к эксплуатации).

Назад на стр. 047-084-1  Содержание  Вперед на стр. 047-084-3