Jsou vaše peníze u Citibank v bezpečí?
Platby pomocí platebních karet jsou dnes již neodmyslitelnou součástí elektronického obchodování. Konkrétní implementace platebních bran se liší a v tomto článku bychom chtěli rozebrat platební bránu Citibank a její implementaci programu na počítání kontrolního součtu zpráv. Jsou vaše peníze u Citibank v bezpečí?
Na úvod vás zlehka zasvětím do tajů bezpečného programování. Jazyk C/C++ používá k ukládání textových řetězců do paměti takzvané NULL-terminated řetězce. V praxi to znamená, že má program na zásobníku kus paměti, který považuje za řetězec do té doby, než narazí na znak NULL (jenž je reprezentován znakem s hodnotou 0). Bohužel jazyk C nemá možnost zajistit, aby program zapisoval pouze do té části paměti, která byla pro řetězec předem vyhrazena (alokována), a pokud si programátor nedá pozor, může dojít k přepsání dat mimo tuto vyhrazenou paměť. Jelikož jsou na zásobníku uložena i data, která určují, na jakou adresu se má po ukončení funkce vrátit řízení programu, může dojít k jejich (ať už záměrné nebo nechtěné) změně a tím ke změně programu. V lepším případě se pak program chová nedefinovaně, v horším umožní případnému útočníkovi spustit vlastní kód. Tato chyba se nejčastěji nazývá „buffer overflow“ (přetečení bufferu) a je jednou z nejčastějších programátorských chyb zneužívaných pro útoky na Internetu.
Jistě už tušíte, kde asi udělali indičtí programátoři chybu v programu pro počítání kontrolního součtu, který je nabízen ke stažení na adrese: http://citiconnecttest.citibusinessdirect.com/CitiConnect/default.htm
Ano, hádáte správně. Jedná se o zapisování do bufferu s pevnou velikostí bez specifikování horní meze, a to hned na několika místech. Nebudu zde vypisovat všechny výskyty, uvedu jen několik do očí bijících případů:
Funkce Transpo(string, Key) – první vstupní parametr je sestavený řetězec s parametry zprávy posílané platební bráně, druhý parametr je takzvaný Working Key, s jehož pomocí je ze zprávy vypočten kontrolní součet.
Tato funkce obsahuje definici proměnných „char trans[500]“, „char str_bin[8000]“, tedy máme na zásobníku místo o velikosti 8.000 byte. Nyní si spočítáme délku vstupního řetězce řádkem „slen = strlen(string);“, dále pak pomocnou velikost „leng = slen * 8“, následně do proměnné str_bin uložíme číselnou reprezentaci ASCII znaků ve vstupním řetězci funkcí „asctobin(string,slen,str_bin);“ (která uvnitř také obsahuje buffery o velikosti 8.000 znaků a nikde nekontroluje, nejsou-li vstupní data „delší“ než alokovaná část paměti. Následuje smyčka, která má za úkol vzít každý šestnáctý znak z překódovaného vstupního řetězce počínaje (slen MODULO 16):
for(i=vlen;i<leng;i+=16) strncat(trans,str_bin+i,1);
Opomeneme-li to, že vymyslet takto neefektivní implementaci stálo jistě spoustu práce celý vývojový tým programátorů, zůstává ve vzduchu viset otázka:
Co se stane, když délka vstupního řetězce bude delší než 1.000? Za prvé budeme kvůli „str_bin+i“ číst mimo paměť vyhrazenou pro buffer str_bin (leng = délka vstupního řetězce * 8). Za druhé budeme díky strncat(trans,…) zapisovat mimo paměť vyhrazenou pro buffer trans.
Správná implementace této smyčky by měla vypadat:
if (leng>=8000) exit(1); /* spatna vstupni data */ for(i=vlen,j=0;i<leng; i+=16, j++) trans[j] = str_bin[i]; trans[j] = 0;
Tím zajistíme, že proměnná „i“ nabude maximálně hodnoty 7.999 a proměnná „j“ maximálně hodnoty 499. A zároveň urychlíme chod programu, protože v každém průchodu smyčkou nepřipojujeme znak na konec řetězce, kdy program musí pokaždé procházet řetězec od začátku a hledat znak NULL, ale zapisujeme jej na přesně definovanou pozici a řetězec finálně ukončíme NULL znakem až po celém průběhu smyčkou.
Takovýchto chyb je v kódu knihovny nasekáno více a na některých místech (slen = strlen(string); string[slen] = 0; – aneb nalezneme znak NULL v řetězci, což dělá funkce strlen a následně na tuto pozici opět zapíšeme NULL) – mám pocit, že programátor nevěděl, co dělá.
Neměl jsem možnost takto prohlédnout zdrojový kód zbytku platební brány Citibank a pevně doufám, že tento kus kódu, který mi prošel pod rukama je ojedinělý výtvor, který byl programován ve čtyři ráno po týdnu beze spánku a desáté kávě. Obávám se však, že zbytek platební brány programovali ti samí lidé. A z toho mi běhá mráz po zádech.
Na straně obchodníka se tento špatně napsaný kód dá zabezpečit tak, že obchodník zajistí ověření velikostí a validity dat pro kontrolní součet sám. Bohužel nikde v dokumentaci není napsáno, jak velká vstupní data mohou být a obchodník, který si pouze nainstaluje již předkompilované binární knihovny, může být nemile překvapen. Co je na tomto případu horší, je fakt, že podobné chyby se mohou vyskytovat i v interním software platební brány a ty mohou být potenciálně v nejhorším případě zneužity k manipulaci s vašimi penězi.
Autor Citibank na problém upozornil, nedostalo se mu však odpovědi.
Školení Twitteru s Danem Dočekalem

- Jak komunikovat na Twitteru.
- Jak začlenit Twitter do marketingového mixu vaší firmy.
- Jak využít Twitter jako zdroj informací pro rozhodování.
- Nabízíme i školení Facebooku a Google+.
Detailní informace o školení Twitteru »
Přehled názorů
Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

EU chce vědět, kolik je vám let
Microsoft chce změnit jak vyhledáváme, Apple bude mít vlastní mapy
Apple vzorem v neplacení daní a šéf Yahoo lhal o vzdělání
Sportem ku zdraví a počítačové invaliditě
Aktualizace a zranitelnosti: Mocná zbraň i Achillova pata