Portál AbcLinuxu, 27. dubna 2024 15:56

Lokální útoky na operační systém linuxového typu

4. 12. 2007 | Tomáš Pelka
Články - Lokální útoky na operační systém linuxového typu  

Článek se zabývá otázkou lokální bezpečnosti, tedy takovou, která je realizována lokálně, nikoliv prostřednictvím sítě. Operační systém Linux byl vybrán z důvodu jeho rostoucí obliby, ale především jeho celkové vyšší transparentnosti a otevřenosti.

Úvod

Bezpečnost je velmi komplexní záležitost. Zjednodušeně by se dala představit jako skládanka, u níž je bezpodmínečně nutné zajistit správné složení do výsledného celku, ve kterém nebudou "díry".

Linux má už ve své podstatě v tomto ohledu dvě protichůdné vlastnosti. Ta kladná vychází z toho, že do něj přispívá velké množství lidí, a tudíž se velmi rychle rozvíjí. Se zmíněnou vlastností koresponduje velmi rychlá oprava chyb. Velké množství přispívatelů ale vytváří stinnou stranu problematiky. Chyby mohou být opraveny, ale také nevědomky do operačního systému zaneseny.

Vyvstává potřeba organizace, která by celý proces kontrolovala. Dojde-li v operačním systému k implementační chybě, je velmi složité ji později napravit. I když původní Unix nebyl přímo navržen s ohledem na bezpečnost, lze dnes unixové systémy, včetně Linuxu, zabezpečit poměrně dobře. Díky otevřenosti zdrojových kódů jádra a programů lze poměrně snadno prozkoumávat výhody a slabiny programů na té nejnižší úrovni a díky licenci GNU GPL či jakékoliv jiné OSS licenci tyto slabiny opravit nebo možnost jejich výskytu omezit. Otevřenost kódu zaručuje, že před námi nikdo nemůže nic skrývat. Navíc otevřenost nám umožňuje Linux vylepšovat a upravovat [1].

Vše však má svoji odvrácenou stranu. Nevýhoda filozofie tkví v tom, že stejně jako uživatelé mají přístup k otevřeným zdrojovým kódům také potenciální útočníci, kteří mohou tyto kódy zneužít ve svůj prospěch.

Používání bezpečných programů je jen část úkolu. Neméně důležité je služby také správně nakonfigurovat.

Pokusme se hackera identifikovat a lépe popsat. Hacker je člověk či raději programátor, který vnímá programování jako jistou formu uměleckého vyjádření a počítač jako umělecký nástroj. Hackeři jsou poháněni snahou po sebezdokonalení a řešení neobvyklých problémů novými cestami, touhou rozebírat a chápat. Tyto hodnoty poháněné vědomostmi se nazývají hackerskou etikou: uznání logiky jako formy umění, podpora svobodného toku informací překonávající všechny hranice a omezení s prostým cílem dosáhnout lepšího chápání okolního světa. Tato etika vychází ze stejné filozofie jako Pythagorejci ve starém Řecku, kteří měli podobnou etiku a subkulturu navzdory neexistenci počítačů [2].

Jak rozpoznat dobrého hackera, který přináší nový, kreativní pohled na technické vymoženosti, od toho špatného, zloděje čísel kreditních karet? Pro špatného hackera byl vymyšlen termín cracker, který popisuje špatného hackera a odlišuje jej od toho dobrého. Bohužel tento výraz není obecně často užíván. A tedy pojmy hacker a cracker v uších obecné veřejnosti splývají [2].

Exploitování programu

Exploitování je základem hackingu. Program není nic jiného než komplexní sada pravidel sledující určitý tok činností, která počítači říkají, co má dělat. Exploitování programu znamená přinutit programy vykonávat to, co chce útočník, dokonce i když je program navržen tak, aby tomu zabránil. Program může dělat jen to, k čemu je navržen. Bohužel to, co je napsáno se nemusí shodovat s tím, co programátor zamýšlel. Bezpečnostní díry jsou ve skutečnosti vady nebo přehlédnutí v návrhu programu nebo v prostředí, ve kterém program pracuje [1].

Často opakovaná programátorská chyba se nazývá off-by-one. Název napovídá, že jde o chybu, při níž se programátor splete o jedničku. Následující příklad vše vysvětlí. Představme si, že máme postavit plot o délce 20 m. Po dvou metrech bude sloupek. Kolik sloupků budeme potřebovat? Samozřejmě, bez dlouhého přemýšlení je odpověď 10. Ale to je špatně. Ve skutečnosti je jich potřeba 11. Někdy se tato chyba nazývá také fencepost error. Takovéto chyby často bývají nepostřehnuty, protože programy nejsou standardně testovány na všechny možné vstupní varianty. Jejich efekt se mnohdy neprojeví, ale když už se projeví, může dojít k lavinovému efektu a krom logiky programu může být narušena i bezpečnostní stránka [1].

Jeden nedávný omyl (cca před třemi lety) se přihodil i v OpenSSH. Byla tam nalezena chyba off-by-one v kódu pro alokaci kanálu. Tato chyba byla po objevení hodně exploitována. Kód obsahoval tuto podmínku if:

if (id < 0 || id > chanells_alloc)
a správně měl kód vypadat takto:
if (id < 0 || id >= chanells_alloc)

Toto je jen jeden příklad z mnoha. Existují ovšem chyby, jejichž exploitování není tak jednoduché. Mezi takové netriviální, obecné exploitovací techniky patří chyby přetečení paměti (buffer-overflow) a chyby ve formátovacím řetězci. S těmito chybami je nakonec možné zcela převzít vládu nad průběhem vykonávání programu. Nejběžnější technikou je propašování části škodlivého kódu a jeho spuštění. Takovým technikám se říká execution of arbitrary code (spouštění libovolného kódu). V následujících kapitolách bude tato chyba často skloňována.

