Приветствую всех!

Многие из нас уже знают, что POS-terminal'ы и пин-пады обычно собираются на базе заказных чипов, даташиты на которые не найти. Но, понятное дело, так было далеко не всегда. И мне стало интересно: а что, если попробовать найти такой древний терминал, отреверсить его схему и написать что-то под него, не имея ни SDK, ни документации?



Итак, в сегодняшней статье разберём и разберёмся, как запустить раритетный пин-пад из начала двухтысячных годов. Попутно разберёмся с прошивкой старых защищённых микроконтроллеров и узнаем, как они работали. Традиционно будет много интересного.

Суть такова


Когда-то давно я уже писал пост про то, как работают пин-пады и что у них внутри.



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

Но в лучшие годы всё было совершенно иначе. А как оно было, сейчас и будем разбираться.

Обзор оборудования




Так получилось, что в мои руки попал пин-пад Hypercom HFT106. Девайс очень старый, начала двухтысячных годов. По виду он тоже сильно отличается от привычных нам, напоминая то ли калькулятор, то ли какой-то сервисный прибор. Слот для смарт-карт расположен в задней части, карта вставляется вертикально.



Обратная сторона. Тут ничего интересного, только порт 6P6C.



А вот и пример терминала, к которому такой девайс подключался. Это Hypercom T7PS, древний аппарат на процессоре Z80. Но про этот экземпляр поговорим как-нибудь потом.

Внутренности


Само собой, чтобы узнать, на чём он собран, девайс надо разобрать.



Здесь это весьма проблематично — мало того, что он залит смолой, так ещё и к крышке приварена металлическая скоба, погруженная в эпоксидку. Из-за этого неразрушающая разборка невозможна. Крышку эту в итоге пришлось отломать.



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



Дисплей, обычный 1602.





Модуль считывателя карт. В одном из разъёмов находилась SAM-карта, второй оказался пуст. Интересно, зачем он вообще, в залитом-то корпусе… На этой же плате находится концевик тампера.



SAM-карта. Обратная сторона маркировки не имела.

Что же внутри этого пин-пада?


Само собой, вопрос о том, на базе чего собрано данное устройство, так и остался открытым. Пришлось гуглить. На форуме nedoPC кто-то уже разбирал подобный терминал. Модель, правда, была другой, HFT105. После нескольких часов ковыряния эпоксидки и изучения фотографий платы было выяснено, что HFT106 является по сути более защищённым аналогом HFT105. По схемотехнике они абсолютно идентичны.



Плата терминала HFT105 крупным планом.

DS5002FP


Итак, пин-пад оказался собран на базе защищённого микроконтроллера от Dallas. Штука эта весьма интересная — по сути это 8051-совместимый МК, специально разработанный для подобных применений. У этого контроллера нет пользовательского ПЗУ, вся программа загружается в SRAM.



Вот его структурная схема. Видно, что для работы с внешней памятью все данные на шине тоже зашифрованы, а также обфусцированы (периодически МК читает из памяти случайные значения для защиты от сканирования шины логическим анализатором). Также имеется аппаратный вход тампера (Self-Destruct input), при активации которого сбрасываются ключи и векторы прерываний.

Для защиты от реверс-инжиниринга существовали доступные под заказ ещё более защищённые версии этого чипа, обладающие контуром безопасности прямо на кристалле, который защищает чип от вскрытия и исследований электронным микроскопом. В качестве алгоритма шифрования используется DES с ключом длиной в 64 бита, также по усмотрению заказчика мог быть предусмотрен проприетарный алгоритм шифрования. МК оборудован аппаратным генератором случайных чисел (если верить даташиту, принцип основан на девиациях частоты кварца и внутреннего генератора, которые измеряются контроллером), использующимся для генерации ключей.



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

Софт


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


SDK для столь экзотического контроллера без проблем можно найти: он имеется в составе Keil для МК MCS-51. Скачиваем Keil, открываем Device Database и устанавливаем поддержку для этого МК.

Теперь очередь заливки софта в контроллер. И тут всё весьма интересно: никакой программатор для этого не понадобится.

MTK2


Как ясно из описания МК, прошивка у него хранится в SRAM, которая сбрасывается при нарушении целостности контура. Логично, что загрузка прошивки должна осуществляться в уже собранное устройство.



