Візуалізація і декодування даних з магнітних АТМ-карт

Предмет інтересу цієї публікації — зчитування і декодування даних з другої доріжки банкоматовской картки в умовах дефіциту обладнання і засобів.

Для початку наведу сухі теоретичні знання. Якщо теорія не цікавить — можна пропустити.

Плівка або доріжка являє собою пластик, з нанесеними найдрібнішими (дуже дрібними) частками феромагнетика — речовини, що володіє залишковою намагніченістю. Феромагнетик, крім того, що він дуже дрібний і не розрізнюється в шкільний або ремонтний мікроскоп, так він ще має форму, схожу на стільники, гранули або кристали.

В процесі нанесення на поверхню він відразу проходить орієнтацію — тобто повертається відповідно лініям магнітного поля. Цим досягається деяке покращення магнітних властивостей доріжки. Далі наноситься фіксатор і захисний шар. Все, змінювати свого становища фізично вони не можуть, зміна напрямків векторів магнітних індукцій (та сама залишкова намагніченість, магнітні лінії) може відбуватися тепер тільки на молекулярному рівні. Але не потрібно думати, що смужка після виготовлення відразу володіє магнітними властивостями. По-перше, якщо вони є, то занадто малі, по-друге, напрями векторів орієнтовані випадковим і компенсують один одного.

Вносимо таку смужку в зону дії магнітного поля і чекаємо. Чекаємо, поки відбудеться перестрибування енергетичних конячок через бар'єр і вектори магнітної індукції цих частинок не будуть збігатися за розміром з векторами зовнішнього магнітного поля, а самі частинки не запасут деяку енергію і не стануть справжніми постійними магнітами. Все, тепер цією смужкою можна притягувати цвяхи і шокувати мавп у зоопарку.

Існує якесь первинне намагнічування, що переводить незайману доріжку зі стану летаргії в стан залишкової намагніченості. Для повного уявлення потрібно розглянути картинку гістерезису, вона відображає всі можливі магнітні стану наших феромагнетиків. Серед яких є і два стани повного розмагнічування.

Тепер ближче до того, як все відбувається при запису і читання на реальній магнітній смузі картки.

Перше. При запису головка, яка створює поле біля магнітної смуги, насправді створює поле не поруч з нею, а в ній. Щоб це зрозуміти, треба згадати просте правило: струм тече по шляху найменшого опору. А тепер уявімо підкову, так, звичайну підкову від коня. Вона має розріз, притуліть підкову розривом перпендикулярно смузі. Це і є сучасна головка для подібних записів.Тобто вся справа в розриві, який майже торкається магнітній смузі.

Обмотаємо підкову дротом і пустимо електричний струм, підкова стане електромагнітом, магнітне поле потече по підкові і в місці розриву підкови зустріне сильний опір — повітря або якийсь спеціально підсунутий туди діелектрик.

Що залишається робити магнітному полю? Піти по шляху найменшого опору — по самій магнітній смужці! Стрибнувши на смужку, замкнутися через неї. Що нам на руку.

Спосіб представлення дискретної (вважай надалі — цифрової інформації) на такий смужці теоретично може сильно відрізнятися. Можна підставити себе на місці конструктора і спробувати промоделювати процеси запису та зчитування. При цьому в наших руках такі козирі:

— інформацію потрібно записувати ділянками фіксованої довжини;
— записувати на смужку можна 2 типу ділянок, тобто з різними напрямками силових ліній магнітного поля (векторів магнітної індукції і купи інших величин, на що нам, втім, пофіг). Для простоти позначимо їх як SN і NS;
— записувати на смужку можна типи ділянок SN і NS, але кожен з них може мати різну ступінь намагнічування, тобто можна визначити градацію ступеня намагніченості для будь-якого з ділянок, наприклад, домовившись з вами про те, що будемо приписувати справа цифру від 0 до 9, що виражає ступінь намагніченості в зростанні;
— зчитування можливе за умови зміни магнітного потоку головки, яка проходить поряд з намагніченої смужкою. Змінний магнітний потік проходить через сердечник (все тугіше саму підкову) і в результаті на виводах обмотки, розташованої на сердечнику, з'явитися змінне напруга.