Lokální útoky - přetečení paměti

V nadcházející části se budeme věnovat především chybně napsanému kódu. Chybně napsaný kód je velmi nepříjemná záležitost. Způsobuje časté havárie, ztráty dat a zbytečné úniky výpočetního výkonu. Jakkoliv může být takový kód při normální práci nepříjemný, zvykli jsme si na něj a počítáme s ním. Často zálohujeme, stahujeme aktualizace a bezpečnostní záplaty. Skutečný problém ale nastává, když je chyba v programu potenciálně zneužitelná útočníkem. Chybný kód představuje vstupní bránu pro řadu útoků, ať už lokálních nebo vzdálených. Existuje několik tříd programátorských chyb, které mohou způsobit vážné trhliny v bezpečnosti služeb nebo celého systému.

Největší problém nastává u programů, které mají nastaven suid respektive sgit bit. Takové programy by měly být programovány co nejpečlivěji, protože program běží s jinými právy, než s jakými byl původně spuštěn. Uživatel využívající takový program může kvůli chybě získat práva, která by vůbec získat neměl. U tohoto druhu programů je třeba dbát na to, aby byla práva odkládána ve správném čase a hlavně korektně. Nejúčinnější ochranou je dobrá a rychlá informovanost. Jen tak je možné provést odpovídající kroky vedoucí k nápravě.

Paměť

Dříve, než budou vysvětleny konkrétní programátorské chyby, které jsou využitelné k exploitování, je třeba říci pár slov o paměti, její segmentaci a deklaraci.

Paměť je dočasné úložiště, nic víc než bajty označené tzv. adresou. Bajty na jednotlivých adresách lze číst nebo zapisovat.

Procesor má vlastní paměť, která je relativně malá. Tyto části paměti se nazývají registry. Existují speciální registry, které udržují informace o vlastním spouštěném programu. Jeden z nejdůležitějších je EIP (extended instruction pointer). Jak název napovídá, jedná se o ukazatel ukazující na právě prováděnou instrukci. Dalšími důležitými registry pro vykonávání programu jsou EBP (extended base pointer) a ESP (extended stack pointer) [2]. Tyto informace jsou platné pouze pro procesory Pentium a kompatibilní.

Důležitou věcí v souvislosti s deklarací paměti je pořadí bajtů v čtyřbajtovém slovu na architektuře x86. Toto řazení je známé jako little endian, které říká, že nejméně významný bajt je první. Znamená to, že bajty slova, jsou uloženy v převráceném pořadí. Hexadecimální hodnota 0x12345678 v kódování little endian je v paměti uložena jako 0x78 0x56 0x34 0x12.

Občas se stane, že pole alokovaných bajtů není využito úplně. Za alokovanými bajty budou nevyužité znaky. V tom případě se použije nula (bitová nula nebo také znak null) pro ukončení řetězce. Ukončování řetězců nulovou hodnotou zvyšuje efektivitu a umožňuje funkcím s řetězcem lépe pracovat.

Paměť programu je rozdělena na pět segmentů: text, data, bss (block started by symbol, segment neinicializovaných dat), heap (halda) a stack (zásobník). Každý segment reprezentuje speciální část paměti, která je vymezena pro určité účely [3].

Segment text je někdy označován jako code. Jde o místo, kde se nacházejí instrukce strojového jazyka. Tato vlastnost však platí jen pro procesory vycházející z Von Neumannovy architektury, kde není oddělena paměť na datovou a instrukční. Naproti tomu procesory s Harvardskou architekturou mají zmiňované paměti odděleny, tudíž tento bezpečnostní problém odpadá. Navíc novější procesory obsahují ve své instrukční sadě příznak, který tyto paměti odlišuje.

Data a bss se využívají k ukládání globálních a statických proměnných.

Segment heap (halda) se používá pro ostatní programové proměnné. Celá tato paměť je řízena alokačními a de-alokačními algoritmy, které rezervují paměťové místo pro další použití.

Segment stack (zásobník) má také proměnnou velikost a používá se jako dočasné úložiště pro kontext volání funkcí. Segmenty heap i stack jsou dynamické a rostou proti sobě.

Přetečení paměti

Programovací jazyk C nepatří mezi jazyky silně typované. Odpovědnost za datovou integritu je ponechána na programátorovi. Kdybychom tuto odpovědnost nechali na překladači, výsledný kód by byl neúměrně velký. Optimalizace a efektivita výsledného kódu je cenou za zvýšenou pečlivost programátora. Kontrola programátora také zvyšuje náchylnost na přetečení paměti. Jakmile je proměnná v alokované paměti, neexistuje žádný mechanismus, který pohlídá, že se proměnná opravdu do alokované paměti vejde. Popsané skutečnosti jsou hlavním rozdílem oproti jazykům opravdu silně typovaným jako například C++ či Java. Máme-li například následující kus kódu:

void overflow_function(char *str){
    char buffer[20];
    strcpy(buffer, str);
}
int main() {
    char big_string[128];
    int i;
    for(i = 0; i < 128; i++){
         big_string[i] = 'A';
    }
    overflow_function(big_string);
    exit(0);
}
Výsledkem po kompilaci a spuštění je:
user@host:~$ gcc overflow.c -o overflow
user@host:~$ ./overflow
Neoprávněný přístup do paměti (SIGSEGV)

