Fuzzing von Webapps

Lukas Gamper

Was ist Fuzzing

  • Bugs provozieren durch zufällige Eingaben
  • Überblick über Stabilität
  • Blackboxmethode
    => Kein Wissen über Target erforderlich

Pros

  • Wenig Aufwand
  • Lange Laufzeiten
  • Unkonventionelle Fehler
  • Überblick über Stabilität

Cons

  • Nur partielle Coverage
  • Debugging schwierig
  • Schlecht reproduzierbar

SinglePageFuzzer

github.com/usystems/singlepagefuzzer

  • Fuzzer für Web Applikationen
  • Simuliert User-Eingaben

Idee

  1. Wähle zufälliges Dom Element
  2. Simuliere Events
  3. Ist ein Event-Handler vorhanden?
    => warte bis Aktion beendet
  4. Weiter mit 1

Umsetzung

  1. Wähle zufälliges Dom Element
    • ​Wähle zufälligen Punkte auf Screen
    • überprüfe mit Element Filter
  2. Simuliere Events
    • Erstelle Javascript Event anhand der Event Verteilung
    • Dispatche Event auf ausgewähltem Element
  3. Ist ein Event-Handler vorhanden?
    • überwache Dom mit Mutation Observer
    • überwache Laufzeit mit Timeout
    • Erstelle Statistik über Laufzeit

Weitere Funktionen

Dom Element Filter

selectFilter: function(x, y, el) {
    return el.nodeName == 'DIV');
}

Zufälliger Wert in <Input>

allowedChars: ['a', 'b', 'c', ..., ' ', '\t', '\n'];

Timeout ersetzbar

timeout: angular.$timeout

Requests verwerfen / verlangsamen

request: {
    lag: 1000, // ms
    dropRequest: 0.1, // fraction
    dropResponse: 0.1, // fraction
    offline: 10000, // ms
    online: 5000 // ms
}

Browser Support

Edge

Chrome

Firefox

Safari

 

 

Unsere Erfahrungen

  • Viele Bugs gefixed
  • Auch von Kunden gemeldete Bugs
  • Simulation von schlechter Verbindung
  • Stabilität stark verbessert

Beispiel 1: TodoMVC

(function(el){
    el.src='//url/to/singlepagefuzzer.js';
    el.onload=function(){
        SinglePageFuzzer.start({

        });
    };
    document.head.appendChild(el);
})(document.createElement('script'));

skeleton

Beispiel 1: TodoMVC

element filter

Beispiel 1: TodoMVC

SinglePageFuzzer.start({
    selectFilter: function(x, y, el) {
        while (el !== null) {
            if (el.nodeName == 'SECTION') 
                return true;
            else 
                el = el.parentElement;
        }
        return false;
    }
});

element filter

Beispiel 1: TodoMVC

SinglePageFuzzer.start({
    eventDistribution: [
        SinglePageFuzzer.createEventProbability(0.5, [
            SinglePageFuzzer.createClick()
        ])
    ]
});

click event

Beispiel 1: TodoMVC

SinglePageFuzzer.start({
    eventDistribution: [
        SinglePageFuzzer.createEventProbability(0.1, [
            SinglePageFuzzer.createDblclick()
        ])
    ]
});

double click event

Beispiel 1: TodoMVC

SinglePageFuzzer.start({
    eventDistribution: [
        SinglePageFuzzer.createEventProbability(0.2, [
            SinglePageFuzzer.createInput(),
            SinglePageFuzzer.createSubmit()
        ])
    ]
});

Events

Beispiel 1: TodoMVC

SinglePageFuzzer.start({
    eventDistribution: [
        SinglePageFuzzer.createEventProbability(0.2, [
            SinglePageFuzzer.createKeydown
                (SinglePageFuzzer.ENTER),
            SinglePageFuzzer.createKeypress
                (SinglePageFuzzer.ENTER),
            SinglePageFuzzer.createKeyup
                (SinglePageFuzzer.ENTER),
        ])
    ]
});

Events

Beispiel 1: TodoMVC