Таким чином, змінювати воно може тільки при зміні магнітного потоку. А він може мінятися в трьох випадках:

а) зміна напрямків ліній магнітного поля. Тобто ділянки повинні йти в такому порядку:
(SN)(NS)(SN). В результаті отримаємо, грубо кажучи, 2 рази пульсуючий струм;
б) зміна інтенсивності магнітний полів ділянок. Наприклад, така послідовність ділянок повинна викликати появу\зміна електричного струму в головці — (SN1)(SN2)(SN9)(SN3) (3 зміни в амплітуді ел.струму головки), а ось така вже немає — (SN5)(SN5)(SN5)(SN5)(SN5);
в) комбінація а і б (SN5)(NS5)(NS6).

Начебто проблем немає, бери, використовуй будь-який з варіантів для представлення нулів дискретних ділянок. Так, для запису все просто. Проблеми з'являються при зчитуванні. Один з основних факторів, який ставить палиці в колеса — це швидкість зчитування, тобто швидкість протягання стрічки під голівкою. Винайдені людиною пристрої для ручного протягування карти через них не можуть дозволити собі точно розпізнати швидкість без додаткових хитрувань, з якою рука проводить карту (це можливо, але потрібно робити додаткову тактову магнітну чи іншу лінію). В банкоматах простіше і достатня точність може бути реалізована.

Так в чому ж проблема? Ну, різна швидкість і фіг би з нею.

А ви спробуйте, будучи простим рядовим пристроєм розберіть наступну послідовність:
(SN)(NS)(NS)(SN)(NS)? (послідовність 1)
(1) (2) (3) (4) (5)

Що можна сказати про цю послідовності? Тільки те, що на викличе рівно 3 рази (між ділянками 1 і 2, 3 і 4, 4 і 5) зміну полярності електричного поля в голівці.

Якщо прийняти перший приходить в голову варіант кодування 0 і 1 зміною полярності ділянок магнітного поля, то впевнено можна сказати, що SN — це 1, а NS — це 0, і отримавши стрибок напруги в сторону +, можна сказати, що стався перехід з 1 на 0. Значить, розпізнано 2 ділянки. А от далі, де 2 і 3 стоять поруч — (NS)(NS) ніякої зміни не буде, але ж відомо, що на цьому місці останнє, що було розпізнано за попереднім стрибка напруги — це 0! Але спробуй, доведи скільки точно нулів на цій ділянці при різних швидкостях руху, два або більше. Те сть що послідовність 1 саме послідовність 1, а не, наприклад, ця:
(SN)(NS)(NS) (NS) (NS) (SN)(NS)? (послідовність 2)
(1) (2) (3) (помилка) (помилка) (4) (5)

Між 3 і 4 все рівно — стрибок напруги відбувається у бік — і можна сказати, що 3 — це 0, а 4 — це 1. Виходів із ситуації маса, від лінії синхронізації до частотного кодування. Яке і є основним в магнітних картах — це подвоєння частоти F\2F.

(NS)(SN)(NS)(NS)(SN)(SN)(NS)(SN)(NS)(SN)
( 1 )( 0 )( 0 )( 1 )( 1 )

Зміст, здається, зрозуміла. Для кодування 1 використовується факт інтерпретації стрибків напруги — подвоєння частоти зміни полярності ділянок для кодування одного елемента. Якщо придивитися уважніше, то можна побачити, що таке кодування повністю усуває недоліки кодування, представленого вище при деяких умовах.

Припустимо, ми зупинимо карту на ділянці (NS)(NS). Можна подумати, що пристрій зіб'ється і неправильно порахує число нулів, тобто візьме (NS)(NS)(NS)(NS) за 00. Насправді цього не відбудеться, тому що при кодуванні умовою переходу на наступну групу ділянок є зміна полярності, а її не відбувається і пристрій просто ставить 0 і чекає зміни полярності (чекає хоч до безкінечності) для того, щоб знову запустити свій лічильник — генератор для розпізнання наступної групи ділянок. Питання, як пристрій визначає частоту появи змін полярності, звичайно, цікаве, але зараз не потрібний.