Ve funkci byl vytvořen buffer o velikosti 20 znaků, to je námi očekávaná hodnota. Do tohoto bufferu však vložíme 128 znaků. Z důvodu přetečení paměti program selže. Tato situace nahrává hackerovi. Programátor nepředpokládal, že někdo bude jako vstupní parametr funkce zadávat tolik znaků. Program, který jinak funguje naprosto normálně, najednou "spadne". Tato skutečnost programátora jen utvrdí v použití vstupního filtru, validátoru dat.

Přetečení zásobníku

Vraťme se ještě k předchozímu programu. Když se zavolá funkce overflow_function, vytvoří se na stacku rámec zásobníku. Když se funkce poprvé zavolá, vypadá rámec podobně jako na obrázku 1.1.

Když se funkce pokusí zapsat 128 bajtů dat do 20 bajtového bufferu, dojde k zapsání 20 bajtů do bufferu a zbylých 108 bajtů přepíše návratovou adresu, ukazatel na rámec a argument funkce. Když podprogram skončí, pokusí se pomocí záznamu o návratové adrese skočit zpět do hlavní funkce main(), ale tato adresa je přepsána nesmyslnou hodnotou, v našem případě samými A, což je hexadecimálně 0x41. Skočí tedy na adresu 0x41414141, která je neplatná. V každém případě program skončí. Tento jev je nazýván přetečení zásobníku (stack-based overflow).

K přetečení může dojít i v jiném segmentu paměti. Ale přetečení zásobníku je z hlediska využití nejzajímavější, protože můžeme přepsat návratovou adresu a tím změnit tok vykonávání programu. Kdyby totiž byla návratová adresa jiná než 0x41414141 a byla by to platná adresa nějakého kódu, který eventuálně podstrčí útočník, znamenalo by to vykonávání právě podstrčeného kódu. Tato metoda se nazývá tzv. infekce kódu (bytecode infection). Bytecode je kus chytře podstrčeného assemblerovského kódu, který je vložen do bufferu. Takový kód má několik omezení. Musí být samostatný a nesmí obsahovat speciální znaky v instrukcích, protože by měl vypadat jako data v bufferu.

Rámec zásobníku
Obrázek 1.1: Rámec zásobníku

Jeden z nejpoužívanějších kódů je tzv. shellkód, který spouští příkazový interpret shell. Podaří-li se přelstít nějaký suid root program (takový program, který vlastní root a má přidělen suid bit) tak, aby se s jeho právy spustil shell, má útočník vyhráno a získává plnou kontrolu nad strojem a systémem.

Vycházíme-li ze situace, že máme k dispozici takto postižený program, postačí jen vhodně vygenerovat data, která předáme programu. Data budou obsahovat shellkód, který po skončení programu přepíše návratovou adresu a umožní tak převzít kontrolu nad strojem jako s právy uživatele root. Aby byl shellkód spustitelný, je žádoucí předem znát jeho adresu, což může být u dynamického zásobníku poněkud problematické. Pro správnou funkci je nutné přepsat pouze čtyři bajty návratové adresy. Pokud tato podmínka není splněna, program je ukončen. Pro řešení této situace existují dvě známé techniky.

První je nazvána NOP sled. NOP je instrukce, která nedělá vůbec nic. Použijeme ji ve formě velkého pole NOP, které je ukončeno shellkódem. EIP bude neustále inkrementován, až narazí na shellkód.

Druhou technikou je zaplnění konce bufferu mnoha po sobě jdoucími návratovými adresami. Vytvořený buffer bude vypadat jako na obrázku 1.2.

Buffer
Obrázek 1.2:Buffer

U obou technik je ale nutné znát alespoň přibližné umístění bufferu v paměti, aby bylo možné uhodnout návratovou adresu. Jednou z možností je aproximování umístění v paměti na základě ukazatele na zásobník (registr ESP). Odečtením offsetu od ESP získáme relativní adresu libovolné proměnné. Jelikož je prvním prvkem na zásobníku buffer, který je přepsán, správná adresa by měla být ukazatel na zásobník, takže offset by měl být blízko 0.

Přetečení v segmentech halda a bss

Nejen u zásobníku může dojít k přetečení. Stejný problém se týká i haldy a segmentu bss. Tento typ útoků není tak standardizovaný jako přetečení zásobníku, ale to neznamená, že není stejně účinný. Jelikož v tomto případě neexistuje návratová adresa, která by mohla být přepisována, závisí tyto útoky na přepisování některých důležitých proměnných, jež se nacházejí v paměti za bufferem. Pokud je například za bufferem uložen seznam přístupových práv nebo autentizační informace, může přetečení bufferu znamenat získání plných přístupových práv (v nejhorším případě). V jiných případech se může jednat o ukazatel na funkce obsažené v těle programu. Přetečením bufferu a přepsáním těchto adres můžeme spustit shellkód. Protože exploitování v segmentech halda a bss je mnohem více závislé na rozložení paměti v programu, není tak triviální nalézt zranitelná místa programu.

Jeden poměrně chytrý způsob, jak pomocí tohoto druhu přetečení získat superuživatelská práva, ukazují následující řádky. Využijeme jednoduchého programu pro zápis do souboru. Podmínky: nastavení suid bitu, vlastnictví roota a samozřejmě náchylnost k tomuto druhu přetečení. Napaden bude velmi důležitý soubor /etc/passwd. Právě pomocí tohoto přetečení bude vytvořen nový uživatelský účet. Prostým editováním /etc/passwd. Tento účet bude bez hesla a bude superuživatelský (uid bude rovno 0). Odpovídající řádka v /etc/passwd by mohla vypadat následovně.

r00t::0:0:hacker:/root:/bin/bash

Vkládaný řetězec je nutné drobně upravit. Je důležité, aby data měla správnou délku, která způsobí správné přetečení. Jinými slovy, musí přesně padnout do masky rámce zásobníku.

