W prezentacji zostanie przedstawione podejście do problemu automatycznego wyszukiwania podatności bez posiadania znacznej mocy obliczeniowej (własnej farmy serwerów) które pomogło w ujawnieniu prawie 400 różnych błędów w oprogramowaniu open-source (w tym ~110 podatności z CVE) w okresie jednego roku. Pokazane zostaną procesy zwiększające efektywność fuzzingu w chmurze oraz autorski system (codename: Cloudfuzz) wspomagający deduplikację crashy, analizę błędów, zarządzanie korpusem oraz serwerami. Omówię także najpoważniejsze błędy odkryte za pomocą systemu, a także widoki na rozwój projektu.
PLNOG19 - Andrzej Prałat & Wojciech Rybicki - Jak usprawnić działanie WAF wyk...
CONFidence 2018: "Small money, a lot of bugs" - Large scale bughunting dla typowego "Janusza" (Kamil Frankowicz)
1. Small money, a lot of bugs
Large scale bughunting dla typowego "Janusza"
Confidence 2018, Kraków
Kamil Frankowicz
2. Wczoraj na IRC...
17:01 <XXX> "Large scale bughunting dla typowego "Janusza""
17:01 <XXX> fumfel to nie potrafi ludzi nie obrażać nawet przez 10
sekund jak wymyśla tytuł prezentacji
[...]
17:05 <YYY> ale co do fumfel, to sgoda
17:05 <YYY> zgoda
17:05 <YYY> z tym Januszem to przesada
3. $whoami
Kamil Frankowicz (fumfel)
● Security Engineer @ CERT.pl
● Bughunting & analiza podatności
● Fan fuzzingu i powodowania awarii programów
● fumfel@cert.pl
● frankowicz.me
● @fumfel
4. O czym będzie?
● Przypomnienie, jak kiedyś to było...
● O poszukiwaniu błędów, w dosyć dużej skali.
● O problemach podczas poszukiwań i ich rozwiązaniach.
● O ciekawych przypadkach.
5. TLDL - Too long, didn’t listen
Bugi są wszędzie - nawet w
Twoich narzędziach. Warto
rozpocząć poszukiwania!
7. 2014 - Good old days
● Kto pamięta co ciekawego porabiał
w pracy na początku kwietnia 2014?
○ Dlaczego do tego doszło?
■ Brak testów?
■ Brak narzędzi?
■ Braki kadrowe?
■ Brak $$$?
● Powstaje AddressSanitizer (ASAN)
8. 2015 - Good old days
● Upubliczniony zostaje LibFuzzer oraz MemorySanitizer (MSAN)
○ Znajduje Heartbleeda w 10 sekund!
● Fuzzing jest “uprawiany” przez researcherów bezpieczeństwa.
○ Pojedyncze projekty.
○ AFL 4 life - kilkadziesiąt znalezionych podatności.
9. 2016 - Better old days
● 13.09.16 - Pierwszy błąd zgłoszony przeze mnie w Yarze.
● 01.12.16 - Upubliczniony zostaje Google OSS-Fuzz.
○ 104 znalezione podatności przez pierwszy miesiąc.
● Ciągle fuzzing jest “uprawiany” przez researcherów.
bezpieczeństwa.
○ Głównie za pomocą AFL - lekko przebija się LibFuzzer.
○ Szersze spojrzenie - większa skala.
10. 2017 - Quite good old days
● Google OSS-Fuzz znajduje ponad 900 podatności.
● Ja dopiero dobijam do setki ;-)
● Deweloperzy mają większą świadomość kwestii związanych z
testami automatycznymi.
● Rodzi się koncepcja Fuzz-Driven Development
11. Podsumowanie: 2014-2017
● W znaczący sposób rozwinęły się narzędzia do fuzz testingu i
wykrywania błędów: ASAN, MSAN, UBSAN, SanCov.
● Deweloperzy już wiedzą, że istnieje coś takiego jak fuzzing i
mają świadomość jak może pomóc.
○ Integracja LibFuzzera ze swoim projektem jest banalna.
● Proces fuzzingu z “punktowego” zmienił się na ciągły.
● Dzięki taniejącej mocy obliczeniowej, zwiększyła się skala.
13. A na co to komu? [2016 rok]
● Najpierw chciałem “ogarnąć” AFLa...
○ ...potem udowodnić, że można robić to bez dużej ilości $$.
● W momencie rozpoczynania projektu (prawie) nikt tego nie robił.
● Z osobistych obserwacji wiedziałem, że projekty open-source
cierpią na brak osób testujących kod pod kątem security.
● Moja mantra: bugi są wszędzie!
18. Poza problemami z dziurawym softem....
Pierwsze kilka rzeczy z głowy:
● Tanie serwery
● Analiza znalezionych błędów
● Deduplikacja crashy
● Monitorowanie serwerów
● Zarządzanie korpusem
● Zarządzanie serwerami
21. W poszukiwaniu tanich VPS...
● Miałem ułatwione zadanie na początek: 100$ kredytu DigitalOcean
z GitHub Student Pack
● VPS za 5 USD (18.5 PLN) jest dobry przez pierwsze kilka dni
fuzzingu:
○ 1 vCPU
○ 512 MB RAM
○ 20 GB SSD
● Kredyty szybko się skończyły...
22. W poszukiwaniu tanich VPS...
● … testując innych dostawców dowiedziałem się, że parametry VPS
(w tym cena) to nie wszystko.
● Liczy się też współczynnik oversellingu, którego żaden dostawca
nie podaje, lecz jest to prosta zależność: im taniej, tym bardziej
obciążone serwery.
● Prawie idealnie z początkiem mojego projektu na polskim rynku
pojawiła się Aruba Cloud.
23. W poszukiwaniu tanich VPS: Aruba Cloud
● 4 PLN netto za miesiąc pracy serwera.
● Początkowo “kulawy” provisioning serwerów
i przedpotopowy panel do zarządzania.
● Ogromny overselling na który znalazłem
patent ( ▀ ͜͞ʖ▀)
○ Bardzo nierównomiernie obłożenie DC.
○ IT oraz CZ - dramat (ciągle 4 PLN).
○ GB, FR - jest całkiem ok.
24. Tylko jeden core?!!!!1111
● Zamiast kupować mocniejsze VPS,
szukałem projektów związanych z AFL,
które modyfikują sposoby wyszukiwania
interesujących ścieżek. w kodzie
testowanego programu.
● Na scenę wchodzi AFLFast z pięcioma
sposobami określania “energii” danego
stanu.
27. Jak sprawdzić co się zepsuło? To proste!
● ASAN / MSAN / UBSAN -
niesamowite ułatwienie pracy.
● W ostateczności Valgrind daje radę.
● ASAN / MSAN / UBSAN + LibFuzzer
= <3
● ASAN / MSAN + AFL = <3
28. Zaczynają się schody...
● Crashy może być dużo: >500 na sesję fuzzingu to normalne.
● Wiele ścieżek do tego samego błędu.
● Niestabilne warunki triggerowania błędu.
● Błędy w zależnościach.
● Zawieszenia testowanego problemu, wycieki pamięci...
29. Wireshark + LibFuzzer - nie jest kolorowo
==20863==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60200df8f0d2 at pc 0x00000044ae69 bp 0x7ffd3175a660 sp
0x7ffd31759e10
READ of size 4 at 0x60200df8f0d2 thread T0
#0 0x44ae68 (fuzzshark_ip_proto-udp+0x44ae68)
#1 0x251e4ce (fuzzshark_ip_proto-udp+0x251e4ce)
#2 0x251f4d8 (fuzzshark_ip_proto-udp+0x251f4d8)
#3 0x649a89 (fuzzshark_ip_proto-udp+0x649a89)
#4 0x64a814 (fuzzshark_ip_proto-udp+0x64a814)
#5 0xd87103 (fuzzshark_ip_proto-udp+0xd87103)
#6 0xd84e5f (fuzzshark_ip_proto-udp+0xd84e5f)
#7 0x5e3de3 (fuzzshark_ip_proto-udp+0x5e3de3)
30. Wireshark + LibFuzzer - nie jest kolorowo
./fuzzshark_ip_proto-udp: Running 1 inputs 1 time(s) each.
Running: ./crash-be8d94351dc2841dfc3bc7aaceba0a03f812bbce
Executed ./crash-be8d94351dc2841dfc3bc7aaceba0a03f812bbce in
156 ms
*** NOTE: fuzzing was not performed, you have only executed the
target code on a fixed set of inputs.
31. Jak zautomatyzować ten proces?
1. Badanie raportu ASAN Valgrind:
a. Typ awarii.
b. Patterny crasha oraz blacklistowane wzorce.
2. Wykrywanie timeoutów.
3. Deduplikacja i wyszukiwanie unikalnych awarii:
a. Minimalizacja crasha.
b. Sprawdzenie unikalności poprzez różnicowanie znanych
patternów.
32. Jak zautomatyzować ten proces?
Parsowanie raportów jest proste!
ASAN_REPORT_REGEX =
re.compile(r"/*[A-Za-z0-9_-]+.[A-Za-z0-9]{1,4}:d*:*d*")
ASAN_REPORT_REGEX_WO_SYMBOLS =
re.compile(r"/*[A-Za-z]++0[xX][0-9a-fA-F]+")
VALGRIND_REPORT_REGEX =
re.compile(r"([A-Za-z0-9_-]+.[A-Za-z0-9]{1,4}:d*:*d*")
33. Cloudfuzz - C&C dla fuzzerów
1. Automatyczna analiza i deduplikacja crashy
+ powiadomienia.
2. Proste monitorowanie VPS + “naprawa”
serwerów (czyszczenie /tmp, itp.)
3. Statystyki fuzzingu.
4. Integracja z API dostawców cloud (DO,
Aruba).
5. [In progress] Harmonogram + automatyczne
budowanie projektów (integracja z Google
OSS-Fuzz).
40. ● Na początku maja pojawił się ciekawy
projekt wykorzystujący instrumentację AFL
do tworzenia plików powodujących
niestabilne zachowanie - PerfFuzz.
● Niestety jeszcze nie wiem jak działa w
praktyce - autorzy nie udostępnili
informacji o “internalsach”.
Autogeneracja “patologicznego” inputu
41. ===============Fuzzing test case #128===============
(Test case is not favored)
===============Fuzzing test case #135===============
adding out/queue/id:000313,src:000135,op:flip2,pos:12,+cov,+max to
queue
adding
out/queue/id:000314,src:000135,op:arith8,pos:21,val:-23,+cov,+max to
queue
adding out/queue/id:000315,src:000135,op:havoc,rep:32,+max to queue
adding out/queue/id:000316,src:000135,op:havoc,rep:16,+max to queue
Autogeneracja “patologicznego” inputu
44. Kiedy przestać?
● To że nie znaleziono żadnego błędu nie oznacza, że ich nie ma :-)
● Da się obliczyć kiedy będzie szkoda prądu na fuzzing!
american fuzzy lop 2.51b (magic_fuzzer)
┌─ process timing ─────────────────────────────────────┬─ overall results ─────┐
│ run time : 0 days, 0 hrs, 10 min, 15 sec │ cycles done : 6 │
│ last new path : 0 days, 0 hrs, 0 min, 1 sec │current paths : 3104 │
│ last uniq crash : none seen yet │ path coverag : 21.7% │
│ last uniq hang : none seen yet │ uniq crashes : 0 │
│ correctness : 5.486657e-04 │ uniq hangs : 0 │
│ fuzzability : 4.415707e-01 │ effec paths : 1.555 │
45. Kiedy przestać?
● Na pomoc przychodzą metody statystyczne dodane do AFL za
pomocą projektu Pythia.
● Interesujący output użytych statystyk:
○ Correctness - Prawdopodobieństwo znalezienia crasha.
○ Fuzzability - Jak trudne jest znalezienie nowych ścieżek?
○ Path coverage - Aktualna liczba znalezionych ścieżek w kodzie
do asymptoty możliwych ścieżek do znalezienia.
● Omówienie implementacji dla entuzjastów.
49. ClamAV + 7z =/= <3
● Niezałatane 7z (2010 rok!) powodowało zdalne double-free
podczas rozpakowywania archiwum np. z załącznika w mailu.
● Poprawka podatności w 7z w 2013 roku - praktycznie od razu po
zgłoszeniu (wersja 9.31).
● Cieszy szybka reakcja Cisco - poprawienie zajęło ~12h.
50. ClamAV + 7z =/= <3
==27355== Invalid free() / delete / delete[] / realloc()
==27355== at 0x4C2EDEB: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27355== by 0x78886D: MixCoder_Free (XzDec.c:351)
==27355== by 0x78886D: XzUnpacker_Free (XzDec.c:612)
==27355== by 0x43CE4D: cli_scanxz (scanners.c:951)
==27355== by 0x43CE4D: magic_scandesc (scanners.c:3226)
==27355== by 0x436A0A: cli_base_scandesc (scanners.c:3616)
==27355== by 0x43F63D: cli_magic_scandesc (scanners.c:3625)
==27355== by 0x43F63D: scan_common (scanners.c:3891)
==27355== by 0x43FF8E: cl_scandesc_callback (scanners.c:4032)
==27355== by 0x43FF8E: cl_scanfile_callback (scanners.c:4099)
==27355== by 0x43FF8E: cl_scanfile (scanners.c:4082)
==27355== by 0x405255: main (clamfuzz.c:25)
51. Z3 - UAF za free!
● Pośród testów regresyjnych znalazłem
leżący między innymi, test case
powodujący use-after-free.
● W/w przypadek dotyczył błędu
niestabilnego zachowania solvera
SAT, zgłoszonego tydzień wcześniej.
● Nawet nie musiałem odpalać fuzzera!
55. Na zakończenie
Jest dużo lepiej :-)
● Dokładnie 8171 błędów mniej! (w tym 1844 podatności).
● Coraz więcej deweloperów fuzzuje swój kod w sposób ciągły.
● Szybki rozwój narzędzi do fuzzingu.
● Fuzzujcie swój software i narzędzia, plz.
○ Ja cały czas to robię, ale nie zrobię wszystkiego za Was ;-)