Если отковырять одну из резиновых ножек, то можно увидеть там вырез, где скрываются два торчащих из смолы штырька. Один из них — земля, другой — PROG. Если их замкнуть, то при подаче питания будет запущен расположенный в масочном ПЗУ загрузчик, задача которого — поместить пришедшую по UART программу в SRAM. Перемычка на эти штырьки не налезала, поэтому я просто запихал туда фольгу от обёртки жвачки.


Теперь очередь софта для прошивки. Есть такая утилита как Dallas Microcontroller Toolkit (MTK2). Она предназначена для заливки HEX-файла с программой в целый модельный ряд МК от Dallas. Среди всех прочих есть и наш экземпляр.

Подключение


Пин-пад подключается к терминалу по интерфейсу RS-422. Внутри он реализован на базе двух трансиверов RS-485, один из которых включён всегда на приём, а другой — на передачу.



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



Так получилось, что месяцем ранее я разобрал другой терминал — Hypercom Optimum T4220. Именно из его интерфейсного модуля и были позаимствованы все нужные компоненты — микросхема, разъём 6P6C и кабель от пин-пада. В принципе, ничто не мешает использовать два трансивера RS-485, как это реализовано в пин-паде.

Схемы девайса с форума nedoPC. Скопировал сюда на всякий случай









Первый запуск


Итак, подключаем девайс к компьютеру. В качестве преобразователя USB-UART выступила традиционно Arduino. Замыкаем контакты и подаём питание.


Теперь открываем MTK2 и пытаемся установить соединение с загрузчиком. И оно работает!
Само собой, если подать питание просто так, то ничего не будет — из-за севшей батарейки оригинальная прошивка давно утрачена.

Загрузчик




Если открыть список команд, то можно заметить, что среди них есть возможность прямо из загрузчика управлять портами. Для проверки попробуем завести пищалку. При помощи команды P выставляем высокий уровень на соответствующей ножке, и терминал начинает непрерывно пищать. Ну что же, схема нас не обманула, HFT106 действительно во многом близок к HFT105.

Официальный порядок загрузки прошивки такой:

  1. F. Затереть SRAM.
  2. L. Залить HEX.
  3. D. Прочитать память.
  4. V. Проверить правильность записи.
  5. C. Сверить CRC.

В ходе выполнения этих операций происходит очистка памяти, после чего ГСЧ генерирует ключ (он является неизвлекаемым и недоступен для чтения), которым шифруется прошивка. Если выполнение программы загрузчика при этом не было прервано (то есть если не была выполнена команда E или если МК не был сброшен), то возможно и чтение содержимого ОЗУ, что используется для верификации.

После того, как программа успешно залита, необходимо установить командой Z флаг защиты, блокирующий доступ к памяти. Отныне её содержимое будет закрыто навсегда, загрузчик или нечто другое извне получить доступ к нему не сможет. Операция эта необратима, если данный бит взведён, то обнулить его можно либо полной очисткой памяти, либо командой U, которая сбрасывает ключи (что тоже приводит к потере информации).

Пишем первую программу


Ну что же, время написать что-то под этот девайс. Начнём, конечно, с классического микроконтроллерного «Hello, world!» — с вывода текста на экран.
Дисплей здесь работает в восьмибитном режиме, все его линии данных подключены к порту P2. Для управляющих линий отведён P3. Итак, тестовая прога получилась вот такая:

#include <REG52.H>                /* special function register declarations   */
                                  /* for the intended 8051 derivative         */
#include <stdio.h>                /* prototype declarations for I/O functions */


#ifdef MONITOR51                         /* Debugging with Monitor-51 needs   */
char code reserve [3] _at_ 0x23;         /* space for serial interrupt if     */
#endif                                   /* Stop Exection with Serial Intr.   */
                                         /* is enabled                        */

/*------------------------------------------------
The main C function.  Program execution starts
here after stack initialization.
------------------------------------------------*/
void delay(void) {
unsigned long n;
	for(n = 0; n < 100; n++);;
}

void lcdSend(int isCommand, unsigned char toLCD) {
	P3 &= ~(1 << 7);
    if(isCommand == 0) P3 |= (1 << 6);
	else if(isCommand == 1) P3 &= ~(1 << 6);
    delay();
	P2 = toLCD;
	P3 |= (1 << 5);
	delay();
	P3 &= ~(1 << 5);
	delay();
}
void lcdCommand(unsigned char cmd) {
    lcdSend(1, cmd);
}

void lcdChar(const char chr) {
    lcdSend(0, chr);
}