Lokální útoky - formátovací řetězce

Podobně jako u metod využívajících přetečení paměti je cílem této metody změna toku programu. Exploity tohoto druhu závisejí taktéž na programových chybách a na rozdíl od přetečení paměti nemusejí mít přímý dopad na bezpečnost. Ve srovnání s exploitačními technikami postavenými na přetečení paměti jsou techniky formátování řetězce poměrně snadno odstranitelné [2]. Ovšem za předpokladu, že se o těchto chybách ví.

Formátovací řetězce a funkce printf()

Formátovací řetězce nacházejí uplatnění ve formátovacích funkcích, např. ve funkci printf(). Příkladem může být následující kus kódu.

printf("Vypiseme neco na standardni vystup:%d",some_var);

"Vypiseme neco na standardni vystup:%d" je formátovací řetězec. Funkce jej vytiskne, ale nejprve provede speciální operaci, projde jej a otestuje na výskyt formátovacích parametrů. V příkladu je formátovacím parametrem %d. Tento parametr zapříčiní vypsání argumentu some_var, tedy hodnoty proměnné jako celé číslo v desítkové soustavě. Většina parametrů získává hodnotu proměnné předáním hodnoty. Existují i výjimky, které očekávají ukazatel. Jedná se především o řetězcové proměnné a data ve formě bajtů. Speciální činnost funkce zmíněná na začátku kapitoly proběhne vždy, když funkce najde ve formátovacím řetězci formátovací parametr. Každý formátovací parametr očekává samostatnou proměnnou. Funkce má proměnný počet parametrů. Důležitá je také skutečnost, že argumenty funkce jsou uloženy na zásobníku v opačném pořadí [4]. Rámec zásobníku je vyobrazen na obrázku 1.3.

V případě, že se budeme zabývat zobrazováním čísel, je jasné, že číslo bude fyzicky uloženo stále stejně ve formátu dvojkového doplňku. To, co ovlivňujeme formátovacím parametrem, je jeho reprezentace.

Vraťme se nyní k počtu parametrů. Bylo řečeno, že je třeba uvést tolik hodnot, kolik je formátovacích parametrů. Co však nastane v případě, že jeden nebo více parametrů chybí? Funkce jednoduše vytiskne hodnotu zásobníku na odpovídající pozici. Právě této vlastnosti je při útocích tohoto typu využito. Zjednodušeně řečeno měníme počet argumentů předávaných nebo očekávaných formátovací funkcí.

Rámec zásobníku funkce printf()
Obrázek 1.3: Rámec zásobníku funkce printf()

Někdy se stane důsledkem nepozornosti, že programátor namísto printf("%s",string) zapíše pouze printf(string). Funkčně je vše v pořádku, formátovací funkce vypíše všechny značky řetězce dané adresou string. Funkce končí, když narazí na nulový bajt. Následuje jednoduchý program pro demonstraci výše zmíněné chyby.

#include <stdlib.h>
int main(int argc,char *argv[]){
char text[1024];
static int testVal=-72;
if(argc < 2){
printf("Pouziti:%s<text k vytisknuti>\n", argv[0]);
exit(0);
}
strcpy(text, argv[1]);
//spravny způsob vytisteni
printf("Spravne:\n");
printf("%s",text);
printf("\n");
//nespravny způsob vytisteni
printf("Spatne:\n");
printf(text);
printf("\n");
//debug
printf("[*]testVal@0x%08x = %d0x%08x\n",&testVal,testVal,testVal);
exit(0);
}

Oba způsoby fungují korektně, pokud programu předložíme jakýkoliv text bez formátovacích parametrů. Změna ovšem nastane, pokud programu předáme parametr, jenž obsahuje formátovací řetězec.

user@host:~$ ./format text\%x
Spravne:
text%x
Spatne:
textbf800828
[*]testVal@0x08049728=-720xffffffb8

Program vyhodnotil součást řetězce text%x jako další formátovací parametr, avšak bez příslušné proměnné ve formátovací funkci. Program tedy vypsal obsah paměti následující za proměnnou testVal na zásobníku a tuto hodnotu formátoval jako hexadecimální číslo. Postup je možné využít opakovaně k prozkoumání obsahu zásobníku. Postačí vhodně zvolit parametr. Například požadujeme-li prozkoumání 50 paměťových míst za poslední validní hodnotou, předáme parametr například ve tvaru perl -e print "%80x."x50; [2].

Příklad, který byl uveden, ukazoval vypsání paměti pomocí parametru předávaného hodnotou (%x). Použijeme-li však parametr předávaný odkazem (%s), pokusí se program vypsat obsah paměti na adrese dané parametrem programu. Pokud je zvolena neplatná adresa, program havaruje. Pokud je adresa platná, bude vypsán obsah na této paměťové adrese.

Čtení obsahu rámce zásobníku není příliš zajímavé, daleko vhodnější je možnost zápisu do něj. Je použita naprosto stejná technika jako při čtení zásobníku; jedinou odlišností je použití jiného formátovacího parametru. Jedná se o parametr %n [4].

Závěr

Další, velmi výhodnou možností je použití "Warning options" překladače GCC. Jelikož nemám žádné znalosti jiných překladačů, zaměřím se pouze na GCC. Mezi tyto "Warning options" nebo "Warning flags" patří například -Wall, -Wformat, -Wno-format-extra-args nebo -Wformat-security. Tyto přepínače mimo jiné kontrolují formát argumentů některých funkcí (printf(), scanf(), ...) nebo varují při možnosti vzniku bezpečnostních problémů [5].

