Картинки с внешних ресурсов — добро или зло?

Information Security
Sandbox
Большинство многопосещаемых площадок позволяют размещать у себя картинки с внешних ресурсов. Это очень удобная и полезная фича не только для простых пользователей, но и для людей, собирающих информацию о вас.

Большой брат следит за тобой

Вы хотите узнать больше информации о самых действенных методах? Вам интересно, как с помощью маленькой картинки определить разрешение экрана, локальное время и сменить парочку паролей? Добро пожаловать под кат!
Содержание:


Что мы будем использовать

  • Пассивные методы — прозрачная для пользователя запись поступающей информации
  • Активные методы — отдача уникального контента на каждый запрос

Активные методы поддаются обнаружению, однако именно они могут дать нам желанный результат.

Статистика

Пассивные методы


Нам нужно получить всю информацию, которая позволяет отделить каждого пользователя от основной массы, и затем начинать следить за ними. На наиболее-низком уровне это IP протокол, затем TCP, возможно SSL/TLS, и уже потом HTTP.

Традиционно в этой сфере используется анализ трафика.
Mozilla Firefox (EN) Google Chrome (RU)
GET /image.png HTTP/1.1
Host: habrahabr.ru
User-Agent: Mozilla/5.0
Accept: image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://habrahabr.ru/
Connection: keep-alive


Перенос: \r\n

