Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis...

70
Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure Software Thesis supervisors: Prof. dr. ir. F. Piessens Prof. dr. ir. B. Preneel Academic year 2018 – 2019 Master of Science in Engineering: Computer Science

Transcript of Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis...

Page 1: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Fuzzing Universal Plug and Play

Eleanor Van Looy

Thesis submitted for the degree ofMaster of Science in Engineering:Computer Science, option Secure

Software

Thesis supervisors:Prof. dr. ir. F. PiessensProf. dr. ir. B. Preneel

Academic year 2018 – 2019

Master of Science in Engineering: Computer Science

Page 2: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Fuzzing Universal Plug and Play

Eleanor Van Looy

Thesis submitted for the degree ofMaster of Science in Engineering:Computer Science, option Secure

Software

Thesis supervisors:Prof. dr. ir. F. PiessensProf. dr. ir. B. Preneel

Assessors:Dr. R. Strackx

Dr. G. Karachalias

Mentors:Ing. L. Wouters

Dr. J.T. Mühlberg

Academic year 2018 – 2019

Page 3: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

© Copyright KU Leuven

Without written permission of the thesis supervisors and the author it is forbiddento reproduce or adapt in any form or by any means any part of this publication.Requests for obtaining the right to reproduce or utilize parts of this publicationshould be addressed to the Departement Computerwetenschappen, Celestijnenlaan200A bus 2402, B-3001 Heverlee, +32-16-327700 or by email [email protected].

A written permission of the thesis supervisors is also required to use the meth-ods, products, schematics and programmes described in this work for industrial orcommercial use, and for submitting this publication in scientific contests.

Page 4: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Preface

I would like to thank my supervisors prof. dr. ir. Frank Piessens and prof. dr. ir. BartPreneel for being the driving force behind the research domain of this thesis, especiallyprofessor Piessens for providing feedback at the intermittent presentations. I wouldalso like to thank my assessors dr. Raoul Strackx and dr. Georgios Karachalias forreading and evaluating the text. Special thanks to my mentors ing. Lennert Woutersand dr. Jan Tobias Mühlberg for helping me throughout the year: introducing me tofuzzing and C, giving research suggestions and providing constructive feedback duringthe writing process. I am also grateful to my family and friends, who supported methroughout this process. Especially my mother ir. Emma Arblaster, boyfriend JonasVan Goolen and best friend ir. Rebecca Van Houtvinck for proofreading this thesis.

Eleanor Van Looy

i

Page 5: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Contents

Preface iAbstract ivAbstract vList of Figures and Tables viList of Abbreviations and Symbols vii1 Introduction 1

1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Research Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.4 Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.5 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Background Information 32.1 Universal Plug and Play . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 Fuzzing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Fuzzing the Simple Service Discovery Protocol 113.1 MiniUPnP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.2 libUPnP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4 Fuzzing XML Parser of libUPnP 214.1 Looking for unknown vulnerabilities with AFL . . . . . . . . . . . . 214.2 Analyze results with AddressSanitizer . . . . . . . . . . . . . . . . . 244.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5 Comparing fuzzers AFL and AFLFast 295.1 XML fuzzing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295.2 SSDP fuzzing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

6 Conclusion and Future Work 376.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

A Results 41

ii

Page 6: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Contents

B libUPnP XML Code 45C AddressSanitizer Errors 51Bibliography 55

iii

Page 7: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Abstract

It is hard to write bug free software, certainly for a large project in C. Consequently,it is of paramount importance to test such software exhaustively. The objectiveof this thesis is to find a strategy to automate software vulnerability detection in(C) implementations of stateless network protocols. The approach used to reachthis objective starts by researching existing problems with Universal Plug and Play(UPnP) and then applies fuzz testing to UPnP implementations, thereby designing astrategy to rediscover old vulnerabilities. The fuzz testing is done with AmericanFuzzy Lop (AFL) which automates the generation of test files to feed into a program.The tested implementations are libraries, meaning the tester still has to write aprogram incorporating the library to be fuzzed. Subsequently the approach uses thisstrategy to try to discover new vulnerabilities. Finally comparing the fuzzer AFLto its forked version AFLFast for the previously defined strategies. Two years ago,AFLFast claimed to find bugs faster than AFL. Three main findings were concludedfrom the results. First, the fuzzing strategy that found old vulnerabilities in libUPnP’s(one of two major UPnP libraries) Simple Service Discovery Protocol (SSDP) parserdid not find any faults within the patched version. Secondly, fuzzing the XML parserin combination with AddressSanitizer was able to find an illegal memory read andtwo memory leaks. Lastly, AFL outperformed its forked version AFLFast. No newvulnerabilities were found in the patched SSDP parser, so this part can be consideredrather robust now as it had the most problems in the past. The fact that memorybugs were only found when AddressSanitizer was used in combination with AFL,substantiates the statement that AddressSanitizer improves the chances of findingmemory bugs. Moreover, it does not take long to run, so certainly recommended.The finding that AFL outperforms AFLFast in the experiments done in this thesis isprobably due to AFLFast not having been actively maintained for two years.

iv

Page 8: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Abstract

Het is moeilijk om software te schrijven zonder fouten, zeker als het om een grootproject in C gaat. Daarom is het belangrijk om software te testen. Het doel van dezethesis is om een strategie te bekomen om de detectie van softwarekwetsbaarheden in(C) implementaties van staatloze netwerkprotocollen te automatiseren. De aanpakom dit doel te bereiken begint met het onderzoeken van bestaande problemen vanUniversal Plug and Play (UPnP) en vervolgens het toepassen van fuzz-testen op UPnP-implementaties waarbij een strategie ontworpen wordt om oude kwetsbaarhedenopnieuw te ontdekken. Het fuzz-testen wordt gedaan met American Fuzzy Lop(AFL), die testinput om aan een programma te geven automatisch genereert. Deimplementaties die we testen zijn sofwtarebibliotheken, dit betekent dat de testernog steeds een programma moet schrijven alvorens de fuzzer te kunnen gebruiken.Vervolgens wordt deze strategie gebruikt om nieuwe kwetsbaarheden proberen teontdekken. Ten slotte wordt de fuzzer AFL met zijn afgesplitste versie AFLFastvergeleken op eerder gedefinieerde strategieën. Twee jaar geleden beweerde AFLFastsneller fouten op te kunnen sporen dan AFL. Drie belangrijke bevindingen werdengeconcludeerd. Ten eerste heeft de fuzzing-strategie die oude kwetsbaarheden in deSimple Service Discovery Protocol (SSDP) parser van libUPnP (een van de tweemeest gebruikte UPnP-bibliotheken) gevonden heeft, geen fouten gevonden in deverbeterde versie. Ten tweede kon het fuzzen van de XML-parser in combinatie metAddressSanitizer vinden dat op één plek illegaal geheugen gelezen kan worden en erop twee plekken geheugenlekken kunnen zijn. Ten slotte presteert AFL beter dan zijnafgesplitste versie AFLFast. Omdat er geen nieuwe kwetsbaarheden in de verbeterdeSSDP-parser gevonden zijn en deze parser in het verleden de meeste problemen had,kan dit nu als vrij robuust beschouwd worden. Het feit dat fouten in het omgaan metgeheugen alleen werden gevonden wanneer AddressSanitizer in combinatie met AFLwerd gebruikt, benadrukt de stelling dat AddressSanitizer de kans op het vinden vandeze fouten verbetert. Het duurt ook niet lang om het uit te voeren, dus het is zekeraan te raden. Dat AFL beter presteert dan AFLFast in de experimenten in dezethesis is waarschijnlijk omdat AFLFast al twee jaar niet meer actief is bijgewerkt.

v

Page 9: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

List of Figures and Tables

List of Figures

2.1 Grey-box file fuzzers [23] . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.1 Typical M-SEARCH message [21] . . . . . . . . . . . . . . . . . . . . . . 12

4.1 Debugging AddressSanitizer error . . . . . . . . . . . . . . . . . . . . . . 26

5.1 Coverage report - original input files . . . . . . . . . . . . . . . . . . . . 315.2 Best coverage AFL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.3 Best coverage AFLFast . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.4 Coverage AFL in parallel - 20 minutes . . . . . . . . . . . . . . . . . . . 325.5 Coverage AFLFast in parallel - 8 hours . . . . . . . . . . . . . . . . . . 325.6 AFL - path coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335.7 AFL - crash and hang results . . . . . . . . . . . . . . . . . . . . . . . . 335.8 AFL - execution speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335.9 AFLFast - path coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . 335.10 AFLFast - crash and hang results . . . . . . . . . . . . . . . . . . . . . . 345.11 AFLFast - execution speed . . . . . . . . . . . . . . . . . . . . . . . . . 34

List of Tables

A.1 Coverage results for each path in unique_service_name() . . . . . . . . 41A.2 Reduction values of XML test data files under afl-tmin . . . . . . . . . . 42A.3 AFL fuzzing XML parser summary . . . . . . . . . . . . . . . . . . . . . 42A.4 AFLFast fuzzing XML parser summary . . . . . . . . . . . . . . . . . . 43A.5 AFL fuzzing SSDP parser summary . . . . . . . . . . . . . . . . . . . . 43A.6 AFLFast fuzzing SSDP parser summary . . . . . . . . . . . . . . . . . . 43

vi

Page 10: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

List of Abbreviations and

Symbols

Abbreviations

UPnP Universal Plug and PlaySSDP Simple Service Discovery ProtocolSDK Software Development KitSOAP Simple Object Access ProtocolPnP Plug and PlayIoT Internet of ThingsCVE Common Vulnerabilities and ExposuresAFL American Fuzzy LopST Search TargetGDB GNU Debugger

vii

Page 11: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 12: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 1

Introduction

1.1 Motivation

According to “UPnPTM Device Architecture 1.1”, UPnP is a network protocol de-signed to be invisible to mainstream users. In itself it is not a secure protocol,as its architecture does not enforce any authentication [31]. On top of that theimplementations have various flaws [26, 10, 11]. In addition, UPnP software de-velopment kits (SDK’s) are frequently integrated into devices (especially routers)without much discernment [24]. The most popular SDK’s (libUPnP [17] and Mini-UPnP [25]) are written in C making them more prone to bugs. Furthermore, manyhome/small-business router companies use the same UPnP SDK [26], which makesfinding exploitable vulnerabilities in these SDK’s worthwhile for attackers. Especiallybecause getting access to a router results in access to its network [19]. Users are oftenoblivious to these security issues. This makes it all the more crucial for developersand (security) testers to minimize software vulnerabilities in order to prevent attacks.Unfortunately, time constraints during development sometimes result in functionalitybeing the only priority, consequently neglecting security aspects. There are multipleways to search for vulnerabilities, for instance checking the code manually, symbolicexecution or fuzz testing. Fuzzing automates the test process. It has become apopular method for finding vulnerabilities in software since its introduction in theearly nineties [23]. This popularity stems from the simple concept, straightforwarddeployment and the empirical results showing its e�ectiveness [23]. For example, thee�ectiveness can be demonstrated by the fuzzer AFL’s trophy case [42]: it has foundbugs in browsers and operating systems, among other things.

1.2 Related Work

A lot of related work can be found for both fuzzing and UPnP vulnerabilities, butnot for a combination of the two. The most substantial contribution about thevulnerabilities in UPnP happened in 2013 when Rapid7 released the white paper“Security Flaws in Universal Plug and Play” [26]. In this paper the authors discusstheir research measuring the global exposure of UPnP (supposed to only be locally

1

Page 13: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

1. Introduction

available) which resulted in finding that the two most used UPnP libraries (miniUPnPand libUPnP) contained remotely exploitable vulnerabilities. The researchers did thisby sending UPnP discovery requests to every routable IPv4 address approximatelyonce every week for five and a half months. 81 million unique IP addresses respondedto these discovery requests. 20% of these also expose their Simple Object AccessProtocol (SOAP) service. SOAP allows commands to be sent to a UPnP device, whichmeans remote attackers can target systems behind the firewall. A lot of informationabout fuzzing can be found in “Fuzzing: Art, Science, and Engineering” [23]. Inthis paper they make a generalization of 55 di�erent fuzzers so their di�erences andrelationship to each other can be discussed more easily. The choice of fuzzers to becompared in this thesis came from the information in this paper.

1.3 Research Goals

Using UPnP implementations as an example we intend to come up with a strategyto automate detection of software vulnerabilities in implementations of statelessnetwork protocols. Specifically, by evaluating AFL’s ability to rediscover knownvulnerabilities and to find unknown vulnerabilities in di�erent components of UPnPimplementations. Thereby developing an in depth understanding of the UPnPprotocol; fuzzing; Unix commands; vim; shell scripting and compiling, linking anddebugging C code.

1.4 Approach