Popsané lokální útoky nebo lépe řečeno programátorské chyby lze většinou poměrně snadno odstranit. Daleko větším problémem je jejich nalezení. Díky komunitě, která se kolem Linuxu rozrostla, není tento problém neřešitelný. Je kladen poměrně velký důraz na otevřenost i v otázkách bezpečnosti, nic není skrýváno. Tato skutečnost napomáhá tomu, aby byly chyby brzo nalezeny a odstraněny. Doporučením pro předcházení problémům je častá aktualizace systému a sledování diskusních fór, konferencí a jiných informačních zdrojů s tématikou bezpečnosti. Mimo tyto základní metody je vhodné pro další ochranu před tímto druhem útoků systematicky získávat dobré programátorské návyky, pečlivé prověřování a testování napsaného kódu.

V poslední době je stále oblíbenější řešení knihovna Libsafe. Obrovskou výhodou je jednoduchá instalace. Navíc není nutné měnit již zkompilované programy. Podle autorů zastaví tato knihovna drtivou většinu chyb způsobených přetečením bufferu. Libsafe chrání pouze provádění aplikací, ne samotného jádra operačního systému. Tento kód chrání jedna z alternativ Libsafe systému OpenWall. Jedná se o jadernou záplatu (kernel patch). Řeší jisté bezpečnostní problémy na úrovni jádra, například vytváří tzv. nespustitelný zásobník (nonexecutable user stack area), čímž zabraňuje spouštění kódu v zásobníku. Zaměřuje se především na otázky spojené se správou paměti (nechrání haldu).

Další alternativou k Libsafe je například StackGuard.

Knihovna Libsafe pracuje následovně. Namísto běžně používaných funkcí jazyka C, jako je například gets(), strcpy(), getwd(), scanf() nebo sprintf(), vyvolá službu Libsafe. Při tomto volání zjistí, zda-li se cíl volání nachází na zásobníku, a také jestli některá z adres nepřepíše data mimo rámec zásobníku. V případě, že jsou předcházející podmínky splněny, je operace zablokována [1].

Zmíněné funkce provádějí přesně to, co programátor požaduje. Tato vlastnost je důvodem jejich nebezpečnosti. Je dosaženo vysoké rychlosti na úkor bezpečnosti. Druhým problémem je skutečnost, že programátor není schopen zadat velikost bufferu. Nabízí se další řešení: používat bezpečné verze funkcí jako fgets() místo gets() nebo strncpy() namísto strcpy() [1].

Lokální útoky nejsou samozřejmě tvořeny jen přetečením paměti a chybami formátovacího řetězce. Dále je možné setkat se s útoky zvanými návrat do libc (Return-to-libc attacks), přetečení celých čísel (Integer overfows), chyby souběhu (Race conditions) atd.

Literatura

Další články z této rubriky

V sobotu se uskuteční konference CryptoFest
Pozor na androidové aplikace
Silent Circle představil bezpečný smartphone Blackphone 2
Android je bezpečnější, řada hrozeb však stále přetrvává
Avast varuje před nebezpečnými aplikacemi v Google Play

Diskuse k tomuto článku

wake avatar 4.12.2007 00:33 wake | skóre: 30 | blog: wake | Praha
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Cyklus 'if'???
Tento příspěvek má hlavičku i patičku!
Luboš Doležel (Doli) avatar 4.12.2007 00:42 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Díky, opraveno.
4.12.2007 09:48 xxx
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
spolu s goto, by if mohlo tvorit cyklus :-) :-(
wake avatar 15.12.2007 17:25 wake | skóre: 30 | blog: wake | Praha
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
spolu s while i print muze tvorit cyklus... ;-) ;-)
Tento příspěvek má hlavičku i patičku!
michich avatar 4.12.2007 00:45 michich | skóre: 51 | blog: ohrivane_parky
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Není libsafe dnes již překonán standardními gcc/glibc vylepšeními FORTIFY_SOURCE a -fstack-protector? Fedora je s těmito volbami kompilována.
4.12.2007 08:52 bluemoon
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
velmi pekny clanek...
4.12.2007 10:10 zelial | skóre: 21
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
dobrý článek! v závěru byly zmíněny další typy chyb - bude pokračování?
Grunt avatar 4.12.2007 10:17 Grunt | skóre: 23 | blog: Expresivní zabručení | Lanžhot
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Nemohu si pomoct, ale jaký je rozdíl mezi tímto článkem a str. 18-93 z knihy Hacking bez tajemstvý:Umění exploitace?
Na co 64-bitů když to jde i s jedním? | 80.78.148.5 | Hack (for) free or Die Hard!
4.12.2007 10:25 m_ax
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Rozdiel je asi 70 stran :))
4.12.2007 10:42 kain
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
tiez ma to napadlo. Pri fenceposte som si ihned spomenul hacking bez tajemstvi a domnienka sa potvrdila pri popise chyby openssh. Ale ten priklad je vynikajuci, tak preco ho nepouzit.
7.12.2007 14:58 Harvie
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
V podpisu autora ;D
4.12.2007 10:26 marek
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
supr článek:-) děkuji
michich avatar 4.12.2007 10:39 michich | skóre: 51 | blog: ohrivane_parky
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Pro zájemce o tuto problematiku můžu doporučit prakticky zaměřený článek Ulricha Dreppera Defensive Programming (a prezentaci k němu). Zajímavý je taky Security Enhancements in RHEL (+ prezentace).
4.12.2007 11:33 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Co máte pořád všichni s tím /etc/passwd, to všichni pořád dokola opisují z nějaké 15 let staré knihy nebo je to nějaká epidemie? Zkusil si autor opravdu na nějaké (aspoň trochu) současné distribuci přidat do /etc/passwd řádek, který uvádí, a poté se přihlásit jako uživatel r00t bez hesla? A fungovalo mu to?
satanatas avatar 4.12.2007 11:40 satanatas | skóre: 14 | blog: vše co můžete s klidem hodit za hlavu ze světa linuxu i jiných světů | Graveyard
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
no vy ste tomu teda dal. teď už nic nebrání tomu, aby kdejaký bfu opsalo pár řádek do pc a dokázalo tak bez problému hackovat cokoliv. :*}
pele avatar 4.12.2007 12:16 pele | skóre: 28 | blog: Bleabr | UH
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Zkusil, funguje:)
Pravda má jednu velkou výhodu: člověk si nemusí pamatovat, co řekl.
4.12.2007 12:22 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
A to byla nějaká normální distribuce nebo jste nejdřív provedl řadu opatření, aby to mělo šanci fungovat?
4.12.2007 12:35 Mortal | skóre: 26 | blog: mortals_log
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
normalni gentoo bez zadnych specialnich uprav
V pekle jsou samé diskety a ďábel je velká disketová mechanika
pele avatar 4.12.2007 12:56 pele | skóre: 28 | blog: Bleabr | UH
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
+1 sarge
Pravda má jednu velkou výhodu: člověk si nemusí pamatovat, co řekl.
4.12.2007 14:14 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Tak to by mne docela zajímalo, kde udělali soudruzi z Gentoo chybu. Když tu položku, kde kdysi dávno býval hash hesla, nenecháte prázdnou, ale zkopírujete tam hash nějakého známého hesla, půjde se s tímto heslem přihlásit jako r00t? Používá ta distribuce standardní pam_unix.so nebo nějakou specialitu?
4.12.2007 14:29 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Je tam pam_unix.so, /etc/pam.d/system-auth vypadá takto:
#%PAM-1.0