Краще один раз побачити, ніж сто разів прочитати. Заглянемо в вміст доріжок магнітних карт і подивимося, чи можна в домашніх умовах однозначно зрозуміти, що ж на них написано. Попутно отримавши певний інструмент для візуальної оцінки стану доріжок.

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

Звичайні тирсу або металева пил не підійдуть, занадто великі частинки. Пропонується використовувати частинки тонера для картриджів принтерів. Вони дуже ретельно оброблені, однорідні, і деякі з них мають у своєму складі магнітні пігменти.

image

В оригіналах-джерелах ідеї пропонується використовувати суміш тонера і крохмалю, але це, мабуть, з тієї причини, що ідея оцінювати стан карток з допомогою тонера або спеціального спрея з'явилася давно, а тонери тоді були специфічними. Тому, наприклад, нам рівнятися на Францію від 1999 року не варто. Ми підемо в сучасний магазин і придбаємо тонер з магнітними пігментами (як показано на малюнку), бажано кольоровий.

Обсипав карту і постукавши її об стіл для струшування надлишок тонера отримуємо в своє розпорядження цей знову відкрився світ. На смужці відразу видно всі дефекти ділянок, одержувані картою. У деяких побутових випадках це може стати в нагоді.

Ми ж повинні продовжити. Весь інтерес в тому, щоб прочитати вміст карти маючи під руками тільки фотоапарат, лупу, або звичайно ж мікроскоп. Як стане зрозуміло далі, для аналізу другої доріжки з 3-їй достатньо фотоапарата. На малюнках представлені фотографії з середнього цифрового фотоапарата і з цифрового мікроскопа.

image

Вся доріжка №2 (ABA)

image

Вся доріжка №2 (ABA) з нанесеними в програмі paint орієнтирами.


І та ж сама доріжка, трохи крупніше:



Для зручності, звичайно ж, використовувати знімки з мікроскопа.

Отже, аналіз. Але спершу потрібно звернутися до стандартів:

ISO 7810 Physical Characteristics of Credit.Card Size Document
ISO 7811-1 Embossing
ISO 7811-2 Magnetic Stripe — Low Coercivity
ISO 7811-3 Location of Embossed Characters
ISO 7811-4 Location of Tracks 1 and 2
ISO 7811-5 Location of Track 3
ISO 7811-6 Magnetic Stripe — High Coercivity
ISO 7813 Financial Transaction Cards

Далі в правій стороні документа дивимося зверху вниз:
— Малюнок карти і її розміри 3.375×2,125 дюймів, один дюйм=2,54 см, виходить 85*54 мм Збігається з розмірами досліджуваної карти.
— Рядок «Magnetic Stripe Encoding — Financial Transaction Cards» показує відстань від краю карти в дюймах і характеристики доріжок (track) у вигляді своєрідної таблиці. Всього доріжок 3, кожна має свою назву:

TRACK 1 IATA
TRACK 2 ABA
TRACK 3 THRIFT

Щільність запису RECORDING DENSITY (bits per inch) для кожної з доріжок.
CHARACTER CONFIGURATION (including parity bit) «Пристрій символу», по суті, число біт, байт, з урахуванням біта парності й INFORMATION CONTENT (including control characters) вміст символів. Видно, що перша доріжка містить як цифри, так і літери, друга і третя містять тільки цифри — 40 цифрових символів.
Нижче і зліва розташовані розшифровки форматів доріжок.

У теорії, у нашій 2-ой доріжки ABA повинно міститися не більше 75 біт / дюйм. Тобто не більше 3,375 (довжина карти)*75(ємність на дюйм)=253,125 біт=253 біта на всю доріжку. Розмір байта — 5 біт, кодування тільки цифри, при цьому виходить 253/5=50 символів, але за стандартом їх 40. Зайві — це послідовність для синхронізації в самому початку доріжці — нулі.

5 бітне кодування розписано в посиланню нижче.