Chapter 2, the background chapter, introduces the reader to the two main subjects ofthis thesis: UPnP and fuzzing. It also explains how to operate the used fuzzers. Afterthis introduction, Chapter 3 demonstrates how to find known vulnerabilities in theSSDP implementation of the two most used UPnP libraries by fuzzing. It subsequentlyexplains how to use that experience to find unknown vulnerabilities in a patchedSSDP implementation of one of the two libraries (libUPnP). In Chapter 4 a di�erentpart of libUPnP gets analyzed: the UPnP specific eXtensible Markup Language(XML) parser. This part of the library has no known (previous) vulnerabilities. Thefuzzing strategies of Chapters 3 and 4 are used to compare two fuzzers, to find outwhich fuzzer is more appropriate for this library. Finally, in Chapter 6 the conclusionof this thesis and suggestions for further work are formulated.

1.5 Results

Three main conclusions arise from this thesis. First, the fuzzing strategy that foundold vulnerabilities in libUPnP’s SSDP parser did not find any faults within the patchedversion. Secondly, fuzzing the XML parser in combination with AddressSanitizer wasable to find an illegal memory read and two memory leaks. Lastly, AFL outperformsits forked version AFLFast which claimed to find bugs faster two years ago, but hasnot been actively maintained since then.

2

Page 14: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 2

Background Information

In this chapter the Universal Plug and Play protocol and Fuzzing techniques arediscussed as a foundation for this thesis.

2.1 Universal Plug and Play

UPnP is based on Plug and Play (PnP) [12], which is designed to be able to pluga device into a system without user configuration. UPnP takes this principle andapplies it on a network. The idea of Universal Plug and Play is enabling networkeddevices to discover and possibly control each other on a (local) network, withoutuser interference [31, 14, 19].

2.1.1 History & Use

In the late 1990s when networks started getting popular various companies were look-ing for solutions to make networks and networked applications easier to manage [14].One such solution was proposed by Microsoft: the UPnP protocol [28]. This protocoltargets home networks, proximity networks and networks in small businesses andcommercial buildings [31]. Nowadays there are a lot of programs and devices thatdepend on UPnP (e.g. Internet of Things (IoT) devices, gaming platforms) and onrouters it is even turned on by default in most cases [14, 26].

As mentioned in the introduction of this section, the main objective of UPnPis to create peer-to-peer network connectivity of network devices and networkedprograms on a LAN with little to no manual user configuration to make these devicesand programs easier to manage. The devices and programs do this through discoveryand advertisements of services and configure themselves accordingly [31].

Aside from easily adding networked devices and applications to your LAN, UPnPis often used by software for port forwarding [24]. Again, to eliminate manualconfiguration.

3

Page 15: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2. Background Information

2.1.2 Protocol stack

The description of the protocol stack is based on “UPnPTM Device Architecture 1.1”made by the UPnP Forum [31]. The UPnP protocol consists of multiple layers inwhich a combination of network protocols are used for seamless proximity networkingin addition to control and data transfer among networked devices. These layers are:

• Addressing

• Discovery

• Description

• Control

• Eventing

• Presentation

In the first layer, addressing, the network device tries to obtain an IP address andconnects to the local network. In the second layer, the device tries to discover otherdevices on the network using the Simple Service Discovery Protocol (SSDP). Firsta multi-cast discovery message gets sent over UDP. Then potentially other UPnPdevices on the network answer with a description URL, which is used in the nextlayer, the description layer. The device can use the description URL of anotherdevice to find its UPnP service profile. This is an XML file describing its device withcontrol URL’s, where commands can be sent to by other devices. This mechanism isdefined in the next two layers. In the control layer the SOAP protocol is used tosend a command to a control URL of an other device. In the eventing layer a UPnPdevice can subscribe to the state of an other UPnP device if a subscribe control URLis available. In the last layer, presentation, it is possible to have a UI to present thedevice, for instance a web interface of a router.

2.1.3 UPnP Security Issues

The worst flaw found in a UPnP implementation results in routers having UPnPavailable on the WAN side. This means attackers can remotely exploit devices onthe LAN of these routers. This was found by the Rapid7 [26] research group, seeSection 1.2. Being exposed to the internet is not a prerequisite for exploiting otherUPnP vulnerabilities [6]. A malicious program could open up ports on a router whereincoming tra�c from the internet gets through the firewall or vulnerabilities could beexploited locally (this explains why UPnP is designed for small and trusted networks).To give an idea of the amount of flaws in the implementations of UPnP, there are 94related Common Vulnerabilities and Exposures (CVE) entries [8], starting in 2001and still actively being found with the last one, at time of writing, in July 2019. Ofall things using UPnP, routers are the most interesting to exploit because this couldpotentially give access to a whole network [19]. UPnP is switched on by default onmost routers nowadays [15] and most users have no idea of what UPnP is or do not

4

Page 16: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2.2. Fuzzing

even use it. Consequently, they certainly do not know what its flaws are thus a lotof routers are unnecessarily vulnerable to attacks. Moreover, users do not tend toupdate firmware [19] (or updates are not distributed), so older vulnerabilities canstill be and are actively exploited. For instance, in November 2018 Hui Wang andRootKiter published an article about how they found a 100k node botnet [37] used tosend spam based on a format string vulnerability found in 2013 by DefenseCode [19].

2.2 Fuzzing

A fuzzer tool automatically generates (mostly unexpected) input which it feeds to aprogram and then analyzes the behaviour of the program for each of these inputs [7].A fuzzer is defined by how it generates and schedules input and how it analyzesthe behaviour of the program. To study the di�erences in fuzzers better, thesetwo characteristics will be discussed considering the two fuzzers used for this thesis:AFL [42] and AFLFast [4] and a third fuzzer libFuzzer [20]. After this discussionfollows a description of how to choose a fuzzer. All this is based on the paper“Fuzzing: Art, Science, and Engineering” [23]. Finally, how to use AFL will bedescribed in detail as it is used extensively in this thesis. AFLFast is used in thesame way.

2.2.1 Analyzing Behaviour

A fuzzer can observe the behaviour of a program in di�erent levels of detail. Ablack-box fuzzer can only observe the input and output behaviour. A white-boxfuzzer analyzes the internals of the program and information gathered while executing.White-box fuzzing has a higher overhead but more information about the programthan black-box fuzzing. Between these two extremes lies grey-box fuzzing whichuses information approximation to test more inputs in the same amount of time aswhite-box fuzzing. AFL, AFLFast and libFuzzer are all grey-box fuzzers.

Grey-box fuzzers are also known as coverage-guided fuzzers. This means theyneed to monitor the code coverage of each test case. They do this by adding theirown code to the program to be executed, which is called instrumenting. Instrumenta-tion can be static (added before execution) or dynamic (added while executing). AFLand AFLFast support both modes, static instrumentation on the source code levelor dynamic instrumentation on binary level. LibFuzzer uses static instrumentation.

AFL and AFLFast di�er the most from libFuzzer in how the gathered informa-tion is used to determine which test cases are more interesting to evolve into newcases. AFL and AFLFast take branch coverage into account by instrumenting everybranch instruction. However, they store this information in a bit vector, which cancause path collisions. LibFuzzer uses node coverage as execution feedback. The goalof node coverage, also known as statement coverage, is to “execute every statementin the program at least once” [27]. With branch coverage the goal is to “write enough

5

Page 17: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2. Background Information

test cases that each decision has a true and a false outcome at least once.” [27] Nodecoverage is easier to keep track of, but the metric is poor.

When the fuzzer detects a violation to its security policy due to a certain in-put, this input is saved as a found bug, which should be triaged later by the user.An obvious violation is when a program crashes (returns fatal signal). A lot ofmemory safety vulnerabilities are found this way and it is easy to implement. AFL,AFLFast and libFuzzer all have the option to add AddressSanitizer [34] to the in-strumentation, which makes the program crash when a memory address is accessedin a wrong way. LibFuzzer has other predefined sanitizer options: UndefinedBe-haviorSanitizer [36], which causes a crash when undefined behavior is detected,and MemorySanitizer [35], which causes a crash when it detects uninitialized reads.To discover other non-crashing design and implementation errors with any of thethree fuzzers abort() can be added to the program to execute under certain circum-stances [39]. To make sure this piece of code is only used when fuzzing the line #ifdefFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (flag all the fuzzersuse) or #ifdef __AFL_COMPILER (flag only AFL and AFLFast use) should beadded.

2.2.2 Input Generation and Scheduling

AFL, AFLFast and libFuzzer are all mutation based fuzzers where one or more seedsgiven by the user are mutated to generate new test cases. There are di�erent sortsof mutations, all three can use dictionary based mutation where a set of predefinedvalues and format strings are used for mutation. AFL and AFLFast also use arith-metic mutation, where simple arithmetic is performed on a selected byte sequence asif it is an integer value.

The scheduling of these inputs is done evolutionary in all three fuzzers. A populationof inputs is maintained, each with a level of ‘fitness’. An evolutionary algorithmselects fit inputs and generates new potential inputs with transformations such asmutation (discussed in previous paragraph) and recombination. To implement anevolutionary algorithm, you need to know three things: what makes an input fit,how inputs are selected and how a selected input is used. The answer to these threethings is what di�erentiates AFL from AFLFast. In AFL the fastest and smallestinput is fit, the next input is selected from a circular queue and a selected input isfuzzed for a constant number of runs. AFLFast has improved AFL in these threeaspects, which makes it find bugs quicker according to the author.

2.2.3 Choosing a Fuzzer

In “Fuzzing: Art, Science, and Engineering” a taxonomy of 55 fuzzers is made. Inmost cases, these fuzzers are introduced in major security and software engineeringconferences. First, these fuzzers are divided into three groups: black-box, grey-boxor white-box, described in Section 2.2.1. Grey-box fuzzers are often more interestingbecause they make a trade-o� between performance and amount of information to

6

Page 18: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2.2. Fuzzing

Figure 2.1: Grey-box file fuzzers [23]

process with information approximation. This makes them able to process moreinputs than white-box fuzzers, but collect more information about an input thanblack-box fuzzers. If only a binary file is available, black-box fuzzing will have to do.If there is enough time for systematic fuzzing, white-box fuzzing is the way to go.

In the group of grey-box fuzzers there is another division: fuzzers for concurrencybugs, kernels or files. In this thesis parsers will be analyzed, so a file fuzzer willbe necessary. The original group of 55 fuzzers is now narrowed down to 14 fuzzers,see Figure 2.1. Arrows are used in the taxonomy to indicate whether a fuzzer cites,references or uses techniques of another fuzzer. As can be seen in Figure 2.1 sixother fuzzers in this category are based on AFL.

In general fuzzers do not tend to have a lot of documentation. However, AFLdoes have a substantial amount (documentation in project [38], Google group [49],creator Michal Zalewski’s blog [42] and other blogs), making it easier to use. Itstrophy case [42] demonstrates its e�ectiveness, including bugs found in iOS, Mozilla

7

Page 19: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2. Background Information

Firefox, VLC and clang.AFL automates the detection of software vulnerabilities in the sense that it

automatically produces input based on given seed files. If a library needs to beanalyzed (like in this thesis) a program that makes use of the library still needs tobe written by the tester [39].

2.2.4 Fuzzing with AFL

AFL can fuzz programs written in C, C++ or Objective C [42]. The UPnP librariesevaluated in this thesis are both written in C, so AFL can be used for both. Settingup AFL and the basics of how to use it are explained in detail in the ‘afl-training’tutorial [22]. This section is based on that tutorial and the AFL README file [39].Once you have got AFL working on your machine, you need an executable programthat you can feed fuzzed input to. As we want to fuzz a library we first need to writea program which uses this library. A program like this is called a harness. If there issample code using the section of the library you want to fuzz included in the library,it could be (partly) used as a harness. Normally, AFL executes the whole programfor every test case. To eliminate the overhead of starting up a new process each time,you can use persistent mode. This enables fuzzing the program in process. To usethis mode you use the AFL function ‘__ AFL_LOOP()’ in a while loop aroundthe part of the code that should run for every test case. AFL comes with compilers(afl-clang, afl-clang-fast and afl-gcc) that extend the original ones (clang and gcc)by injecting instrumentation code (see Section 2.2.1). These compilers do not onlymake instrumentation possible, for instance, to make use of the persistent modementioned above, you need to use afl-clang-fast. To get the most out of AFL it isimportant to not only compile the harness, but also the library with AFL. For mostlibraries compiling will be done with the command ‘CC=/path/to/afl/afl-clang-fast./configure1 && make’. The option ‘AFL_HARDEN=1’ can be added to the makecommand. It enables code hardening making it easier to detect simple memory bugs.

The (static) instrumentation makes fuzzing faster, but changes its executionsemantics. To get execution semantics closer to real execution you can use QEMUmode [44]. QEMU is a processor emulator [32]. With this method you compile theprogram without instrumentation. When fuzzing, the resulting binary runs in anAFL version of QEMU [5] where the instrumentation is added at run-time (dynamicinstrumentation, see Section 2.2.1). The disadvantage is that the fuzzing process cantake 2-5 times longer and the parallelization techniques that AFL provides cannotbe fully utilized. Except for using it to get execution semantics closer to real execu-tion, you can also use QEMU mode to fuzz binaries you do not have the source code of.