auth       required     pam_env.so
auth       sufficient   pam_unix.so try_first_pass likeauth nullok
auth       required     pam_deny.so

account    required     pam_unix.so

password   required     pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 try_first_pass retry=3
password   sufficient   pam_unix.so try_first_pass use_authtok nullok md5 shadow
password   required     pam_deny.so

session    required     pam_limits.so
session    required     pam_unix.so
Standardní rootovský záznam v /etc/passwd je potom takovýto: root:x:0:0:root:/root:/bin/bash

V každém případě - není to jedno? Pokud by někdo zvládnul zapsat do /etc/passwd, zvládne i zápis do /etc/shadow, ne?
michich avatar 4.12.2007 15:48 michich | skóre: 51 | blog: ohrivane_parky
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
V každém případě - není to jedno? Pokud by někdo zvládnul zapsat do /etc/passwd, zvládne i zápis do /etc/shadow, ne?
Tak to vůbec není tak jisté. Třeba proto, že shadow má svůj SELinux kontext.
4.12.2007 15:53 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
V tom případě nechť někdo vyzkouší, jestli to funguje i v rámci SELinuxu. Protože pochybuju, že by ho někdo z nás, kdo to zkoušel, měl zapnutý.

V každém případě to, soudě podle příspěvku peleho, dělá i Debian, takže asi půjde o obecnější záležitost.
4.12.2007 17:28 azurIt | skóre: 34 | blog: zatial_bez_mena
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Sarge nemam nikde ale v Etch to urcite nejde (skusal som len prazdne heslo). Slackware 10.2 ide.
5.12.2007 00:47 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Pro zajímavost jsem teď zkusil pod VMware nainstalovat čistý aktuální Arch Linux a přihlášení funguje jak s prázdným heslem, tak s kopií hashe z jiného účtu...
4.12.2007 14:35 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Abych nezapomněl - zkopírovaný hash hesla funguje.
Grunt avatar 4.12.2007 18:08 Grunt | skóre: 23 | blog: Expresivní zabručení | Lanžhot
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Co máte pořád všichni s tím /etc/passwd, to všichni pořád dokola opisují z nějaké 15 let staré knihy nebo je to nějaká epidemie?
Co je na /etc/passwd, špatného nebo snad 15 let starého?
Zkusil si autor opravdu na nějaké (aspoň trochu) současné distribuci přidat do /etc/passwd řádek, který uvádí, a poté se přihlásit jako uživatel r00t bez hesla? A fungovalo mu to?
A proč by to nemělo fungovat? Dokonce znam distribuci ve které byla hesla uvedena v tomto souboru.
Na co 64-bitů když to jde i s jedním? | 80.78.148.5 | Hack (for) free or Die Hard!
4.12.2007 23:13 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Trik je v tom, že na aspoň trochu rozumně nastavené distribuci to nemá nejmenší šanci fungovat. Už neexistence odpovídajícího řádku v /etc/shadow by měla být pro pam_unix.so dostatečným důvodem, aby přihlášení zamítl. Rozhodně by neměl umožnit přihlášení bez hesla na základě toho, co je (nebo není) ve druhé položce v /etc/passwd. A to nemluvím o tom, že mnohé distribuce vám přihlášení bez hesla neumožní ani v případě, že bude prázdná druhá položka v /etc/shadow. Pokud na nějaké distribuce uvedená finta projde v té podobě, v jaké je popsaná v článku, je to podle mne zralé na bugreport.
pavlix avatar 12.12.2007 16:44 pavlix | skóre: 54 | blog: pavlix
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Coz nic nemeni na moznosti zmenit /etc/shadow.
Já už tu vlastně ani nejsem. Abclinuxu umřelo.
12.12.2007 18:09 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
A přesně o tom tu od začátku mluvím. Proč autor nenapíše "lze změnit obsah libovolného souboru" (to mi zní dostatečně hrozivě) nebo proč to nedemonstruje na /etc/shadow? Nebo proč, když už si vybere /etc/passwd, raději nepoužije jako ukázku něco, co by opravdu fungovalo? Protože to buď všichni opisují už patnáct let jeden od druhého nebo jsou posedlí tím tajemně zavádějícím názvem. Těžko říct, co je horší.
12.12.2007 19:44 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Protože to minimálně v několika distribucích (zkoušel jsem Gentoo a Arch, podle příspěvku výše se to týká i Debianu Sarge) funguje i dnes?
12.12.2007 20:30 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
A nebylo by lepší použít jako ukázku něco, co funguje nejen v distribucích, kde někdo něco zanedbal?
12.12.2007 20:57 Honza Jaroš | skóre: 6 | blog: moje_strana_plotu | Bohnice
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
O tom se hádat nechci. Jen jsem chtěl říct, že pokud to autor zkoušel a fungovalo mu to, těžko mu můžeme vyčítat, že ho nenapadlo, že by to mohlo být v jiných distribucích jinak.
Matyáš Dvořák avatar 4.12.2007 12:57 Matyáš Dvořák | skóre: 13
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Nejlip popsane preteceni zasobniku co jsem kdy cetl :)
savalo.dev
5.12.2007 08:24 rastos | skóre: 62 | blog: rastos
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Tým, ktorých problematika článku zaujíma odporúčam do pozornosti túto diplomovku.