(function(el){
    el.src='https://cdn.rawgit.com/usystems/singlepagefuzzer/' +
        'master/src/singlepagefuzzer.js';
    el.onload=function(){
        SinglePageFuzzer.start({
            selectFilter: function(x, y, el) {
                while (el !== null) {
                    if (el.nodeName == 'SECTION') return true;
                    else el = el.parentElement;
                }
                return false;
            },
            eventDistribution: [
                SinglePageFuzzer.createEventProbability(0.5, [SinglePageFuzzer.createClick()]),
                SinglePageFuzzer.createEventProbability(0.1, [SinglePageFuzzer.createDblclick()]),
                SinglePageFuzzer.createEventProbability(0.2, [
                    SinglePageFuzzer.createInput(),
                    SinglePageFuzzer.createSubmit()
                ]),
                SinglePageFuzzer.createEventProbability(0.2, [
                    SinglePageFuzzer.createKeydown(SinglePageFuzzer.ENTER),
                    SinglePageFuzzer.createKeypress(SinglePageFuzzer.ENTER),
                    SinglePageFuzzer.createKeyup(SinglePageFuzzer.ENTER)
                ])
            ]
        });
        setTimeout(function() { SinglePageFuzzer.stop() }, 5000)
    };
    document.head.appendChild(el);
})(document.createElement('script'));

Beispiel 1: TodoMVC

request: {
    lag: 1000, // 1s
    dropRequest: 0.1, // 10%
    dropResponse: 0.1, // 10%
    offline: 10000, // 10s
    online: 5000 // 5s
}

Network

Beispiel 1: TodoMVC

(function(el){
    el.src='https://cdn.rawgit.com/usystems/singlepagefuzzer/' +
        'master/src/singlepagefuzzer.js';
    el.onload=function(){
        SinglePageFuzzer.start({
            selectFilter: function(x, y, el) {
                while (el !== null) {
                    if (el.nodeName == 'SECTION') return true;
                    else el = el.parentElement;
                }
                return false;
            },
            eventDistribution: [
                SinglePageFuzzer.createEventProbability(0.5, [SinglePageFuzzer.createClick()]),
                SinglePageFuzzer.createEventProbability(0.1, [SinglePageFuzzer.createDblclick()]),
                SinglePageFuzzer.createEventProbability(0.2, [
                    SinglePageFuzzer.createInput(),
                    SinglePageFuzzer.createSubmit()
                ]),
                SinglePageFuzzer.createEventProbability(0.2, [
                    SinglePageFuzzer.createKeydown(SinglePageFuzzer.ENTER),
                    SinglePageFuzzer.createKeypress(SinglePageFuzzer.ENTER),
                    SinglePageFuzzer.createKeyup(SinglePageFuzzer.ENTER)
                ])
            ],
            request: {
                lag: 1000, // 1s
                dropRequest: 0.1, // 10%
                dropResponse: 0.1, // 10%
                offline: 10000, // 10s
                online: 5000 // 5s
            }
        });
        setTimeout(function() { SinglePageFuzzer.stop() }, 5000)
    };
    document.head.appendChild(el);
})(document.createElement('script'));

Beispiel 2: Rondo

(function(el){
    el.src='//url/to/singlepagefuzzer.js';
    el.onload=function(){
        SinglePageFuzzer.start({

        });
    };
    document.head.appendChild(el);
})(document.createElement('script'));

Skeleton

Beispiel 2: Rondo

SinglePageFuzzer.start({
    eventDistribution: [
        SinglePageFuzzer.createEventProbability(1, [
            SinglePageFuzzer.createMousedown(),
            SinglePageFuzzer.createMousemove(),
            SinglePageFuzzer.createMouseup()
        ])
    ]
});

Events

Beispiel 2: Rondo

SinglePageFuzzer.start({
    timeout: angular.$timeout
});

Timeout

Beispiel 2: Rondo

(function(el){
    el.src='https://cdn.rawgit.com/usystems/singlepagefuzzer/' +
        'master/src/singlepagefuzzer.js';
    el.onload=function(){
        SinglePageFuzzer.start({
            eventDistribution: [
                SinglePageFuzzer.createEventProbability(1, [
                    SinglePageFuzzer.createMousedown(),
                    SinglePageFuzzer.createMousemove(),
                    SinglePageFuzzer.createMouseup()
                ])
            ],
            timeout: angular.$timeout
        });
    };
    document.head.appendChild(el);
})(document.createElement('script'));

Danke

https://github.com/usystems/singlepagefuzzer

fuzzing wwd

By gamperl

fuzzing wwd

fuzzing web applications

  • 268