Before the fuzzing can start there is one more step to do: producing initial testcases. These test cases should be input that the program would expect [42]. If thelibrary contains unit test for the part you are fuzzing, you can use these. For optimal

1Or with another AFL compiler. In the remainder of this thesis ‘/path/to/afl/’ will be omitted.

8

Page 20: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

2.3. Conclusion

performance these test cases should be small (best under 1 kB) and functionallydi�erent from each other. To make sure the test cases are functionally di�erentyou can use the afl-cmin tool. It will (potentially) shrink a set of test cases to asubset of functionally di�erent test cases that take di�erent paths in the code. Thequality of the initial test cases can have a huge impact on the fuzzing performance [39].

The actual fuzzing generally starts with the ‘afl-fuzz -i in -o out ./harness @@’command, with ‘in’ the directory where the test case(s) reside. AFL will create an‘out’ directory where the queue, crashes and hangs2 are stored. The ‘@@’ option isneeded if the harness takes files as input. If the harness takes input from stdin thisoption is not needed. To fuzz in QEMU mode you need to add the ‘-Q’ option tothe command: ‘afl-fuzz -Q -i in -o out ./harness @@’. To continue fuzzing where youleft of, you replace ‘-i in’ with ‘-i-’.

To increase productivity, parallel fuzzing [46] is possible where multiple corescan be used in parallel for the same fuzz job. To do this you can execute afl-fuzz asmany times as cores you want to use, adding ‘-M fuzzerName’ for a master instanceor ‘-S fuzzerName’ for secondary instances to the command. You also have to makesure they have the same output directory. The master instance will perform in adeterministic way, as opposed to secondary instances that perform randomly. Whenone fuzzer instance is running without a strategy specified it will switch between thetwo modes [30].

Parsers often reject input that does not comply to their grammar. AFL has theoption to include a dictionary in order that the mutations done by the fuzzer makesense grammatically [39].Predefined dictionaries can be found in the ‘dictionaries’directory. To use a dictionary, use the ‘-x path/to/dictionary’ option when callingthe fuzz command.

2.3 Conclusion

UPnP implementations su�er from various flaws, vulnerabilities are getting exploitedand UPnP is widely used, making it an interesting protocol to research. Fuzzing is atried and true method for testing the security of software but it is important to makethe right choice of fuzzer for a particular program type to increase fuzzing success.

2test cases that cause the tested program to time out

9

Page 21: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 22: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 3

Fuzzing the Simple Service

Discovery Protocol

Of all the parts of the UPnP protocol, SSDP is an interesting place to start. It is thefirst step to set up a connection between devices (discovery layer, no previous set-up,see Section 2.1.2) and it has a number of known vulnerabilities [9]. If we take a lookat the vulnerabilities found by Rapid7 (discussed in Section 1.2), a lot of them arein SSDP parsers.

This chapter starts with experimentally evaluating to which extent these SSDPvulnerabilities can be automatically re-discovered with fuzzing using AFL. This isdone for both MiniUPnP and libUPnP. Looking for known vulnerabilities gives youthe opportunity to set up your test environment and check whether and how wellyour fuzz technique works on the protocol. In addition you familiarize yourself withhow the fuzzer you use responds to these vulnerabilities. Another advantage of doingthis, is getting to know the protocol and code better.

After finding known vulnerabilities by fuzzing, the patched version of libUPnP isfuzzed in the same way to check if anything new can be found.

3.1 MiniUPnP

One of the two most used UPnP libraries, MiniUPnP, had multiple vulnerabilitiesin its SSDP parser [26], which were patched in version 1.4. They were found in theProcessSSDPRequest() function, defined in the file minissdp.c, and are known asCVE-2013-0229. The vulnerabilities enable a (remote) attack that causes a service tocrash. The attack is possible with a request it does not expect which makes it a goodcandidate to try and find by fuzzing. The vulnerable code are the lines highlightedin Listing 3.1. The first argument of the ProcessSSDPRequest() function is a sockets. In line 14 it uses this argument to read at most 1500 bytes from this socket whichit stores in bufr[]. To get to the vulnerable code the text read from the socket shouldstart with ‘M-SEARCH’. In Figure 3.1 a typical M-SEARCH message is depicted.

The while loop at line 32 could go on indefinitely if the SSDP request does notend in ‘\r\n’, because there is no check to see if it is still reading from bufr[]. When

11

Page 23: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3. Fuzzing the Simple Service Discovery Protocol

Figure 3.1: Typical M-SEARCH message [21]

the Search Target (ST) field is found in line 35, the while loop at line 39 has thesame problem as it does not check boundaries. However, it is less likely to loop fortoo long as you would need a sequence of spaces and tabs to make it go on. Thewhile loop at line 40 looks more like the first one, as it needs to find ‘\r\n’ to end it.As long as it does not, it will keep on increasing the length of the ST string. Thesepotentially infinite loops are what can cause a crash. This implementation is rathernaive as it assumes the incoming SSDP message will be formed correctly. The secondargument, port, is not important for this vulnerability.