--Data Bits-- Parity
b1 b2 b3 b4 b5 Character Function
0 0 0 0 1 0 (0H) Data
1 0 0 0 0 1 (1H) "
0 1 0 0 0 2 (2H) "
1 1 0 0 1 3 (3H) "
0 0 1 0 0 4 (4H) "
1 0 1 0 1 5 (5H) "
0 1 1 0 1 6 (6H) "
1 1 1 0 0 7 (7H) "
0 0 0 1 0 8 (8H) "
1 0 0 1 1 9 (9H) "
0 1 0 1 1 : (AH) Control
1 1 0 1 0 ; (BH) Start Sentinel
0 0 1 1 1 < (CH) Control
1 0 1 1 0 = (DH) Field Separator
0 1 1 1 0 > (EH) Control
1 1 1 1 1 ? (FH) End Sentinel

Що ж, щоб почати, треба почати. Маючи таблицю декодування, напишемо програму розшифровки цивілізаційною. І так, нам же потрібен дамп, отриманий при візуалізації, он він (зрозуміло, трохи змінений, щоб приховати персональні дані, яких, до речі кажучи, там кіт наплакав):

000000000000000000000000000000000000000110111111100001000010000100001010101000101011000010000100001010110101000010000100010000010100010000010001000001101001110010010101101010100010110010000010010110110011010110101001000001000010101010101100000000000000000000

Ну і сама програма:

.686 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\shell32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data?
.data
Handle_File_Input dd 0
Handle_File_Result dd 0

InputFile db "Content_track_2.txt", 0
ResultFile db "Result.txt", 0
flStr OFSTRUCT <>
NBW dd ? , 0
NBR dd ?, 0

title_box db "[АВА] track-decoder", 0
ms1 db "Некоректний формат доріжки: положення стартовою послідовності [Start_Sentinel] не збігається з положенням першого одиничного біта, який зустрівся на доріжці.Різниця становить - Продовжити виконання ?", 0
ms2 db "Доріжка порожня-містить тільки нулі", 0
ms3 db "Відсутній або неможливо відкрити фаил Content_track_2.txt", 0
ms4 db "Виконання закінчено, результат у файлі Result.txt.Можна повторити виконання, при цьому файл вводу буде лічений наново, а рядок у ньому перегорнуто.", 0

bet db 254 dup (030h)
en db 0ffh
Start_Sentinel db "1010", 0ffh ;обрамлення рядка 

;bet db "00000000000000000000000000000000000000011011111110000100001000010000101010100010101100001000010000101011010100001000010001000001010001000001000100000"
;bey db "110100111001001010110101010001011001000001001011011001101011010100100000100001010101010110000000000000000"

result db 60 DUP(0)

val_0 db '.' ;00000
val_1 db 030h ;00001 - ансі
val_2 db 038h ;00010 - ансі
val_3 db '?' ;00011
val_4 db 034h ;00100 - ансі
val_5 db '?' ;00101.
val_6 db '?' ;00110
val_7 db '?' ;00111
val_8 db 032h ;01000 - ансі
val_9 db '?' ;01001
val_10 db '?' ;01010
val_11 db '?' ;01011
val_12 db '?' ;01100
val_13 db 036h ;01101 - ансі
val_14 db '?' ;01110
val_15 db '?' ;01111
val_16 db 031h ;10000 - ансі
val_17 db '?' ;10001
val_18 db '?' ;10010
val_19 db 039h ;10011 - ансі
val_20 db '?' ;10100
val_21 db 035h ;10101 - ансі
val_22 db 'M' ;10110 - ансі
val_23 db '?' ;10111
val_24 db '?' ;11000
val_25 db 033h ;11001 - ансі
val_26 db 'S' ;11010 - ансі
val_27 db '?' ;11011
val_28 db 037h ;11100 - ансі
val_29 db '?' ;11101
val_30 db '?' ;11110
val_31 db 'E' ;11111 - ансі

.code
start:
begin:
push OF_READWRITE
push offset flStr
push offset InputFile
call OpenFile
cmp eax, 0ffffffffh ;чето не то з файлом
jz ext ;нехай пользватель розбереться і повторить при необхідності
mov dword ptr [Handle_File_Input], eax
push FILE_BEGIN
push NULL 
push 0
push eax
call SetFilePointer ;встановимо вказівник на початок файлу
push 0
push Handle_File_Input
call GetFileSize
mov ebx, 254
cmp eax, ebx ;порівняймо на макс. можливий розмір другий доріжки
cmova eax, ebx ;вперто прочитаємо тільки 254 символу
push NULL
push offset NBW 
push eax 
push offset bet 
push Handle_File_Input
call ReadFile ;читаємо дамі