void lcdString(const char* str) {
    while(*str != '\0') {
        lcdChar(*str);
        str++;
    }
}
void main (void) {
/*------------------------------------------------
Setup the serial port for 1200 baud at 16MHz.
------------------------------------------------*/
#ifndef MONITOR51
    SCON  = 0x50;		        /* SCON: mode 1, 8-bit UART, enable rcvr      */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
    TH1   = 221;                /* TH1:  reload value for 1200 baud @ 16MHz   */
    TR1   = 1;                  /* TR1:  timer 1 run                          */
    TI    = 1;                  /* TI:   set TI to send first char of UART    */
#endif

   lcdCommand(0x38);
   lcdCommand(0x01);
   lcdCommand(0x06);
   lcdCommand(0x0C);
   lcdCommand(0x80); 
   lcdString("Hello, Habr!");
	while(1);;
}



Инициализация дисплея абсолютно стандартная, подробно расписывать её не вижу смысла.
Собираем проект и в папке с ним получаем *.hex-файл с готовой прошивкой.


Теперь открываем MTK2, выбираем в меню «Load SRAM», выбираем нашу прошивку. По окончании загрузки отправляем команду E.
И, если всё было успешно, на экране загорится примерно следующее:


Ну что же, всё успешно.

Клавиатура


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

#include <REG52.H>                /* special function register declarations   */
                                  /* for the intended 8051 derivative         */
#include <stdio.h>                /* prototype declarations for I/O functions */

#ifdef MONITOR51                         /* Debugging with Monitor-51 needs   */
char code reserve [3] _at_ 0x23;         /* space for serial interrupt if     */
#endif                                   /* Stop Exection with Serial Intr.   */
                                         /* is enabled                        */

/*------------------------------------------------
The main C function.  Program execution starts
here after stack initialization.
------------------------------------------------*/
void delay(void) {
unsigned long n;
	for(n = 0; n < 100; n++);;
}
char s[16];
char symbols[4][4] = {{'E', '0', 'R', 'C'},
   	              {'9', '8', '7', 'B'},
		      {'6', '5', '4', 'A'},
		      {'3', '2', '1', 'Z'}};
char symbolsP0[4] =  {'L', 'K', 'J', 'I'};
void lcdSend(int isCommand, unsigned char toLCD) {
	P3 &= ~(1 << 7);
    if(isCommand == 0) P3 |= (1 << 6);
	else if(isCommand == 1) P3 &= ~(1 << 6);
    delay();
	P2 = toLCD;
	P3 |= (1 << 5);
	delay();
	P3 &= ~(1 << 5);
	delay();
}
void lcdCommand(unsigned char cmd) {
    lcdSend(1, cmd);
}

void lcdChar(const char chr) {
    lcdSend(0, chr);
}

void lcdString(const char* str) {
   while(*str != '\0') { //*str != '\0'
        lcdChar(*str);
        str++;
    }
}
void main (void) {
   int n1, i, j, k;  
   lcdCommand(0x38);
   lcdCommand(0x01);
   lcdCommand(0x06);
   lcdCommand(0x0C);
	while(1) {
		P1 = 0x0F;
		P0 |= (1 << 7);
		for(i = 4; i < 8; i++) {
		for(j = 4; j < 8; j++) P1 |= (1 << j);
		P1 &= ~(1 << i);
		for(k = 0; k < 4; k++) {
			if(((P1 >> k) & 1) == 0 ) {
				P3 &= ~(1 << 4);
				n1 = P1;
				sprintf(s, "%X", n1);
				lcdCommand(0x80); 
				lcdString("Scanc0de: ");
				lcdString(s);
				lcdCommand(0xC0);
				lcdString("Key: ");
				lcdChar(symbols[i-4][k]);
				for(j = 0; j < 30; j++)	delay();
			}
			else {
				P3 |= (1 << 4);
			}
		}
	}
		P0 &= ~(1 << 7);
		for(i = 0; i < 4; i++) {
			if(((P1 >> i) & 1) == 0 ) {
				P3 &= ~(1 << 4);
				n1 = P1;
				sprintf(s, "%X", n1);
				lcdCommand(0x80); 
				lcdString("Scanc0de: ");
				lcdString(s);
				lcdCommand(0xC0);
				lcdString("Key: ");
				lcdChar(symbolsP0[i]);
				for(j = 0; j < 30; j++)	delay();
			}
			else {
				P3 |= (1 << 4);
			}
	}
}
}

Запускаем, и вот результат:



А что же насчёт банковских функций?


Увы, у меня нет никакого софта или документации на пин-пады или терминалы Hypercom. Пожалуй, по этим терминалам информации в интернете меньше всего.
Что же до платёжных функций (хранения ключей, работы с картами), то аппаратной их поддержки в микроконтроллере нет. DS5002FP был чипом общего назначения (и предназначался, к слову, не только для платёжных терминалов, но и для тех областей, где была нужна защита от реверс-инжиниринга), так что всё было реализовано средствами почившей прошивки.



Из других терминалов, работавших на базе такого чипа, мне известен Castles CIT7000, для которого я даже смог найти SDK. Увы, самой железки у меня нет.

Вот как-то так


Увы, сейчас реально применить для чего-то девайс не представляется возможным: батарейка давно села, а поменять её, не разрушив корпус, не представляется возможным. По сути срок жизни девайса ограничен зарядом батарейки, после исчерпания которого прошивка держится в памяти только до выключения питания. Тем не менее, было очень интересно попробовать запустить этот раритетный экземпляр.
Такие дела.

Ссылки





Возможно, захочется почитать и это:


Комментарии (20)


  1. Squoworode
    22.11.2023 09:47
    +1

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

    Но ведь можно разрушить батарейку


    1. MaFrance351 Автор
      22.11.2023 09:47
      +1

      ...но сначала надо до неё добраться.


      1. Squoworode
        22.11.2023 09:47

        Так вон же она, на фото, разве нет? Полмиллиметра эпоксидки затекло на верхнюю плоскость, да две точки сварки на ней же.


        1. MaFrance351 Автор
          22.11.2023 09:47

          Для этого надо отковырять крышку. Которая, в свою очередь, вморожена в эпоксидку. К ней приварен кусок профиля, который погружен в смолу до её застывания.


          1. MajorMotokoKusanagi
            22.11.2023 09:47

            Эпоксидка химически крайне стойкая?


            1. MaFrance351 Автор
              22.11.2023 09:47

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


          1. Squoworode
            22.11.2023 09:47

            Я не понял, разве это не было отковыряно в процессе написания статьи?


            1. MaFrance351 Автор
              22.11.2023 09:47

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


  1. Radisto
    22.11.2023 09:47
    +3

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


    1. MaFrance351 Автор
      22.11.2023 09:47
      +2

      Хотя свой срок службы девайс наверняка отработал. Производитель уверяет, что батарейка держит лет десять минимум.


  1. Kurochkin
    22.11.2023 09:47
    +1

    Интересное развлечение, спасибо.

    Раз уж вы используете устаревшие терминалы в качестве доноров - LCD от них не пробовали запускать? Упомянутые Hypercom T42xx к примеру легко разбираются и дисплей оттуда пригодился бы для самоделок. Вопрос только в распиновке.


    1. MaFrance351 Автор
      22.11.2023 09:47
      +1

      T2100 интереснее - его полностью отреверсили. У T4220 дисплей без маркировки, не смог найти. Надо логическим анализатором тыкать. А вот на принтер даташит легко гуглится.

      Вообще, T4220 штука не слишком интересная. Процессор заказной, JTAG не выведен нигде...


      1. Kurochkin
        22.11.2023 09:47

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


        1. MaFrance351 Автор
          22.11.2023 09:47

          О. Значит, просто забыл уже. Но тоже не нашёл ничего.


    1. Ivan-Kopylov
      22.11.2023 09:47

      LCD от какого-то Ingenico у меня запустился вот по этому рецепту:

      http://mcustuff.blogspot.com/2013/01/pro59801-lcd-module-hack.html

      https://forum.arduino.cc/t/finding-out-how-a-graphic-lcd-works/14637


      1. MaFrance351 Автор
        22.11.2023 09:47

        Это дисплей от терминала Ingenico 5100.


  1. shiz0id
    22.11.2023 09:47
    +1

    Увы, сейчас реально применить для чего-то девайс не представляется возможным

    Калькулятор можно

    Но как батарейку перепаять - вопрос.


    1. MaFrance351 Автор
      22.11.2023 09:47
      +1

      Ну, или пульт для чего-нибудь...

      Тут проще выкинуть штатную электронику и поставить что-то более подходящее.


      1. tormozedison
        22.11.2023 09:47
        +1

        И переделать в кодовый замок.


        1. MaFrance351 Автор
          22.11.2023 09:47
          +2

          С поддержкой входа по карте, как в отеле?