Listing 3.1: MiniUPnP SSDP vulnerability in minissdp.c1 void2 ProcessSSDPRequest ( int s , unsigned short port )3 {4 int n ;5 char bufr [ 1 5 0 0 ] ;6 socklen_t len_r ;7 struct sockaddr_in sendername ;8 int i , l ;9 int lan_addr_index = 0 ;

10 char � s t = 0 ;11 int st_len = 0 ;12 len_r = s izeof ( struct sockaddr_in ) ;1314 n = recvfrom ( s , bufr , s izeof ( bufr ) , 0 ,15 ( struct sockaddr �)&sendername , &len_r ) ;

. . . . . .27 else i f (memcmp( bufr , "M≠SEARCH" , 8) == 0)28 {29 i = 0 ;30 while ( i < n)31 {32 while ( bufr [ i ] != ’ \ r ’ | | bufr [ i +1] != ’ \n ’ )33 i ++;34 i += 2 ;35 i f ( strncasecmp ( bufr+i , " s t : " , 3) == 0)

12

Page 24: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3.1. MiniUPnP

36 {37 s t = bufr+i +3;38 st_len = 0 ;39 while (� s t == ’ � ’ | | � s t == ’ \ t ’ ) s t++;40 while ( s t [ st_len ] != ’ \ r ’ && s t [ st_len ] != ’ \n ’ )41 st_len++;42 }43 }

. . . . . .

3.1.1 Preparations

MiniUPnP daemon version 1.2 [25] was used as the library to fuzz. As the knownvulnerability was patched in version 1.4, any version before that will do. To fuzz alibrary, you first have to make a harness file. The main function of the harness shouldcall an interesting library function to fuzz. For example, to find CVE-2013-0229, theharness calls the ProcessSSDPRequest() function. This function has two arguments:a socket address (where the SSDP request can be read from) and a port number.The port number is hard coded in the harness. The socket address is set by a filedescriptor that points to the file given as a command line argument. This argumentwill be used to fuzz input.

Listing 3.2: MiniUPnP SSDP vulnerability harness1 int main ( int argc , char � � argv )2 {3 int fd = open ( argv [ 1 ] , 0 ) ;4 i f ( fd <1) {5 p r i n t f ( " e r r o r � opening � f i l e � in � harness " ) ;6 return 0 ;7 }8 p r i n t f ( " l e g a l � fd �%i \n" , fd ) ;9 unsigned short port = 15 ;

10 ProcessSSDPRequest ( fd , port ) ;1112 return 0 ;13 }

Usually, the library as well as the harness are compiled using the AFL compiler.When starting out fuzzing however, I thought it was su�cient to add the vulnerablefunction to the harness and just compile that with an AFL compiler. Even though it issu�cient for finding that specific vulnerability, code dependencies are neglected whichhinders reuse. I compiled the library by using the command ‘make -f Makefile.linux’in the root directory of the library. To compile the harness I used the command‘AFL_HARDEN=1 afl-clang-fast harness.c -o harness’ in the directory the harnessis located.

13

Page 25: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3. Fuzzing the Simple Service Discovery Protocol

Once the compiling is done, we need to find a seed file. A file containing a validSSDP request (Listing 3.3) was prepared and put into a directory ‘in’.

Listing 3.3: MiniUPnP SSDP input-seed1 M≠SEARCH � HTTP/1.12 HOST: 2 3 9 . 2 5 5 . 2 5 5 . 2 5 0 : 1 9 0 03 ST : ssdp : a l l

3.1.2 Fuzzing

Now all the preparations are done, the fuzzing can begin. The command used inthe terminal to get AFL to fuzz our harness (called within the directory where theharness executable resides) with the previously mentioned seed file is ‘afl-fuzz -i in-o out ./harness @@’. With this setup, the first crash happened straight away, andthis crash was indeed the result of the vulnerability we were looking for. To fuzzthe harness in QEMU mode we use the command ‘afl-fuzz -Q -i in -o outQEMU./harness @@’, paying attention that this is the harness compiled with a regularcompiler. With this setup, there was not even a crash after 1 hour. We concludethat using QEMU is not recommended for fuzzing UPnP libraries.

3.2 libUPnP

After fuzzing the SSDP parser of MiniUPnP, we switched to fuzzing the otherfrequently used UPnP library, libUPnP (also known as Portable SDK for UPnPDevices [17]). Here we will also look for known vulnerabilities first. The SSDPparser of libUPnP is implemented in the ssdp_server.c file. In the Rapid7 paper [26]mentioned above, there were seven remotely exploitable vulnerabilities (all bu�eroverflows) found in the unique_service_name() function in version 1.3.1. One ofthese is CVE-2012-5958 which is the vulnerability we are going to try and find byfuzzing. The lines that cause this vulnerability are line 36 and 37 in Listing 3.4,highlighted in yellow. The other six are highlighted in green. The length passed asthe third argument of the strncpy() function is the distance between two parts ofthe request, but is not checked against the size of the destination bu�er TempBuf,which is 300.

Listing 3.4: libUPnP SSDP vulnerability in ssdp_server.c1 int2 unique_service_name ( IN char �cmd ,3 IN SsdpEvent � Evt )4 {5 char �TempPtr ,6 TempBuf [COMMAND_LEN] ,7 �Ptr ,8 � ptr1 ,

14

Page 26: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3.2. libUPnP

9 � ptr2 ,10 � ptr3 ;11 int CommandFound = 0 ;1213 i f ( ( TempPtr = s t r s t r ( cmd , " uuid : schemas " ) ) != NULL )14 {1516 ptr1 = s t r s t r ( cmd , " : dev i c e " ) ;17 i f ( ptr1 != NULL ) {18 ptr2 = s t r s t r ( ptr1 + 1 , " : " ) ;19 } else {20 return ≠1;21 }2223 i f ( ptr2 != NULL ) {24 ptr3 = s t r s t r ( ptr2 + 1 , " : " ) ;25 } else {26 return ≠1;27 }2829 i f ( ptr3 != NULL ) {30 s p r i n t f ( Evt≠>UDN, " uuid :%s " , ptr3 + 1 ) ;31 } else {32 return ≠1;33 }3435 ptr1 = s t r s t r ( cmd , " : " ) ;36 i f ( ptr1 != NULL ) {37 strncpy ( TempBuf , ptr1 , ptr3 ≠ ptr1 ) ;38 TempBuf [ ptr3 ≠ ptr1 ] = ’ \0 ’ ;39 s p r i n t f ( Evt≠>DeviceType , " urn%s " , TempBuf ) ;40 } else {41 return ≠1;42 }43 return 0 ;44 }4546 i f ( ( TempPtr = s t r s t r ( cmd , " uuid " ) ) != NULL ) {47 // p r i n t f ( " cmd = %s \n " ,cmd ) ;48 i f ( ( Ptr = s t r s t r ( cmd , " : : " ) ) != NULL ) {49 strncpy ( Evt≠>UDN, TempPtr , Ptr ≠ TempPtr ) ;50 Evt≠>UDN[ Ptr ≠ TempPtr ] = ’ \0 ’ ;51 } else {52 s t r cpy ( Evt≠>UDN, TempPtr ) ;53 }54 CommandFound = 1 ;

15

Page 27: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3. Fuzzing the Simple Service Discovery Protocol

55 }5657 i f ( s t r s t r ( cmd , " urn : " ) != NULL58 && s t r s t r ( cmd , " : s e r v i c e : " ) != NULL ) {5960 i f ( ( TempPtr = s t r s t r ( cmd , " urn " ) ) != NULL ) {61 s t r cpy ( Evt≠>ServiceType , TempPtr ) ;62 CommandFound = 1 ;63 }64 }6566 i f ( s t r s t r ( cmd , " urn : " ) != NULL67 && s t r s t r ( cmd , " : dev i c e : " ) != NULL ) {68 i f ( ( TempPtr = s t r s t r ( cmd , " urn " ) ) != NULL ) {69 s t r cpy ( Evt≠>DeviceType , TempPtr ) ;70 CommandFound = 1 ;71 }72 }7374 i f ( CommandFound == 0 ) {7576 return ≠1;77 }7879 return 0 ;80 }

3.2.1 Preparations

This time we will compile both the library and harness with AFL. Usually, it ispreferable to compile with afl-clang-fast as it uses compiler-level instrumentation.In contrast afl-gcc and afl-clang use assembly-level rewriting. The full accountof why this is better can be found in the README.llvm [43]. Unfortunately,compiling with clang resulted in some issues that we did not have with gcc. It isalso advised to link to a static library rather than to a shared library because it“will avoid having to do library preloading when running the executable.” [1]. Inthis case though, linking to a static library made fuzzing slower. To compile thelibrary you navigate to the library’s directory in the terminal and type ‘CC=afl-gcc./configure’ followed by ‘sudo make install’. The shared library is now installedin /usr/local/lib. To make sure your harness executable will be able to access itlater, add /usr/local/lib to the LD_LIBRARY_PATH environment variable (‘exportLD_LIBRARY_PATH=/usr/local/lib’ in terminal). In libUPnP you cannot justuse any function in the library (without making changes to the library) to fuzz, butonly the functions defined in the API. The other functions are defined as local andare unknown outside of the library. So to find which function should be fuzzed to

16

Page 28: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3.2. libUPnP

find the vulnerability, you have to find which function in the API calls that function.After analyzing the code a bit, this was found to be UpnpSearchAsync(). Beforewe can use this function however, some initializations have to take place. Theseare done with the UpnpInit() and UpnpRegisterClient() functions, see Listing 3.5.UpnpSearchAsync() takes a bu�er which contains the Search Target (ST) field ofthe SSDP request. This bu�er eventually gets passed as the first argument of theunique_service_name() function (see Listing 3.4). To make sure each fuzz run goesover the vulnerable code this bu�er should start with ‘uuid:schemas:device:’ and endwith ‘:anything’. The characters in between are directly determined by the fuzz testcases.

Listing 3.5: libUPnP SSDP vulnerability harness.1 int main ( int argc , char � � argv )2 {3 char � ip_address = " 1 92 . 1 68 . 0 . 2 11 " ;4 unsigned short port = 49152 ;5 int r e t = UpnpInit ( ip_address , port ) ;6 i f ( r e t != UPNP_E_SUCCESS) {7 p r i n t f ( " Error � with�UpnpInit�≠≠�%d\n" , r e t ) ;8 }9

10 int rc = UpnpRegisterCl ient (11 TvCtrlPointCallbackEventHandler , &ctr lpt_handle ,12 &ctr lpt_handle ) ;13 i f ( rc != UPNP_E_SUCCESS) {14 p r i n t f ( " Error � r e g i s t e r i n g �CP: �%d\n" , rc ) ;15 }1617 char prepend [ 2 2 ] = " uuid : schemas : dev i c e : " ;18 char append [ 5 ] = " : end " ;19 char f uzz [ 2 8 0 ] ;2021 char buf [ 3 0 6 ] ;2223 f g e t s ( fuzz , 280 , s td in ) ;24 fuzz [ s t r c spn ( fuzz , " \n " ) ] = 0 ;25 s t r cpy ( buf , prepend ) ;26 s t r c a t ( buf , fuzz ) ;27 s t r c a t ( buf , append ) ;28 buf [ 3 0 5 ] = ’ \0 ’ ;2930 rc = UpnpSearchAsync ( ctr lpt_handle , 5 , buf , NULL ) ;31 i f (UPNP_E_SUCCESS != rc ) {32 p r i n t f ( " Error � sending � search � r eque s t%d\n" , rc ) ;33 }

17

Page 29: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3. Fuzzing the Simple Service Discovery Protocol

34 return 0 ;35 }

The harness is now ready to be compiled and linked to the shared library. Thiswas done with the command given in Listing 3.4.

Listing 3.6: Linking command for libUPnP harness1 AFL_HARDEN=1 a f l ≠gcc ≠DHAVE_CONFIG_H2 ≠I ~/ libupnp ≠1.3.1/ upnp/ inc ≠I ~/ libupnp ≠1.3.1/ ixml / inc3 ≠I ~/ libupnp ≠1.3.1/ upnp/ s r c / inc ≠I ~/ libupnp ≠1.3 .1 harness . c ≠o harness ≠g ≠O24 ≠Os ≠Wall ≠pthread ≠lupnp

3.2.2 Fuzzing

The fuzzing was started with command ‘afl-fuzz -i in -o out ./harness’, so just a singlefuzzing instance. Fuzzing a specific code path in unique_service_name() results infinding the corresponding bu�er overflow after in 1 minute (54 seconds) or 1 hour(58 minutes), depending on the seed given. More specifically, only fuzzing part of thefield by prepending the fuzz input with ‘uuid:schemas:device:’ and appending it with‘:anything’ the bu�er overflow corresponding to this path in unique_service_name()(CVE-2012-5958) is found after 5 minutes of fuzzing if the seed is 160 characters long(bu�er overflow is triggered when it is 161 characters long). If the seed has a morerealistic length of 8 characters, however, it takes 1 hour before the bu�er overflow isfound. This is a result of AFL mostly using bit flips to mutate its data, so it is notideal if you are specifically looking for bu�er overflows. To look for memory bugs itis recommended to use AddressSanitizer in combination with AFL, as is done laterin Section 4.2.

3.2.3 Fuzzing newest libUPnP version

Now the fuzz strategy for libUPnP is fine-tuned, the latest version libUPnP 1.8.4 [17]can be fuzzed for new vulnerabilities. To check if there were any remaining vul-nerabilities left in unique_service_name() in version 1.8.4 every code path in thisfunction was fuzzed until the number of cycles turned green for both the master andsecondary instance. This happens when the fuzzer has not found any new paths in along while [48]. One of the seeds used is the one that results in a bu�er overflow inversion 1.3.1. The other seed is the same one used for fuzzing version 1.3.1: ‘tvdevice’.The di�erent code paths are defined by what is prepended and appended to thefuzzed string. In the most simple case nothing is prepended or appended. There are6 di�erent cases which all have its own harness in its own directory. To link them allat once a the script in Listing 3.7 can be used. Now the folders for each case alsocontain their respective executable file used to fuzz.

Listing 3.7: Script for linking multiple harness files simultaneously.1 #!/ bin /bash

18

Page 30: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

3.3. Conclusion

2 FOLDERS=~/path/ to /main/ d i r e c t o r y /�/34 f o r f o l d e r in $FOLDERS5 do6 HARNESS=$ ( basename ≠≠ $ f o l d e r � . c )7 EXECUTABLE=${HARNESS%.�}8 AFL_HARDEN=1 a f l ≠gcc ≠DHAVE_CONFIG_H9 ≠I ~/ libupnp ≠1.8.4/ upnp/ inc ≠I ~/ libupnp ≠1.8.4/ ixml / inc

10 ≠I ~/ libupnp ≠1.8.4/ upnp/ s r c / inc ≠I ~/ libupnp ≠1.8 .411 $folder$HARNESS ≠o $folder$EXECUTABLE12 ≠g ≠O2 ≠Os ≠Wall ≠l p thread ≠lupnp ≠l i xm l1314 done

For the fuzzing setup one master and one secondary fuzz instance is used. Therewere no crashes in any of the fuzz runs. This together with the patch that now checksthe size of the bu�ers properly (where it used to have a vulnerability in almost everyline) leads us to believe there are no remaining vulnerabilities in this function. Thecoverage of each fuzz run for each case is shown in A.1. This wraps up fuzzing theSSDP part of the protocol.

3.3 Conclusion

MiniUPnP is an easier library to work with as it is more lightweight than libUPnPand no functions are defined as local, so any function can be fuzzed directly. At firstsight, QEMU mode is not interesting to use for UPnP libraries, but more experimentsshould be done (including using it on libUPnP) to be sure. The chance is small thatthere are still vulnerabilities in the SSDP parser of libUPnP. At least, they were notfound with the fuzzing techniques used in this chapter.

19

Page 31: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 32: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 4

Fuzzing XML Parser of libUPnP

In this chapter libUPnP’s1 UPnP specific XML parser is analyzed with AFL. Thispart of libUPnP has no known vulnerabilities [10, 11] and XML parsers have provento be prone to vulnerabilities in the past [18]. In the UPnP protocol an XML parseris used to parse the description file of a UPnP device in the description layer, seeSection 2.1.2.

4.1 Looking for unknown vulnerabilities with AFL

The XML library includes a test folder with a test document and test data that canbe used as a starting point for the test harness (see Listing 4.1) and initial test cases.

To make sure this function (ixmlLoadDocumentEx) is useful to fuzz, it shouldbe checked if it gets used by the sample code for UPnP devices and control pointsprovided by the libUPnP library. This function does not get used there, but it usesa similar function ixmlParseBu�erEx, see Listing 4.2 and 4.3. The di�erence is thatTRUE indicates you want to read from a file and FALSE indicates a bu�er needs tobe copied to the parser.

The static library and compiler issues from Section 3.2.1 are not a problem whenjust using the xml part of the library. This means the library can be configured with’CC=afl-clang-fast ./configure –disable-shared’. The linking command to compilethis harness is shown in Listing 4.4.

Listing 4.1: libUPnP XML harness1 int main ( int argc , char� argv [ ] )2 {3 int rc ;4 IXML_Document� doc = NULL;5 DOMString s ;6 char� p ;

1version 1.8.4 [17]

21

Page 33: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4. Fuzzing XML Parser of libUPnP

78 p r i n t f ( " Test �\"%s \" �\n" , argv [ i ] ) ;9 p r i n t f ( " ����Loading� . . . � " ) ;

10 f f l u s h ( stdout ) ;1112 rc = ixmlLoadDocumentEx ( argv [ i ] , &doc ) ;13 i f ( rc != IXML_SUCCESS) {14 f p r i n t f ( s tde r r ,15 " ��� e r r o r � : �can ’ t � load �document�%s � : � "16 " e r r o r �%d�(%s )\n " ,17 argv [ i ] , rc , get_ixml_error_str ing ( rc ) ) ;18 e x i t (EXIT_FAILURE) ; // ≠≠≠≠≠≠≠≠≠≠>19 }2021 p r i n t f ( "OK\n" ) ;2223 p r i n t f ( " ���� Pr int ing � . . . � " ) ;24 f f l u s h ( stdout ) ;2526 s = ixmlPrintDocument ( doc ) ;27 i f ( s == NULL | | s [ 0 ] == ’ \0 ’ ) {28 f p r i n t f ( s tde r r ,29 " ��� e r r o r � : �can ’ t � pr in t � loaded �document�%s \n" ,30 argv [ i ] ) ;31 e x i t (EXIT_FAILURE) ; // ≠≠≠≠≠≠≠≠≠≠>32 }33 p = s + s t r l e n ( s ) ≠1;34 while ( i s s p a c e (�p) && p > s )35 p≠≠;36 i f (� s != ’< ’ | | �p != ’> ’ ) {37 f p r i n t f ( s tde r r ,38 " ��� e r r o r � : �malformed� pr inted �document� ’%s ’ � : "39 "%s \n" , argv [ i ] , s ) ;40 e x i t (EXIT_FAILURE) ; // ≠≠≠≠≠≠≠≠≠≠>41 }4243 p r i n t f ( "OK\n" ) ;4445 ixmlFreeDOMString ( s ) ;46 ixmlDocument_free ( doc ) ;4748 e x i t (EXIT_SUCCESS) ;49 }

22

Page 34: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4.1. Looking for unknown vulnerabilities with AFL

Listing 4.2: ixmlLoadDocumentEx function1 int ixmlLoadDocumentEx ( const char � xmlFile ,2 IXML_Document �� doc )3 {4 i f ( xmlFi le == NULL | | doc == NULL) {5 return IXML_INVALID_PARAMETER;6 }78 return Parser_LoadDocument ( doc , xmlFile , TRUE) ;9 }

Listing 4.3: ixmlParseBu�erEx function1 int ixmlParseBufferEx ( const char � bu f f e r ,2 IXML_Document �� retDoc )3 {4 i f ( b u f f e r == NULL | | retDoc == NULL) {5 return IXML_INVALID_PARAMETER;6 }78 i f ( b u f f e r [ 0 ] == ’ \0 ’ ) {9 return IXML_INVALID_PARAMETER;

10 }1112 return Parser_LoadDocument ( retDoc , bu f f e r , FALSE) ;13 }

Listing 4.4: Linking command for XML harness1 AFL_HARDEN=1 a f l ≠clang≠f a s t ≠DHAVE_CONFIG_H ≠L ~/path/ to / s t a t i c / l i b r a r y /2 ≠I ~/ libupnp ≠1.8.4/ upnp/ inc ≠I ~/ libupnp ≠1.8.4/ ixml / inc3 harnessxml . c ≠o harnessxml ≠g ≠Os ≠Wall ≠l i xm l

In the next step the test data files are minimized to get rid of redundant infor-mation. This can be done with AFL’s afl-cmin and afl-tmin tools. When providingit with a folder of test data files, afl-cmin will return the smallest subset of thesefiles that still trigger all the important points triggered by the original dataset [40].To use this tool on the initial set of test data, the command ‘afl-cmin -i in -o inmin./harnessxml @@’ is used. This reduces the original set of 38 files to a set of 19files. Larger test files take more memory and time from the binary being fuzzed andmake the fuzzing process less e�cient in other ways [47]. Afl-tmin takes a single fileas input and tries to remove as much data as possible from this file, while makingsure it has the same execution path [41]. Performing afl-tmin on each file in theinmin directory was done with ‘for i in *; do afl-tmin -i $i -o $i.min ./harnessxml@@; done;’. The resulting reductions are shown in Appendix A.2. Now we have an

23

Page 35: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4. Fuzzing XML Parser of libUPnP

e�cient initial set of test data files to start fuzzing.

AFL comes with predefined dictionaries that can be used to seed the fuzzingprocess [39]. To include the XML dictionary in our fuzzing process, the ‘-x /afl-2.52b/dictionaries/xml.dict’ option is used.

To take advantage of parallel fuzzing (explained in Section 2.2.4) one masterfuzzer and two secondary fuzzers were used. The resulting commands are ‘afl-fuzz -x/afl-2.52b/dictionaries/xml.dict -i in -o out -M fuzzer1 ./harnessxml @@’, ‘afl-fuzz -x/afl-2.52b/dictionaries/xml.dict -i in -o out -S fuzzer2 ./harnessxml @@’ and ‘afl-fuzz-x /afl-2.52b/dictionaries/xml.dict -i in -o out -S fuzzer3 ./harnessxml @@’.

After 35 hours in which the master fuzz instance performed 4 and each secondaryinstance more than 500 cycles, AFL had not found any crashes. Comparing thisto the time it took to find the SSDP vulnerabilities in Section 3.2.2, and readingabout other AFL users experience [2] I decided that it did not make much sense tocontinue fuzzing. However, this does not mean that there are no results. The queuesgenerated by the fuzzer instances can be used to run through AddressSanitizer.

4.2 Analyze results with AddressSanitizer

AddressSanitizer detects memory bugs [34] which can be used in combination withAFL, but it uses a lot of memory thus slowing down the fuzzing. That is whyit is recommended to use it after fuzzing [45] on the created queue. To do thisthe binary has to be compiled and linked with the ‘-fsanitize=address’ flag. Thelinking command to compile the harness with AddressSanitizer is shown in Listing 4.5.

Now the binary is compiled and linked, it needs to run with each queue elementone by one. The script that takes care of this is shown in Listing 4.6. The output ofeach run is printed to the file ‘asan.log’. AddressSanitizer outputs errors via stderr,so ‘&>>’ is needed instead of the usual ‘>>’ to print to a file.

When analyzing the ‘asan.log’ file, two types of errors can be found: ‘Address-Sanitizer: SEGV on unknown address’ where SEGV stands for segmentation faultand ‘LeakSanitizer: detected memory leaks’. One queue element triggers the firsterror (see error in Appendix C.1), eight elements trigger the second (see error inAppendix C.2 and C.3).

According to the error in Appendix C.1 the memory access occurs at line 795 offile ixmlparser.c which is part of Parser_getChar (line 66 in Appendix B.1).

Listing 4.5: Linking command for XML harness with AddressSanitizer1 AFL_HARDEN=1 a f l ≠clang≠f a s t ≠DHAVE_CONFIG_H ≠L .2 ≠I ~/ libupnp ≠1.8.4/ upnp/ inc ≠I ~/ libupnp ≠1.8.4/ ixml / inc

24

Page 36: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4.2. Analyze results with AddressSanitizer

3 harnessxml . c ≠o harnessxmlasan ≠g ≠Os ≠Wall ≠l i xm l4 ≠ f s a n i t i z e=address

Listing 4.6: Script AddressSanitizer1 #!/ bin /bash2 FILES1=~/path/ to /out/ fu z z e r 1 /queue /�3 FILES2=~/path/ to /out/ fu z z e r 2 /queue /�4 FILES3=~/path/ to /out/ fu z z e r 3 /queue /�56 f o r f i l e in $FILES17 do8 ~/path/ to / binary / harnessxmlasan $ f i l e &>> asan . l og9 done

1011 f o r f i l e in $FILES212 do13 ~/path/ to / binary / harnessxmlasan $ f i l e &>> asan . l og14 done1516 f o r f i l e in $FILES317 do18 ~/path/ to / binary / harnessxmlasan $ f i l e &>> asan . l og19 done

To understand what goes wrong, we run the program with the XML file thatinitiates the error (see Listing 4.7) with GNU Debugger (GDB). First, the programshould be compiled in debug mode. For the library this results in ‘./configure –enable-debug && make’. Then the linking command for the harness looks like Listing 4.8.

Now the harness is ready to debug. The function Parser_getChar of Appendix B.1gets called the last time on the & character in the last line of Listing 4.7. In thisfunction the rest of the characters get looped over in the while loop at line 64. Afterit handled all the 0’s of the file, the while loop is done five more times: four timesfor ’\000’ (NULL) and once for ’Q’ as can be seen in Figure 4.1.

It does this for multiple reasons. First o� it expects the hex number to end in asemicolon. Secondly the file does not end in ‘\r\n’. And lastly, this only happens ifthe implementation of strchr() accepts NULL values [16]. This is where the programreads an illegal memory location. However, this information does not leak to theharness file. As can be seen at line 75 of Appendix B.1, if the hex number did notend in a ‘;’ the function returns an error and not the calculated sum of the whileloop.

25

Page 37: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4. Fuzzing XML Parser of libUPnP

Figure 4.1: Debugging AddressSanitizer error

Listing 4.7: XML file that causes AddressSanitizer error1 <?xml 00000000000000000000000000? >2 <!≠≠0≠≠><!≠≠0≠≠>3 <!≠≠0≠≠>4 <t e s t xmlns=’http000www0ascc0net0xml0test0schema ’

type=" io0 "> <name>Chinese Test 000 UTF00</name>89 <data>This f i l e has 0 Chinese characterH

#REQUIREDencoded us ing1011 a hexadecimal nume12 <data>The XM0 header j f t h i s f i l e i s1314 &l t ; ? xml encoding0 "UTF00"?& gt ; 015 </data>16 <data>The charac t e r i s here0 [&#xEE0D00000000000000

26

Page 38: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

4.3. Conclusion

Listing 4.8: Linking command for debug mode1 gcc ≠DHAVE_CONFIG_H ≠L ~/path/ to / l i b i x m l . a2 ≠I ~/ libupnp ≠1.8.4/ upnp/ inc ≠I ~/ libupnp ≠1.8.4/ ixml / inc3 harnessxml . c ≠o harnessxml ≠g ≠Os ≠Wall ≠l i xm l

Next, take a look at the LeakSanitizer output in Appendix C.2. The memoryleak results from a malloc() in the ixmlDocument_createTextNodeEx() function,see line 15 in Appendix B.2. One of the XML files that causes this error is shownin Listing 4.9. The last character ‘M’ is of type ‘eTEXT_NODE’ which causes theprogram to run the code in the case statement at line 49 in Appendix B.3. Herethe function ixmlDocument_createTextNodeEx() is called, with &tempNode asthe last argument. In ixmlDocument_createTextNodeEx() tempNode is know astextNode. At line 15 of Appendix B.2 the malloc is done for returnNode. At theend of this function, returnNode is assigned to textNode. So now there is a mallocedmemory block with address in tempNode in Parser_parseDocument(). This addressis passed to ixmlNode_appendChild() at line 58, which does not return successfully.Subsequently, Parser_parseDocument() goes to its ErrorHandler, which does notcontain a free() statement for tempNode. This memory leak could potentially leadto a crash if an XML file like this were to be sent continuously to a UPnP device.

The second LeakSanitizer error is caused by the same issue as the first one, butin the ‘eCDATA_SECTION_NODE’ case at line 71 of Appendix B.3. There isagain an error in xmlNode_appendChild() resulting in Parser_parseDocument()to go to its ErrorHandler, which does not contain a free() statement for cdataSecNode.

Listing 4.9: XML file that causes first LeakSanitizer error1 <!DOCTYPE00000<000000>000<000000>0000>23 <doc a0="&quot ;& l t ;&amp;& gt ;&apos ;"></doc>M

Listing 4.10: XML file that causes second LeakSanitizer error1 <!DOCTYPE000A0<000000>000<0000:a0>0000>23 <doc a0="&quot ;& l t ;&amp;& gt ;&apos ;"></doc ><![CDATA[

4.3 Conclusion

AddressSanitizer should be utilized to increase the chance of finding memory bugs.However, it is not recommended to use this while AFL is fuzzing because of theamount of memory it uses. Looking for software faults proved to be more successfulin the XML parser than in the SSDP parser. Nonetheless, more research should bedone to know if the LeakSanitizer error could lead to actual problems.

27

Page 39: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 40: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 5

Comparing fuzzers AFL and

AFLFast

Besides searching for bugs in the libUPnP library, it is also interesting to comparedi�erent fuzzers in order to achieve a better understanding of which one is mostfit for fuzzing libUPnP and other stateless network protocol implementations. Thecomparison is made between two fuzzers: AFL and AFLFast. This choice was madebased on the paper “Fuzzing: Art, Science, and Engineering” [23].

5.1 XML fuzzing

AFLFast is a project forked from AFL [3]. They di�er in the way they generate newinput files and how they schedule these, explained in Section 2.2.2. To understandthe e�ect of these changes the “exploration vs. exploitation conflict” [23] should beunderstood first. The conflict is defined as “time can either be spent on gatheringmore accurate information on each configuration to inform future decisions (explore),or on fuzzing the configurations that are currently believed to lead to more favorableoutcomes (exploit)” [23]. Configurations are the input files in combination withmetadata like the coverage the input achieved. The changes made by AFLFastmake sure more time is invested in exploration than with AFL. More specificallythe exploration of configurations that get fuzzed less. According to the authorsof AFLFast it finds bugs quicker: “In 24 hours, AFLFast exposes 3 previouslyunreported CVEs that are not exposed by AFL and exposes 6 previously unreportedCVEs 7x faster than AFL. AFLFast produces at least an order of magnitude moreunique crashes than AFL” [4]. However, this comparison was done with AFL version1.96b (now AFL is at version 2.52b). Since then the authors of AFLFast have saidthat AFL 2.33b invests more in exploration which resulted in a performance boost [3].At the moment AFLFast is synced with AFL 2.51b while AFL is at version 2.52b. Itwill be interesting to see what the di�erence between these two fuzzers is now. Inorder to acquire the comparison data the fuzzers were run with one fuzz instancewithout defining a fuzzing strategy. The reason not to use the parallel strategy isbecause AFLFast is unreliable in this mode as the “path probability estimates are

29

Page 41: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5. Comparing fuzzers AFL and AFLFast

incorrect for the imported seeds” [3]. The comparison of these fuzzers is made bythe code coverage they accomplish and the time it takes them to complete one cycle.A cycle, also called a queue pass, is achieved when “the fuzzer went over all theinteresting test cases discovered so far.” [48]. Mostly the chance of finding anythingnew goes down after the first cycle, accoring to AFL author Michal Zalewski [2].When fuzzing the XML library like in Section 4, it takes them both on average 23minutes to complete one cycle (see Appendix A.3 and A.4).

To reveal the code coverage of AFL or AFLFast input files, the tool afl-cov wasdeveloped by Michael Rash [33]. This tool takes the harness program and the outputdirectory of a fuzz run and outputs gcov [13] results of each input file. First a directoryneeds to be created which we will call ’cov’. This directory contains the library’ssource code libupnp-1.8.4, the harnessxml.c file and a linking file. The libupnp-1.8.4library needs to be compiled with gcc (which is the default for this library) and withflags ‘-fprofile-arcs’ and ‘-ftest-coverage’. When in the ‘cov/libupnp-1.8.4’ directoryuse the command ‘CFLAGS+=�-fprofile-arcs -ftest-coverage� ./configure --disable-shared && make’ to configure and make the (static) library. The harnessxml.c file isthe same as in Listing 4.1. The linking file is similar to Listing 4.4 but with gcc andthe ’-fprofile-arcs’ and ’-ftest-coverage’ flags. The linking file results in Listing 5.1.

Listing 5.1: Linking command for XML harness for afl-cov1 gcc ≠DHAVE_CONFIG_H ≠ f p r o f i l e ≠a r c s ≠ f t e s t ≠coverage2 ≠L ~/path/ to / l i b i x m l . a ≠I ~/cov/ libupnp ≠1.8.4/ upnp/ inc3 ≠I ~/cov/ libupnp ≠1.8.4/ ixml / inc harnessxml . c ≠o harnessxmlcov4 ≠g ≠Os ≠Wall ≠l i xm l

Running this linking command creates two files: ‘harnessxml.gcno’ and theexecutable binary ‘harnessxmlcov’. To be able to use gcov and consequently afl-covthe file ‘harnessxml.gcda’ is also needed. To create this file you just need to call‘./harnessxmlcov’ once (does not matter if this is with or without arguments). Noweverything is ready to use afl-cov.

The command used in the ‘cov’ directory to get the coverage results (includingbranch coverage data) is ‘/path/to/afl-cov-master/afl-cov -d /path/to/output/di-rectory --coverage-cmd ��./harnessxmlcov AFL_FILE�� --code-dir . --enable-branch-coverage’. The results of this command can be found in a directory within the outputdirectory and are presented in multiple ways. The first file lists which new linesgot covered for each input file. The second is a zero coverage report which lists thefunctions that did not get covered by any of the input files. The third is a positivecoverage report which lists all the functions that were executed by at least one inputfile, so essentially the complement of the zero coverage report. The most interestingway is the summarized results in a final web report, see Figures 5.1 to 5.5. Figure 5.1shows the coverage report for the original input files. Afl-cov created this reportusing lcov [29]. The fuzz run web reports with the best results (highest statementand branch coverage) for AFL and AFLFast can be found in Figure 5.2 and 5.3respectively. The average statement coverage for AFL is 1092 lines, for AFLFastthis is 1096 lines. The average branch coverage is 658 and 662 branches respectively.

30

Page 42: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5.1. XML fuzzing

Figure 5.1: Coverage report - original input files

Figure 5.2: Best coverage AFL

Figure 5.3: Best coverage AFLFast

Out of the coverage web reports mentioned above and the data about the averagecoverage we can conclude that AFLFast reaches higher coverage, but not with a lotof di�erence. A big disadvantage of AFLFast is that it cannot be used in parallel.When we do try and do this, the time it takes for one cycle is not consistent at all,ranging from 12 minutes to more than 11 hours. The coverage results from a runthat took eight hours can be viewed in Figure 5.5. The coverage results are slightlybetter than in the other runs, but it takes way longer to complete a cycle. Whenusing AFL in parallel (with one master instance and one secondary instance) thetime for one cycle to complete (in the master instance) and coverage results areessentially the same as with a single instance of AFLFast, see Figure 5.4. Using threesecondary fuzz instances in addition to one master fuzz instance took 28 minutes thefirst time running resulting in a statement coverage of 1105 lines and 670 branches,which is better coverage than using AFLFast in single mode. The second time ittook 43 minutes hitting 1106 lines and 671 branches. Although it takes longer tocomplete a cycle and takes up more resources, the coverage is higher.

The AFL (and AFLFast) project has the ability to visualize the fuzz run ingraphs. To generate these graphs, go to the output directory and call ‘afl-plot . plot’.This creates another directory in the current one called ‘plot’. In this directory there

31

Page 43: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5. Comparing fuzzers AFL and AFLFast

Figure 5.4: Coverage AFL in parallel - 20 minutes

Figure 5.5: Coverage AFLFast in parallel - 8 hours

are 4 files. One .png file for each graph and one .html file which you can open inyour browser of choice to view all the graphs [39]. For the best AFL fuzz run, thisresults in the Figures 5.6 to 5.8. For the best AFLFast fuzz run this results in theFigures 5.9 to 5.11.

In the path coverage graph the total paths are all the input files in the queue;the current path is which input in the queue it was fuzzing at that moment; thepending paths are the input files that have not been fuzzed yet; the pending favsare the input files the fuzzer wants to fuzz in this cycle [48]. In the second graphunique crashes and hangs speak for themselves; the levels indicate which iteration ofthe test cases the fuzzer is at [48]. The seeds given by the user are level 1, queueelement derived from the original seeds are level 2, queue elements derived from level2 elements are level 3, and so on [48]. In the last graph execution speed is shown.This stays pretty constant for both fuzzers.

The trend in all three graphs are similar for AFL and AFLFast. Except for thecoverage and number of levels being slightly more for AFLFast and the executionsper second being slightly more for AFL. When looking at the executions per secondfor all runs the average for AFL is also highest (2277 compared to 2127).

Even though AFLFast has a slightly higher coverage, we cannot conclude it findsbugs faster, as no bugs were found using AFL or AFLFast. To check this we shouldrun AFLFast on the SSDP parser of libUPnP 1.3.1 to see how fast it finds the knownvulnerabilities.

32

Page 44: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5.1. XML fuzzing

Figure 5.6: AFL - path coverage

Figure 5.7: AFL - crash and hang results

Figure 5.8: AFL - execution speed

Figure 5.9: AFLFast - path coverage

33

Page 45: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5. Comparing fuzzers AFL and AFLFast

Figure 5.10: AFLFast - crash and hang results

Figure 5.11: AFLFast - execution speed

5.2 SSDP fuzzing

The bugs in the SSDP parser of libUPnP 1.3.1 and how to fuzz the parser arediscussed in Section 3.2. For this comparison a file with one less byte than whatcauses the overflow is used as seed. Like in the previous section, only one fuzzinstance is used for the comparison of the fuzzers. AFL and AFLFast both find thefirst crash after about 1 hour and 40 minutes. They were both run three times untila full cycle was reached. It took AFL between 12 and 13 hours to finish. AFLFastfinished after almost 18 hours in all runs. The coverage and number of uniquecrashes can be viewed in Appendix A.5. Comparing the unique crashes, AFL findsmore than AFLFast. It takes just as long for them to find first crash. It takes longbefore a crash is found, because libUPnP-1.3.1 executes way slower than the newerversions. AFL and AFLFast can only do 5 executions per second (normally this isaround 2000). In “Tips for performance optimization” [47] in the AFL project it isrecommended to add the ‘-d’ option if the executable is slow. This option skips thedeterministic steps in fuzzing. Applying this strategy to AFL and AFLFast makessure the error is found way faster. Each fuzzer was run 10 times with this option.AFL found the first crash between 34 seconds and 1 minute 14 seconds, with anaverage of 48 seconds. For AFLFast this was between 56 seconds and 1 minute 48seconds, with an average of 1 minute 9 seconds. Out of this data we can concludethat AFL is faster for finding this bug. This is also why in Section 3.2.2 the crash isfound at around a minute, because the secondary fuzzer also skips the deterministicsteps.

34

Page 46: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

5.3. Conclusion

5.3 Conclusion

Between AFL and AFLFast there is only a slight di�erence in coverage. The biggestdisadvantage of AFLFast is that it cannot be used in parallel mode. Using AFL inparallel takes just as long to complete a cycle, and the coverage is almost the sameas AFLFast in single mode. AFL in parallel with 4 fuzz instances takes longer, butdoes get more coverage than any other fuzz strategy used in this chapter. AFL findsbugs faster but should be compared on a di�erent kind of bug to generalize this.The reason why these conclusions and the claims of the authors of AFLFast are sodi�erent is probably because those claims were done 2 years ago and AFL has beenmaintained way better than AFLFast since then. AFL is thus the preferred fuzzer atthe moment.

35

Page 47: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 48: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Chapter 6

Conclusion and Future Work

6.1 Conclusion

Users mostly trust the software they are using blindly. The problem with this is thatthey could be exposed to risks they are not aware of. These risks are a consequenceof vulnerabilities in software and opportunities to exploit them. UPnP and itsimplementations have been proven to be susceptible to this. It is widely used andoften turned on by default (e.g. routers) so users often do not know they are usingit, implementations su�er from various flaws and vulnerabilities are getting activelyexploited. Thus the goal of developers and testers, next to providing functionality, isto minimize vulnerable code. One method for finding vulnerabilities that has provenits e�ectiveness with other software is fuzzing.

One part of the UPnP protocol that has a history of vulnerabilities is the SSDPparser. These vulnerabilities were found in both MiniUPnP and libUPnP, the twomost popular UPnP SDK’s. Trying to find new vulnerabilities in the patched versionsof this parser starts with choosing the right fuzzing strategy. To get feedback onthe chosen strategy it is recommended to first use it on an old version containingknown vulnerabilities and try and find those. Fuzzing the SSDP parser in the newestversion of libUPnP did not result in any new vulnerabilities being found. The codeof the SSDP parser is probably the most robust now as a result of the attentionit got when loads of vulnerabilities were found in it. A di�erent parser that hasnot gotten a lot of attention is libUPnP’s UPnP specific XML parser. Fuzzingthis initially also led to no results. The used fuzzer, AFL, produces a queue ofelements that each represent a di�erent path in the code that it found. RunningAddressSanitizer, which looks for memory bugs, on all files in this queue resultedin finding three memory bugs: one illegal memory read and two memory leaks.Further analyzes of the first bug pointed out that the illegal memory read does notget leaked further than in the function it occurs. The two memory leak bugs arerelated. A piece of memory gets allocated but never gets freed if a certain error occurs.With this bug you could potentially fill up the memory, but this needs further research.

37

Page 49: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

6. Conclusion and Future Work

Besides directly looking for vulnerabilities, it is also useful to compare twofuzzers on the previously mentioned parsers to find which one is best to look forvulnerabilities in the future. The two compared fuzzers are AFL and AFLFast.AFLFast is forked from AFL and two years ago the creators of AFLFast published apaper claiming AFLFast to be more e�cient. The only (planned) changes made inAFL to create AFLFast is how input gets scheduled to be fuzzed. However, due to awrong implementation not solved to this date AFLFast cannot take advantage of theparallel mode AFL has. The outcome of this comparison is that that AFLFast has aslightly better coverage than AFL, but when the parallel mode is used in AFL thecoverage is similar. Additionally, AFL finds the known SSDP vulnerabilities quickerdoes. AFLFast does not seem very relevant anymore. This is likely because it is notmaintained anymore, the last update being more than a year ago.

6.2 Future Work

There is a lot of potential for future work. First and for all it should be checked ifthe memory leak discovered in the XML parser can be exploited. This is, does aUPnP device’s memory fill up if it has to parse XML files causing the memory leak,resulting in a crash? Aside from that, other functionality of the libUPnP librarycould be fuzzed, for example SOAP or Eventing. Other things that could be fuzzedis the MiniUPnP library or implementations of other stateless network protocols.

38

Page 50: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Appendices

39

Page 51: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 52: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Appendix A

Results

Appendices hold useful data which is not essential to understand the work done inthe master’s thesis. An example is a (program) source. An appendix can also havesections as well as figures and references.

Prepend Append Statement cov Function cov Branch cov

265 lines 33 functions 120 branches::upnp:rootdevice 257 lines 33 functions 112 branches

uuid ::end 257 lines 33 functions 111 branchesuuid:schemas:device: :end 257 lines 33 functions 111 branchesurn:schemas:device: 318 lines 42 functions 136 branchesurn:schemas:service: 257 lines 33 functions 111 branches

Table A.1: Coverage results for each path in unique_service_name()

41

Page 53: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

A. Results

File Name Original Size (bytes) Reduced Size (bytes) Reduction

040.xml 130 86 34%059.xml 237 226 5%111.xml 128 82 36%element.xml 706 615 13%empty_attribute.xml 144 135 6%p43pass1.xml 390 289 26%tvcontrolSCPD.xml 3707 3613 3%tvdevicedesc.xml 1526 1443 5%tvpictureSCPD.xml 5706 5604 2%zh-utf8-1.xml 572 409 28%zh-utf8-2.xml 807 652 19%zh-utf8-3.xml 811 656 19%zh-utf8-5.xml 815 655 20%zh-utf8-6.xml 810 651 20%zh-utf8-8.xml 651 496 24%zh-utf8-9.xml 535 380 29%zh-utf8-10.xml 548 384 30%zh-utf8-11.xml 582 426 27%zh-utf8-12.xml 783 604 23%

Table A.2: Reduction values of XML test data files under afl-tmin

Run time (1 cycle) Statement cov Function cov Branch cov

1 20m 1092 lines 92 functions 658 branches2 29m 1097 lines 92 functions 661 branches3 17m 1092 lines 92 functions 655 branches4 23m 1085 lines 92 functions 653 branches5 24m 1096 lines 92 functions 661 branches6 21m 1092 lines 92 functions 657 branches7 23m 1093 lines 92 functions 656 branches8 28m 1086 lines 92 functions 655 branches9 22m 1096 lines 92 functions 661 branches10 20m 1092 lines 92 functions 658 branches

Table A.3: AFL fuzzing XML parser summary

42

Page 54: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Run time (1 cycle) Statement cov Function cov Branch cov

1 21m 1100 lines 92 functions 661 branches2 19m 1092 lines 92 functions 657 branches3 29m 1101 lines 92 functions 666 branches4 20m 1101 lines 92 functions 666 branches5 22m 1100 lines 92 functions 664 branches6 26m 1097 lines 92 functions 665 branches7 29m 1100 lines 92 functions 665 branches8 19m 1092 lines 92 functions 658 branches9 21m 1092 lines 92 functions 657 branches10 28m 1093 lines 92 functions 657 branches

Table A.4: AFLFast fuzzing XML parser summary

Run time

(1 cycle)

time until

first crash

Statement

cov

Function

cov

Branch

cov

unique

crashes

seed n/a n/a 207 lines 22 functions 71 branches n/a1 12h40m 5m 362 lines 37 functions 155 branches 102 11h30 1h27m 362 lines 37 functions 154 branches 63 12h7m 1h26m 363 lines 37 functions 156 branches 7

Table A.5: AFL fuzzing SSDP parser summary

Run time (1 cycle) Statement cov Function cov Branch cov unique crashes

1 18h 362 lines 37 functions 152 branches 72 17h45m 362 lines 37 functions 158 branches 53 17h55m 362 lines 37 functions 157 branches 7

Table A.6: AFLFast fuzzing SSDP parser summary

43

Page 55: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 56: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Appendix B

libUPnP XML Code

Listing B.1: Parser_getChar in ixmlparser.c1 s t a t i c i n t Parser_getChar (2 /� ! [ in ] . �/3 const char � src ,4 /� ! [ in , out ] . �/5 p t r d i f f _ t �cLen )6 {7 i n t r e t = ≠1;8 i n t l i n e = 0 ;9 const char �pnum ;

10 i n t sum ;11 char c ;12 i n t i ;1314 i f ( s r c == NULL | | cLen == NULL ) {15 l i n e = __LINE__;16 r e t = ≠1;17 goto ExitFunction ;18 }1920 �cLen = 0 ;21 i f (� s r c != ’& ’) {

. . . . . .38 } e l s e i f ( strncasecmp ( src , QUOT, s t r l e n (QUOT) ) == 0) {

. . . . . .42 } e l s e i f ( strncasecmp ( src , LT, s t r l e n (LT) ) == 0) {

. . . . . .46 }

. . . . . .58 e l s e i f ( strncasecmp ( src , ESC_HEX, s t r l e n (ESC_HEX) ) == 0) {59 /� Read in escape c h a r a c t e r s o f type &#xnn where nn

45

Page 57: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

B. libUPnP XML Code

60 i s a hexadecimal va lue �/61 pnum = s r c + s t r l e n ( ESC_HEX ) ;62 sum = 0 ;63 whi l e ( s t r c h r (HEX_NUMBERS, ( i n t )�pnum) != 0) {64 c = �pnum ;65 i f ( c <= ’9 ’ ) {66 sum = sum � 16 + ( c ≠ ’ 0 ’ ) ;67 } e l s e i f ( c <= ’F’ ) {68 sum = sum � 16 + ( c ≠ ’A’ + 10 ) ;69 } e l s e {70 sum = sum � 16 + ( c ≠ ’ a ’ + 10 ) ;71 }72 pnum++;73 }74 i f (pnum == s r c | | �pnum != ’ ; ’ | |75 ! Parser_isXmlChar (sum ) ) {76 l i n e = __LINE__;77 goto f a i l _ e n t i t y ;78 }79 �cLen = pnum ≠ s r c + 1 ;80 r e t = sum ;81 goto ExitFunction ;82 }

. . . . . .103 f a i l _ e n t i t y :104 i f ( g_error_char ) {105 �cLen = 1 ;106 r e t = ’& ’ ;107 goto ExitFunction ;108 }. . . . . .119 }

Listing B.2: ixmlDocument_createTextNodeEx in document.c1 i n t ixmlDocument_createTextNodeEx (2 IXML_Document �doc ,3 const DOMString data ,4 IXML_Node �� textNode )5 {6 IXML_Node � returnNode ;7 i n t rc = IXML_SUCCESS;89 returnNode = NULL;

. . . . . .

46

Page 58: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

15 returnNode = (IXML_Node �) mal loc ( s i z e o f (IXML_Node ) ) ;16 i f ( returnNode == NULL) {17 rc = IXML_INSUFFICIENT_MEMORY;18 goto ErrorHandler ;19 }20 /� i n i t i a l i z e the node �/21 ixmlNode_init ( returnNode ) ;2223 returnNode≠>nodeName = strdup ( ( const char �)TEXTNODENAME) ;24 i f ( returnNode≠>nodeName == NULL) {25 ixmlNode_free ( returnNode ) ;26 returnNode = NULL;27 rc = IXML_INSUFFICIENT_MEMORY;28 goto ErrorHandler ;29 }30 /� add in node value �/31 i f ( data != NULL) {32 returnNode≠>nodeValue = strdup ( data ) ;33 i f ( returnNode≠>nodeValue == NULL) {34 ixmlNode_free ( returnNode ) ;35 returnNode = NULL;36 rc = IXML_INSUFFICIENT_MEMORY;37 goto ErrorHandler ;38 }39 }4041 returnNode≠>nodeType = eTEXT_NODE;42 returnNode≠>ownerDocument = doc ;4344 ErrorHandler :45 � textNode = returnNode ;46 re turn rc ;47 }

Listing B.3: Parser_parseDocument in ixmlparser.c1 s t a t i c i n t Parser_parseDocument (2 /� ! [ out ] The XML document . �/3 IXML_Document �� retDoc ,4 /� ! [ in ] The XML par s e r . �/5 Parser � xmlParser )6 {7 IXML_Document �gRootDoc = NULL;8 IXML_Node newNode ;9 BOOL bETag = FALSE;

47

Page 59: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

B. libUPnP XML Code

10 IXML_Node �tempNode = NULL;11 i n t rc = IXML_SUCCESS;12 IXML_CDATASection � cdataSecNode = NULL;1314 /� I t i s important that the node ge t s i n i t i a l i z e d here ,15 � otherwi se th ing s can go wrong on the e r r o r handler . �/16 ixmlNode_init ( &newNode ) ;

. . . . . .30 whi l e ( bETag == FALSE ) {31 /� c l e a r the newNode contents . Redundant on the f i r s t32 � i t e r a t i o n , but nonethe l e s s , nece s sa ry due to the33 � p o s s i b l e c a l l s to ErrorHandler above . Currently ,34 � t h i s i s j u s t a memset to zero . �/35 ixmlNode_init ( &newNode ) ;3637 i f ( Parser_getNextNode ( xmlParser , &newNode , &bETag )38 == IXML_SUCCESS ) {39 i f ( bETag == FALSE ) {40 switch ( newNode . nodeType ) {

. . . . . .51 case eTEXT_NODE:52 rc = ixmlDocument_createTextNodeEx (53 gRootDoc ,54 newNode .55 nodeValue ,56 &tempNode ) ;57 i f ( rc != IXML_SUCCESS ) {58 goto ErrorHandler ;59 }6061 rc = ixmlNode_appendChild (62 xmlParser≠>63 currentNodePtr ,64 tempNode ) ;65 i f ( rc != IXML_SUCCESS ) {66 goto ErrorHandler ;67 }6869 break ;7071 case eCDATA_SECTION_NODE:72 rc =73 ixmlDocument_createCDATASectionEx (74 gRootDoc ,75 newNode .

48

Page 60: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

76 nodeValue ,77 &cdataSecNode ) ;78 i f ( rc != IXML_SUCCESS ) {79 goto ErrorHandler ;80 }8182 rc = ixmlNode_appendChild (83 xmlParser≠>84 currentNodePtr ,85 &( cdataSecNode≠>n ) ) ;86 i f ( rc != IXML_SUCCESS ) {87 goto ErrorHandler ;88 }89 break ;

. . . . . .138 ErrorHandler :139 Parser_freeNodeContent ( &newNode ) ;140 ixmlDocument_free ( gRootDoc ) ;141 Parser_free ( xmlParser ) ;142 re turn rc ;143 }

Listing B.4: ixmlDocument_createCDATASectionEx in document.c1 i n t ixmlDocument_createCDATASectionEx (2 IXML_Document �doc ,3 const DOMString data ,4 IXML_CDATASection ��rtCD)5 {6 i n t errCode = IXML_SUCCESS;7 IXML_CDATASection � cDSectionNode = NULL;89 i f ( doc == NULL | | data == NULL) {

10 errCode = IXML_INVALID_PARAMETER;11 goto ErrorHandler ;12 }1314 cDSectionNode = (IXML_CDATASection �) mal loc15 ( s i z e o f (IXML_CDATASection ) ) ;16 i f ( cDSectionNode == NULL) {17 errCode = IXML_INSUFFICIENT_MEMORY;18 goto ErrorHandler ;19 }2021 ixmlCDATASection_init ( cDSectionNode ) ;

49

Page 61: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

B. libUPnP XML Code

22 cDSectionNode≠>n . nodeType = eCDATA_SECTION_NODE;23 cDSectionNode≠>n . nodeName =24 strdup ( ( const char �)CDATANODENAME) ;25 i f ( cDSectionNode≠>n . nodeName == NULL) {26 ixmlCDATASection_free ( cDSectionNode ) ;27 cDSectionNode = NULL;28 errCode = IXML_INSUFFICIENT_MEMORY;29 goto ErrorHandler ;30 }3132 cDSectionNode≠>n . nodeValue = strdup ( data ) ;33 i f ( cDSectionNode≠>n . nodeValue == NULL) {34 ixmlCDATASection_free ( cDSectionNode ) ;35 cDSectionNode = NULL;36 errCode = IXML_INSUFFICIENT_MEMORY;37 goto ErrorHandler ;38 }3940 cDSectionNode≠>n . ownerDocument = doc ;4142 ErrorHandler :43 �rtCD = cDSectionNode ;44 re turn errCode ;45 }

50

Page 62: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Appendix C

AddressSanitizer Errors

Listing C.1: AddressSanitizer error1 Test "/ path/ to /out/ fu z z e r 2 /queue/ id :000478 , s r c :000144+2 000469 , op : s p l i c e , rep : 2 "3 Loading . . . ASAN:DEADLYSIGNAL4 ============================================================5 =======29057==ERROR: Addre s sSan i t i z e r : SEGV on unknown6 address 0 x614000010000 ( pc 0 x000000517423 bp 0 x 6 1 4 0 0 0 0 0 f f f f7 sp 0 x 7 f f f 7 e c 5 f 3 c 0 T0)8 ==29057==The s i g n a l i s caused by a READ memory ac c e s s .9 #0 0x517422 in Parser_getChar

10 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c : 7 9 5 : 811 #1 0x517422 in Parser_copyToken12 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c :97513 #2 0x5146dd in Parser_processContent14 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c : 1 3 4 0 : 715 #3 0x5146dd in Parser_getNextNode16 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c :185817 #4 0x5146dd in Parser_parseDocument18 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c :237719 #5 0x5146dd in Parser_LoadDocument20 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c :262021 #6 0 x51037f in ixmlLoadDocumentEx22 / libupnp ≠1.8.4/ ixml / s r c / ixml . c : 3 3 3 : 923 #7 0 x50bc1e in main /xml/ harnessxml . c : 9 8 : 824 #8 0 x7fae68 f0cb96 in __libc_start_main25 / bu i ld / g l i b c ≠OTsEL5/ g l i b c ≠2.27/ csu / . . / csu / l i b c ≠s t a r t . c : 326 1027 #9 0 x41c569 in _start28 (/ xml/ harnessxmlasan+0x41c569 )2930 Addre s sSan i t i z e r can not prov ide a d d i t i o n a l i n f o .

51

Page 63: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

C. AddressSanitizer Errors

31 SUMMARY: Addre s sSan i t i z e r : SEGV32 / libupnp ≠1.8.4/ ixml / s r c / ixmlpar se r . c : 7 9 5 : 8 in Parser_getChar33 ==29057==ABORTING

Listing C.2: First LeakSanitizer error1 Test "/ path/ to /queue/ id :000162 , s r c :000000+000006 , op : s p l i c e ,2 rep :8 ,+ cov . 3 "3 Loading . . . �� e r r o r : can ’ t load document4 /path/ to /queue/ id :000162 , s r c :000000+000006 , op : s p l i c e ,5 rep :8 ,+ cov . 3 : e r r o r 36 (HIERARCHY_REQUEST_ERR)78 ===========================================================9 ========27894==ERROR: LeakSan i t i z e r : de tec ted memory l e a k s

1011 Direc t l eak o f 104 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :12 #0 0x7fd1db07db60 in __interceptor_malloc13 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 xedb60 )14 #1 0 x55ba54ea5859 in ixmlDocument_createTextNodeEx15 s r c /document . c :2351617 I n d i r e c t l eak o f 21 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :18 #0 0 x7fd1dafcaca0 in strdup19 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 x3aca0 )20 #1 0 x55ba54ea58f f in ixmlDocument_createTextNodeEx21 s r c /document . c :2522223 I n d i r e c t l eak o f 6 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :24 #0 0 x7fd1dafcaca0 in strdup25 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 x3aca0 )26 #1 0x55ba54ea58b3 in ixmlDocument_createTextNodeEx27 s r c /document . c :2432829 SUMMARY: Addre s sSan i t i z e r : 131 byte ( s ) l eaked in 330 a l l o c a t i o n ( s ) .

Listing C.3: Second LeakSanitizer error1 Test "/ path/ to /queue/ id :000456 , s r c :000196 ,2 op : havoc , rep :4 ,+ cov . 3 "3 Loading . . . �� e r r o r : can ’ t load document /path/ to /queue4 / id :000456 , s r c :000196 , op : havoc , rep :4 ,+ cov . 3 : e r r o r 35 (HIERARCHY_REQUEST_ERR)67 ============================================================

52

Page 64: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

8 ==27908==ERROR: LeakSan i t i z e r : de tec ted memory l e a k s9

10 Di rec t l eak o f 104 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :11 #0 0x7f620b5dbb60 in __interceptor_malloc12 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 xedb60 )13 #1 0 x5606c96ba6a9 in ixmlDocument_createCDATASectionEx14 s r c /document . c :4051516 I n d i r e c t l eak o f 15 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :17 #0 0 x7f620b528ca0 in strdup18 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 x3aca0 )19 #1 0 x5606c96ba70a in ixmlDocument_createCDATASectionEx20 s r c /document . c :4132122 I n d i r e c t l eak o f 3 byte ( s ) in 1 ob j e c t ( s ) a l l o c a t e d from :23 #0 0 x7f620b528ca0 in strdup24 (/ usr / l i b /x86_64≠l inux ≠gnu/ l i b a s a n . so .5+0 x3aca0 )25 #1 0 x5606c96ba757 in ixmlDocument_createCDATASectionEx26 s r c /document . c :4212728 SUMMARY: Addre s sSan i t i z e r : 122 byte ( s ) l eaked in 329 a l l o c a t i o n ( s ) .

53

Page 65: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure
Page 66: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Bibliography

[1] H. Böck. Fuzzing with american fuzzy lop. URL: https://lwn.net/Articles/

657959/, last checked on 2019-08-05.

[2] H. Böck et al. Does it make sense to run afl very long?URL: https://groups.google.com/forum/#!msg/afl-users/4XGI5WccJUo/

ll9RH7AIz8UJ, last checked on 2019-07-10.

[3] M. Böhme. AFLFast (extends AFL with Power Schedules). URL: https:

//github.com/mboehme/aflfast, last checked on 2019-07-30.

[4] M. Böhme, V.-T. Pham, and A. Roychoudhury. Coverage-based GreyboxFuzzing as Markov Chain. In Proceedings of the ACM Conference on Computerand Communications Security, pages 1032–1043. ACM, 2016.

[5] ChunshengZhao. Build afl-fuzz(-Q mode) on Kali(2018.2). URL: https:

//github.com/ChunshengZhao/afl252b_qemu2100_kali20082-patches, lastchecked on 2019-05-31.

[6] L. Constantin. Broadcom UPnP Implementation Also Contains Critical Vul-nerability, Researchers Say. URL: https://www.cio.com/article/2388686/

security0/broadcom-upnp-implementation-also-contains-critical-

vulnerability--researchers-say.html,last checked on 2019-08-08.

[7] W. contributors. Fuzzing. URL: https://en.wikipedia.org/wiki/Fuzzing,last checked on 2019-08-08.

[8] CVE. URL: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=UPnP,last checked on 2019-08-08.

[9] CVE. URL: https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=ssdp+

upnp, last checked on 2019-08-13.

[10] CVE. Libupnp: Security Vulnerabilities. URL: https://www.cvedetails.com/

vulnerability-list/vendor_id-15599/product_id-32362/Libupnp-

Project-Libupnp.html, last checked on 2019-07-8.

[11] CVE. Portable Sdk for Upnp: Security Vulnerabilities. URL: https://

www.cvedetails.com/vulnerability-list/vendor_id-12590/product_id-

55

Page 67: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Bibliography

24262/Portable-Sdk-For-Upnp-Project-Portable-Sdk-For-Upnp.html,last checked on 2019-07-8.

[12] T. Fout. Universal Plug and Play in Windows XP, Introduc-tion. URL: https://docs.microsoft.com/en-us/previous-versions/

windows/it-pro/windows-xp/bb457049(v=technet.10)#EGAA, last checkedon 2019-05-21.

[13] GNU development. gcov - coverrchge testing tool. URL: https://

linux.die.net/man/1/gcov, last checked on 2019-08-03.

[14] A. Hemel. UPnP Hacks: UPnP Background. URL: http://www.upnp-

hacks.org/upnp.html, last checked on 2019-05-21.

[15] C. Ho�man. Is upnp a security risk? URL: https://www.howtogeek.com/

122487/htg-explains-is-upnp-a-security-risk/, last checked on 2019-08-08.

[16] S. Hunter et al. What if NULL is passed in strchr(). URL:https://stackoverflow.com/questions/8972247/what-if-null-is-

passed-in-strchr, last checked on 2019-08-07.

[17] M. R. Jimenez and N. K. Papadopoulos. Portable UPnP SDK download. URL:https://sourceforge.net/projects/pupnp/files/, last checked on 2019-05-22.

[18] D. Jovanoski. XML vulnerabilities. URL: https://

resources.infosecinstitute.com/xml-vulnerabilities/#gref, lastchecked on 2019-07-8.

[19] L. Juranic. From Zero to ZeroDay Journey: Router Hacking, Vul-nerability background. URL: http://defensecode.com/whitepapers/

From_Zero_To_ZeroDay_Network_Devices_Exploitation.txt, last checkedon 2019-05-21.

[20] LLVM. libFuzzer - a library for coverage-guided fuzz testing. URL: http:

//llvm.org/docs/LibFuzzer.html, last checked on 2019-05-20.

[21] D. Lukan. MiniUPnPd analysis and exploitation. URL: https://www.viris.si/

2013/12/miniupnpd-analysis-and-exploitation/?lang=en, last checked on2019-05-30.

[22] M. Macnair. afl-training, Exercises to learn how to fuzz with American FuzzyLop. URL: https://github.com/mykter/afl-training, last checked on 2019-05-23.

[23] V. J. Manès et al. Fuzzing: Art, Science, and Engineering, Feb. 2019.arXiv:1812.00140.

56

Page 68: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Bibliography

[24] A. May. What is the use of the UPnP feature in the home router?URL: https://www.quora.com/What-is-the-use-of-the-UPnP-feature-in-

the-home-router, last checked on 2019-08-08.

[25] MiniUPnP Project. MiniUPnP download zone. URL: http://

miniupnp.free.fr/files/, last checked on 2019-05-30.

[26] H. Moore. Security Flaws in Universal Plug and Play: Unplug. Don’t Play.Technical report, Rapid 7, 2013.

[27] G. J. Myers. The Art of Software Testing, Second Edition. John Wiley & Sons,Inc., 2004. ISBN 0-471-46912-2.

[28] J. Niccolai. Microsoft fires back at Sun’s Jini. URL: https:

//www.javaworld.com/article/2076318/microsoft-fires-back-at-sun-s-

jini.html, last checked on 2019-05-21.

[29] P. Oberparleiter. lcov - a graphical GCOV front-end. URL: https://

linux.die.net/man/1/lcov, last checked on 2019-08-03.

[30] B. Perry. Fuzzing workflows; a fuzz job from start to finish.URL: https://foxglovesecurity.com/2016/03/15/fuzzing-workflows-a-

fuzz-job-from-start-to-finish/, last checked on 2019-07-28.

[31] A. Presser et al. UPnPTM Device Architecture 1.1.

[32] QEMU. What is QEMU? URL: https://www.qemu.org, last checked on 2019-05-29.

[33] M. Rash. Produce code coverage results with gcov from afl-fuzz test cases. URL:https://github.com/mrash/afl-cov, last checked on 2019-08-02.

[34] The Clang Team. Clang 10 documentation: ADDRESSSANITIZER. URL:http://clang.llvm.org/docs/AddressSanitizer.html, last checked on 2019-07-26.

[35] The Clang Team. Clang 10 documentation: MEMORYSANITIZER. URL:http://clang.llvm.org/docs/MemorySanitizer.html, last checked on 2019-07-26.

[36] The Clang Team. Clang 10 documentation: UNDEFINED-BEHAVIORSANITIZER. URL: http://clang.llvm.org/docs/

UndefinedBehaviorSanitizer.html, last checked on 2019-07-26.

[37] H. Wang. BCMPUPnP_Hunter: A 100k Botnet Turns Home Routers to EmailSpammers. URL: https://blog.netlab.360.com/bcmpupnp_hunter-a-100k-

botnet-turns-home-routers-to-email-spammers-en/, last checked on 2019-05-23.

57

Page 69: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

Bibliography

[38] M. Zalewski. afl/docs. URL: https://github.com/mirrorer/afl/tree/

master/docs, last checked on 2019-08-12.

[39] M. Zalewski. american fuzzy lop. URL: http://lcamtuf.coredump.cx/afl/

README.txt, last checked on 2019-07-9.

[40] M. Zalewski. american fuzzy lop - corpus minimization tool. URL: https:

//github.com/mirrorer/afl/blob/master/afl-cmin, last checked on 2019-07-9.

[41] M. Zalewski. american fuzzy lop - test case minimizer. URL: https:

//github.com/mirrorer/afl/blob/master/afl-tmin.c, last checked on 2019-07-9.

[42] M. Zalewski. american fuzzy lop (2.52b). URL: http://lcamtuf.coredump.cx/

afl/, last checked on 2019-05-23.

[43] M. Zalewski. Fast LLVM-based instrumentation for afl-fuzz. URL:https://github.com/mirrorer/afl/blob/master/llvm_mode/README.llvm,last checked on 2019-07-26.

[44] M. Zalewski. High-performance binary-only instrumentation for afl-fuzz. URL: https://github.com/mirrorer/afl/blob/master/qemu_mode/

README.qemu, last checked on 2019-05-29.

[45] M. Zalewski. Notes for using ASAN with afl-fuzz. URL: https://github.com/

mirrorer/afl/blob/master/docs/notes_for_asan.txt, last checked on 2019-07-10.

[46] M. Zalewski. Tips for parallel fuzzing. URL: https://github.com/stribika/

afl-fuzz/blob/master/docs/parallel_fuzzing.txt, last checked on 2019-07-9.

[47] M. Zalewski. Tips for performance optimization. URL: https://github.com/

mirrorer/afl/blob/master/docs/perf_tips.txt, last checked on 2019-07-9.

[48] M. Zalewski. Understanding the status screen. URL: http://

lcamtuf.coredump.cx/afl/status_screen.txt, last checked on 2019-07-30.

[49] M. Zalewski et al. afl-users. URL: https://groups.google.com/forum/

#!forum/afl-users, last checked on 2019-08-12.

58

Page 70: Fuzzing Universal Plug and Play · Fuzzing Universal Plug and Play Eleanor Van Looy Thesis submitted for the degree of Master of Science in Engineering: Computer Science, option Secure

KU Leuven Faculty of Engineering 2018 – 2019

Master’s thesis filing card

Student: Eleanor Van Looy

Title: Fuzzing Universal Plug and Play

Dutch title: Fuzz testen van Universal Plug and Play

UDC : 621.3

Abstract:It is hard to write bug free software, certainly for a large project in C. Consequently,it is of paramount importance to test such software exhaustively. The objectiveof this thesis is to find a strategy to automate software vulnerability detection in(C) implementations of stateless network protocols. The approach used to reachthis objective starts by researching existing problems with Universal Plug and Play(UPnP) and then applies fuzz testing to UPnP implementations, thereby designing astrategy to rediscover old vulnerabilities. The fuzz testing is done with AmericanFuzzy Lop (AFL) which automates the generation of test files to feed into a program.The tested implementations are libraries, meaning the tester still has to write aprogram incorporating the library to be fuzzed. Subsequently the approach uses thisstrategy to try to discover new vulnerabilities. Finally comparing the fuzzer AFLto its forked version AFLFast for the previously defined strategies. Two years ago,AFLFast claimed to find bugs faster than AFL. Three main findings were concludedfrom the results. First, the fuzzing strategy that found old vulnerabilities in libUPnP’s(one of two major UPnP libraries) Simple Service Discovery Protocol (SSDP) parserdid not find any faults within the patched version. Secondly, fuzzing the XML parserin combination with AddressSanitizer was able to find an illegal memory read andtwo memory leaks. Lastly, AFL outperformed its forked version AFLFast. No newvulnerabilities were found in the patched SSDP parser, so this part can be consideredrather robust now as it had the most problems in the past. The fact that memorybugs were only found when AddressSanitizer was used in combination with AFL,substantiates the statement that AddressSanitizer improves the chances of findingmemory bugs. Moreover, it does not take long to run, so certainly recommended.The finding that AFL outperforms AFLFast in the experiments done in this thesis isprobably due to AFLFast not having been actively maintained for two years.

Thesis submitted for the degree of Master of Science in Engineering: ComputerScience, option Secure SoftwareThesis supervisors: Prof. dr. ir. F. Piessens

Prof. dr. ir. B. PreneelAssessors: Dr. R. Strackx

Dr. G. KarachaliasMentors: Ing. L. Wouters

Dr. J.T. Mühlberg