lea esi, [en-1] ;один кінець рядка
lea edi, bet ;другий кінець рядка
reverse:
cmp esi, edi
jbe end_reverse
mov al, byte ptr [esi]
mov ah, byte ptr [edi]
mov byte ptr [edi], al
mov byte ptr [esi], ah
dec esi
inc edi
jmp reverse
end_reverse:

;------ Пошук Start_Sentinel-------------------------------------------
mov edi, offset bet
mov al, 030h
mov ecx, 0ffh
repz scasb ;зразу проскануємо рядок до першого знака "1"
mov edx, edi
xor edx, offset [Start_Sentinel+1] ;якщо результат нульовий і вони дорівнюють то значить на доріжці одні нулі
jnz continue_1
push 0
push offset title_box
push offset ms2 ;порожній трек 
push 0
call MessageBoxA
jmp ext 
continue_1:

;-- недостатньо знайти перший одиничний символ і перевірити наявність відразу після нього (включаючи його самого) SS
;-- цей одиничний символ може бути помилкою, тому зразу проскануємо починаючи з нього - знайдемо комбінацію SS (якщо вона є)
;-- різниця між зміщенням знайденого SS і одиничним символом - виведемо її з повідомленням що результат може бути невірний

xor edx, offset [Start_Sentinel+1] ;откатим edx назад
mov eax, edi
mov ebx, offset Start_Sentinel
search_SS:
mov esi, eax
inc eax
mov ecx, -1
mov edi, ebx
repz cmpsb ;скільки байт співпало показано в ecx від'ємним числом
cmp cx, -6
loopnz search_SS
dec eax ;відкоригуємо тому що eax трохи втекло в циклі
sub eax, edx 
jz continue_2 ;збіглася локація першого біта і SS
push 4
push offset title_box
push offset ms1
push 0
call MessageBoxA ;привід для роздумів та вибору
;[ms+191]
cmp eax, 1
jnz ext
continue_2:

mov byte ptr [result], 'S' ;підтвердимо
dec esi ;дивимося на відразу після SS
mov ecx, 5
mov eax, offset [en-1]
sub eax, esi
xor edx, edx
div ecx
mov ecx, eax ;число ітерацій по 5
mov edi, offset [result+1]
mov ebx, offset val_0

pars:
lodsd
mov edx, eax
lodsb
sub al, 30h
sub edx, 030303030h
shl dl, 4
xor al, dl
shl dh, 3
xor al, dh
bswap edx
shl dl, 1
xor al, dl
shl dh, 2
xor al, dh
xlat
stosb
loop pars
push OF_READWRITE
push offset flStr
<habracut />
push offset ResultFile
call OpenFile
mov dword ptr [Handle_File_Result], eax
push FILE_BEGIN
push NULL 
push 0
push eax
call SetFilePointer ;встановимо вказівник на початок файлу
push NULL
push offset NBW 
push 60 
push offset result
push dword ptr [Handle_File_Result]
call WriteFile
ext:
push Handle_File_Input
call CloseHandle
push Handle_File_Result
call CloseHandle
push 4
push offset title_box
push offset ms4
push 0
call MessageBoxA ;привід для роздумів та вибору
cmp eax, 6
jz begin
exit:
push 0
call ExitProcess
end start

І, нарешті, сам результат:

S5224559648685547M08081211550005850000EM…

Який підозріло нагадує наскрайбированные на карті цифри і букви.

Наступна доріжка вже зашифрована, але про це вже іншим разом.

Корисні посилання

ru.wikipedia.org/wiki/Гістерезис
www.dataip.co.uk/Reference/MagneticCardBCD.php
stripesnoop.sourceforge.net/devel/layoutstd.pdf
книга Патріка Гелля — Магнітні карти і ПК.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.