P.S. Je škoda, že sa jednému trollovi podarilo vyprovokovať 80% príspevkov v tejto diskusii.
5.12.2007 08:25 rastos | skóre: 62 | blog: rastos
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Sákriš. Ešte raz (pozor, je to .pdf).
4.12.2007 12:58 DNA
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Kontrola programátora také zvyšuje náchylnost na přetečení paměti. - mě ta věta nedává smysl, možná místo zvyšuje ovlivňuje
Luboš Doležel (Doli) avatar 4.12.2007 13:06 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Tento jev je nazýván přetečení zásobníku (stack-based overflow).
Není to spíš přetečení bufferu na zásobníku? Pod přetečením zásobníku si představím Stack overflow, což je něco jiného.
4.12.2007 13:59 admin
Rozbalit Rozbalit vše admin

Vlákno bylo přesunuto do samostatné diskuse. Máte-li pocit, že je ještě potřeba do flamu přispět, přidávejte prosím komentáře do osamostatněné diskuze, nikoliv sem pod článek, se kterým to nesouvisí. Děkuji.

5.12.2007 15:05 trekker.dk | skóre: 72
Rozbalit Rozbalit vše Re: admin
Ne že bych měl něco proti tomu přesunu, ale ten admin, který to udělal, se pod to mohl podepsat a ne přispět jako "anonym".
Quando omni flunkus moritati
5.12.2007 16:15 Robert Krátký | skóre: 94 | blog: Robertův bloček
Rozbalit Rozbalit vše Re: admin
a) Nevidím důvod, proč by se měl admin pod takovou akci "podepisovat". Je úplně jedno, který admin to provedl. Všichni za jednoho atd.

b) Kdybys na ten odkaz klikl, hned bys věděl, který admin to udělal :-)
MaT avatar 4.12.2007 16:36 MaT | skóre: 28
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
K těm odkazům na literaturu - Heroutova Učebnice jazyka C - je to z nakladatelství Kopp, ne Koop (že by nějaký Koop diskont? :-).
Open source software for open minded people. :-)
Luboš Doležel (Doli) avatar 4.12.2007 18:48 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Díky, opraveno :-)
4.12.2007 19:34 cronin | skóre: 49
Rozbalit Rozbalit vše Operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Aký je to "operačný systém linuxového typu"?
pele avatar 4.12.2007 21:34 pele | skóre: 28 | blog: Bleabr | UH
Rozbalit Rozbalit vše Re: Operační systém linuxového typu
Pravda UNIXoveho je urcite vhodnejsi.
Pravda má jednu velkou výhodu: člověk si nemusí pamatovat, co řekl.
5.12.2007 15:40 Atoi()
Rozbalit Rozbalit vše Re: Operační systém linuxového typu
Jediny spravny termin je v tomto pripade UNIX-like OS vy hlupaci.
5.12.2007 17:18 Elwood
Rozbalit Rozbalit vše NX bit
Odpovědět | Sbalit | Link | Blokovat | Admin
Kdyby Intel při návrhu stránkování pro 386 měl trochu prozřetelnosti a zavedl u stránek atribut zakazující spouštění kódu, mohli jsme si tyto problémy ušetřit. No co, snad u všech 64bit x86 procesorů už tento atribut je a není problém ho použít. Tak snad do budoucna budou tyto typy útolů podstatně složitější.
5.12.2007 17:53 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: NX bit
Intel holt při návrhu 386 asi ještě pořád naivně předpokládal, že se autoři operačních systémů budou chovat rozumně a nebudou plácat instrukční a zásobníkové segmenty přes sebe…
5.12.2007 19:39 ...Jimmy
Rozbalit Rozbalit vše Re: NX bit
Intelu nezbyl ten posledni bit pro oznaceni varianty +r+w-x, cetl jsem o tom v DPMI specifikaci
5.12.2007 20:15 Rob
Rozbalit Rozbalit vše Re: NX bit
A to se jeste dnes/v dobe 386 procesoru dela? Neco jsem o tom cetl v knize z roku 1984, kde se tato "technika", pouzivala na PDP z duvodu usetreni pameti... :). Brr..
5.12.2007 20:59 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: NX bit
Kdyby se to nedělalo, jak byste chtěl spouštět kód uložený na zásobníku?
5.12.2007 22:44 Rob
Rozbalit Rozbalit vše Re: NX bit
aj. omlouvam se. pochopil jsem to trosku jinak
6.12.2007 10:26 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: NX bit
To je ovšem celý problém. Současný stav x86_32 takováto zvěrstva umožňuje, ale již neumožňuje je výběrově zakázat.

