Veilig coderen is een zeer moeilijke praktijk. Wanneer programmeurs software ontwikkelen, is hun doel meestal om de software te laten werken in plaats van te breken. Tijdens dit proces kunnen kwetsbaarheden ontstaan in gevallen waar een legacy functie werd gebruikt in plaats van een veiligere.
C is een van die talen die van nature zeer veelzijdig en krachtig zijn, maar er kleeft één nadeel aan: de beveiliging van software in C is afhankelijk van de kennis van de programmeur. Dit betekent dat als de programmeur goed op de hoogte is van veilig coderen, zijn software ook veilig zal zijn. Aan de andere kant, en dit vormt de grootste brok, als de programmeur niet geavanceerd genoeg is, zullen er mazen in hun software zitten die uiteindelijk leiden tot een exploit.
Voor mensen zoals ik, die verstand hebben van programmeren maar nieuw zijn in de beveiligingsindustrie, is het erg belangrijk om kwetsbare code te bestuderen en de mogelijke gevolgen te begrijpen. Dit helpt bij het verfijnen van codeervaardigheden en het ontwikkelen van een aanvallershouding tijdens de codeerfase in plaats van erna.
In alle eerlijkheid, het is nogal omslachtig om de complete broncode van een applicatie te bestuderen als je op zoek bent naar kwetsbaarheden zoals buffer overflows. Hoewel deze methode zijn eigen verdiensten heeft, is het niet de gemakkelijkste methode om eenvoudige kwetsbaarheden te vinden die kritisch kunnen zijn. Dergelijke kwetsbaarheden moeten onmiddellijk worden verholpen en de eenvoudigste manier om ze te vinden is door middel van een techniek die Fuzzing wordt genoemd.
Fuzzing is een techniek om “eenvoudige” kwetsbaarheden in code te vinden door “willekeurig” gegenereerde gegevens naar een uitvoerbaar programma te sturen. In het algemeen zijn er drie soorten fuzzers:
Mutatie: Een type “domme” fuzzing waarbij misvormde input samples worden gegenereerd en aan de executable worden verstrekt. Deze invoer kan al dan niet overeenkomen met het type invoer dat door de toepassing wordt verwacht, zodat de kans op het vinden van echte bugs niet groot is.
Generatie: Een type “slimme” fuzzing die een aantal initiële testgegevens vereist waaruit het fuzzer-algoritme misvormde input kan genereren vanuit het niets. Dit type fuzzing is in veel gevallen beter dan domme fuzzing, omdat het programma de invoer krijgt die het verwacht.
Evolutionair: Dit type fuzzers gebruikt feedback van elke “fuzz” om na verloop van tijd het formaat van de invoer te leren.
In dit bericht kijken we naar fuzzing met American Fuzzy Lop (AFL). Het is een type evolutionaire fuzzer die geschikt is om programma’s te fuzzen die invoer krijgen van STDIN of een bestand.