GET /image.png HTTP/1.1
Host: habrahabr.ru
Connection: keep-alive
User-Agent: Mozilla/5.0
Accept: */*
Referer: http://habrahabr.ru/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3

Перенос: \r\n

Это два запроса, с одной и той-же страницы, на одну и ту-же картинку, однако с разных браузеров. Как видим, различается не только содержимое заголовков, но и их порядок. У разных версий браузеров так-же будут возникать различия, тем сам мы можем предположить о локализации и умышленном изменении User-Agent.

В случае с большим файлом читая временные метки можно определить скорость передачи информации. По скорости и IP-адресу можно будет узнать провайдера и тариф что поможет применить социальную инженерию к человеку.

Боты
Большинство ботов эмулирующих просмотр сайта и не основанных на браузерных движках не приводят нижнему регистру заголовок host — быстро обнаружить злодеев без помощи администрации поможет такой тег:

<img src="http://HABRAhabr.ru/image.png" alt="На главную страницу">

Активные методы


Теперь мы уже переходим к самому интересному, почему бы нам не выжать все максимально-возможное из этой техники?

Cookie

Должно быть вы слышали о этой технологии передачи данных между сервером и клиентом, её стал поддерживать еще IE 2-й версии. Недавно подошел Mozilla Firefox 22, в котором по умолчанию была заблокированна установка куков со сторонних доменов, но а всех кто использует другие браузеры ожидает большой сюрприз. Векторы использования:

  • Сопоставление выходов клиента с разных IP
  • Отслеживание разных сессий браузера
  • Определение браузера исходя из лимитов на данные
  • Определение локального времени с точностью до секунды

С первым пунктом все ясно — мы устанавливаем куку с большим сроком действия, записываем в неё уникальный идентификатор, и в дальнейшем все считываем.

Второй пункт такой-же простой, как и первый мы — если мы не зададим срока действия, кука будет действовать до первого закрытия браузера, — таким образом после придет запрос только с первой кукой.

Данные из википедии гласят, что каждый браузер устанавливает предел на объем данных, к тому-же он иногда изменяются от версии к версии тем самым, публикуя еще одну картинку с другого домена можно повысить вероятность правильного определения.

Для осуществления четвертого пункта требуются некоторые усилия:

Set-Cookie: name=VALUE[; expires=DATE][; path=PATH][; domain=DOMAIN_NAME][; secure][; HttpOnly];

Cookie: name=VALUE;

Сервер устанавливает куку с помощью Set-Cookie, устанавливает нужные параметры и передает все в браузер. Браузер сохраняет параметры и обратно придут только данные — элегантно и просто.

Самое интересное здесь в поле даты, она задается в формате Wdy, DD Mon YYYY HH:MM:SS GMT, то есть едина вне зависимости от местоположения, однако если системное время не синхронизировано или проставлен другой часовой пояс возникнут различия.

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



Зададим контрольную и еще 12 разных версий куки с разницей в 2 часа и посмотрим следующий ответ пользователя осуществляя перенаправления через Location. Потом сужая или расширяя(Если время изменено больше чем на день) при надобности диапазон доходим до секундных отметок, после чего можно определить зависимость между серверным и клиентским временем и опознать человека в следующий раз.

Cache


Кэш браузера позволяет сделать абсолютно то же самое в тех случаях, когда куки отключены:

Etag
При отдаче картинки отдается заголовок Etag с уникальной хэш-строкой:
Etag: 1aa69b6c6273a8

Последующий запрос к серверу будет выглядеть так:
If-None-Match: 1aa69b6c6273a8

Теперь сервер вправе отдать статус 304 Not Modified без передачи самой картинки — браузер возьмет её из кэша.

Last-Modified
Более-старый аналог Etag, так-же может использоваться для отслеживания. Указывает дату последнего изменения документа.
Server => Last-Modified: Fri, 02 Jan 1970 10:17:36 GMT

Client => If-Modified-Since: Fri, 02 Jan 1970 10:17:36 GMT
Server => HTTP/1.1 304 Not Modified

Expires
Указывает на дату возможного истечения актуальности документа. Более-долгий аналог определения времени.

Expires: Fri, 02 Jan 1970 10:17:36 GMT
Cache-Control: must-revalidate

Подробно о заголовке расписано здесь.

Заголовок Link


HTTP-Заголовок Link эквивалентен тегу <link>. Можно указать ссылку на rss-ленту, таблицу стилей и прочее прямо в заголовках — это шанс, ведь HTML включить в картинку не получится(За исключением старых версий Internet Explorer).

Link: <./style.css>; rel=stylesheet

Используя современные возможности CSS 3медиа-запросы — можно подгружать данные через условия, например по разрешению экрана:
@media all and (device-width: 1024px) { 
	html {
		background: url("./w1024.jpg");
	}
}
@media all and (device-height: 768px) { 
	body {
		background: url("./h768.jpg");
	}
}

Такой способ будет работать не всегда — изображения загружаются только в случае наличия соответствующих им тегов, поддержки WebKit нет, синтаксис в условиях ограничен. Но при некоторых конфигурациях он работает!

Бесконечный gif


Идея в том, что в формате анимированного GIF'а не указывается количество фреймов, так что после отображения картинки браузер ждёт новых фреймов с сервера до тех пор, пока не получит сигнальные биты о конце файла. Другими словами, сервер может пушить в браузер сообщения по открытому каналу в GIF.

(с) alizar

См. habrahabr.ru/post/151538 и habrahabr.ru/post/180877

Кроме того бесконечный gif можно применять для отслеживания времени проведения пользователя на странице — сокет будет закрыт в момент закрытия вкладки или повиснет после изменения настроек сети, переключения прокси-серверов, VPN-серверов…

Заголовок Refresh


Этот заголовок(в отличии от Link) не задан стандартами, однако, поддерживается почти везде.

Refresh: 15; url=http://habrahabr.ru/images/bg-multilogo.png

Он позволяет осуществлять перенаправление через определенный промежуток времени — если юзер загрузит страницу, а затем не закрывая вкладок отключит VPN и прокси — его IP будет у нас в кармане.

Basic-authentication


Способ очень старый, не спорю, он так-же работает на заголовках и все еще актуален. А если выдавать форму только нужным людям обнаружить засаду там, где никто не будет её искать становится непосильной задачей.

Материалы: habrahabr.ru/post/140054

CSRF атаки


CSRF — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Если жертва заходит на сайт, созданный злоумышленником, от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы), осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки, жертва должна быть авторизована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, который не может быть проигнорирован или подделан атакующим скриптом.

https://ru.wikipedia.org/wiki/Подделка_межсайтовых_запросов


Если URL жестко фильтруется еще не значит, что провести подобную атаку невозможно. Через тот-же заголовок Location можно передать вредоносную ссылку на изменение паролей, отправку сообщений или на что то еще:

Location: http://www.ru/panel/password?newpass=qwerty&newpass2=qwerty&submit=ok


Возможно использование только метода GET, такие уязвимости широко распространены и сегодня. Часто встречаются безопасные, но неприятные CSRF на разлогинивание, можно вывести сайт из строя на некоторое время.

Низкоуровневые, ошибочные и прочие методы



Определение серого IP (Внутренней сети)


Внутренние сети широко используются в OpenVPN технологии, были мысли определять их наличие путем измерения TTL приходящего к серверу и минимально-возможное значение при доставке пакета.

Способ быстро был опровергнут — путь к ресурсу и от ресурса может не совпадать(материал) и метод будет давать больше сбоев, чем правильных ответов.

Однако применение все-же есть, по умолчанию TTL в Linux равен 64, в Windows — 128. Такие большие различия помогут определить OS удаленного хоста в некоторых случаях.

Определение использования фаервола (Для Win)


Метод очень простой, однако подходит только для Win систем где широко используются продукты наподобие Kaspersky Internet Security. Размещая код вируса в картинке отследить её блокировку не сложно — ресурс может быть заблокирован надолго, в кэш картинка никогда не ляжет.

Сканирование хоста


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

Заключение


Если у вас есть свой сайт, подумайте, а вам надо столько проблем из-за одной фичи?

UPD1:
baadf00d в комментариях напомнил о утечках DNS(позволяют определить используемый DNS-сервер, иногда бывает провайдерским).

Публичные сервера от Google:
8.8.8.8 8.8.4.4
Настройка Firefox(about:config):
network.proxy.socks_remote_dns = 1
Tags:httpimgcsrfанонимностьбезопасностьttl
Hubs: Information Security
+37
32k 210
Comments 20

Popular right now

Information Security Officer
to 275,000 ₽SmartTel PlusRemote job
Application Security Engineer
from 3,300 €ExnessЛимассол
Application Security
from 100,000 to 150,000 ₽PleskНовосибирскRemote job