Kdo jiný potřebuje měnit kód za běhu než multimediální a jinak výkonově vyšinutí jedinci, kteří jsou pro pár cyklů ochotni obětovat cokoliv?
6.12.2007 16:57 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: NX bit
Asi jsem se vyjádřil trochu nešťastně. Možnost spouštění kódu uloženého na zásobníku (nebo v datovém segmentu) mi osobně nijak nechybí a samomodifikujícím se kódem jsem se ukájel naposledy na Spectru. Takže jsem asi měl napsat spíš "Kdyby se to nedělalo, nemohl by tento typ útoku fungovat, protože kód na zásobníku by spustit nešlo."
7.12.2007 09:23 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: NX bit
Nepoužívá se možnost spouštět kód uložený na zásobníku třeba pro debugery, profilery a podobné nástroje?
7.12.2007 21:16 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: NX bit
Pro ty by mělo stačit překrýt instrukční segment datovým. A navíc až když člověk chce ladit nebo profilovat. K překrývání zásobníkového a instrukčního segmentu při normálním běhu produkční aplikace není žádný důvod - kromě pohodlnosti autorů operačních systémů.
6.12.2007 13:57 Neuro
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
Co to jako je? Je to opsané z knihy Hacking: Umění exploitace a dalsich. Takoveto clanky nemaji zadnou hodnotu. Autoruv prinos neni zadny.
6.12.2007 22:18 honza
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
no hlavne, ze tvuj prinos je obrovsky. ja autorovi dekuji.
7.12.2007 00:43 patok
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Odpovědět | Sbalit | Link | Blokovat | Admin
no rad jsem si to zopakoval i kdyz je mi jasne, ze tohle uz zacina byt docela dost z mody :)) no ale snad to alespon primeje soucasne zacinajici programatory vic myslet nad kodem..... i sam autor by se mel asi zamyslet nad par vecma v tomhle clanku.... IMHO kdyz mame deklaraci promenne:

char buffer[20];
a nakopirujeme do ni vic znaku, nez je schopna pojmout, tak v ni nebude 20 znaku (bajtu), ale 21, protoze se to indexuje od nuly... Tudiz tohle:
Ve funkci byl vytvořen buffer o velikosti 20 znaků, to je námi očekávaná hodnota. Do tohoto bufferu však vložíme 128 znaků. Z důvodu přetečení paměti program selže.
...neni pravda.

A tohle:
Když se funkce pokusí zapsat 128 bajtů dat do 20 bajtového bufferu, dojde k zapsání 20 bajtů do bufferu a zbylých 108 bajtů přepíše návratovou adresu, ukazatel na rámec a argument funkce.
...je zavadejici, protoze 20bajtovy buffer se definuje jako char buffer[19];.

Nechci byt jedovaty, ale proste mi to prijde u takovehoto clanku trosku trapne. A uz vubec se mi nechce verit ze to bylo v nejake knizce, tak trosku vaham, jestli nahodou neplacam blbosti... precijen jsem spis na ten Python, PHP a BASH ;)
7.12.2007 02:26 Jirka | skóre: 36
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Jste si tím opravdu jistý?

char buffer[20];

Vytvoří pole 20 charů, čili 20 B. To, že se indexuje od nuly znamená, že nejvyšší index tohoto pole bude 19. Prvků v něm ale bude 20.

20 B bude pořád 20 B. Možná Vám někde řekli, že pokud do pole char pole[20] můžete dát jen 19 hodnot typu char, čili 1 B hodnot a do posledního znak '\0', kdybyste to chtěl vypsat knihovní funkcí jako řetězec.
7.12.2007 10:09 patok
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
aha, tak to se omlouvam... ja jsem to samozrejme vyzkousel, ale nejakym zahadnym zpusobem mi kompilator do toho buffer[20] vzdycky nakopiroval o 1 znak vic.... tzn. 21 znaku. no vlastne ono to neni tak zahadne... dokud to neprepise tu navratovou hodnotu, tak se to vicemene tvari jako by nic. ted jsem to pro jistotu zkusil znovu a trosku jinak a vazne musim uznat, ze uz jsem mlel k ranu blbosti. ale v zakladu jsem si spletl tedy princip indexovani pole s principem deklarace.
a ano... o tom ukoncovanim retezcu znakem \0 vim, ale neni to primo to co me zmatlo i kdyz mozna to k tomu take prizpelo. :-)
10.12.2007 11:23 IK
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Programatorovi bylo sdeleno, ze jeho apartma je v 6-tem patre. Nastoupil do vytahu, stiskl seste tlacitko od spodu s napisem 5, prijel , vystoupil, nemohl ani za nic nalezt svuj pokoj. Ohromne se pozdeji divil, jaktoze ta patra nezacinaji od nuly. :-D
10.12.2007 12:24 bn1 | skóre: 2
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
:-D jako bych to už někdy zažil :-D :-D
..::kliknutím změníte text v patičce::..
10.12.2007 13:19 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Ale patra jsou číslována od nuly – přízemí (= 1. podlaží), 1. patro (= 2. podlaží), 2. patro (= 3. podlaží) atd. Z toho plyne, že v hotelu byl mezanin ;-)
10.12.2007 16:21 Jirka | skóre: 36
Rozbalit Rozbalit vše Re: Lokální útoky na operační systém linuxového typu
Nebo ten prográmator byl Pascalista. :-)

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.