08.04.23
Easterhegg 2023
K1/3

Wir bauen web fuzzer... ...in schnell

https://emile.space/events/2023/04-easterhegg/

@hanemile
https://emile.space/events/2023/04-easterhegg/
1
08.04.23
Easterhegg 2023
K1/3

Fuzzer, wasn' das?

@hanemile
https://emile.space/events/2023/04-easterhegg/
2
08.04.23
Easterhegg 2023
K1/3

Golang

@hanemile
https://emile.space/events/2023/04-easterhegg/
3
08.04.23
Easterhegg 2023
K1/3

Setting up a project

@hanemile
https://emile.space/events/2023/04-easterhegg/
4
08.04.23
Easterhegg 2023
K1/3
Getting started
; mkdir fuzz
; cd fuzz
; go mod init github.com/<nick>/fuzz
@hanemile
https://emile.space/events/2023/04-easterhegg/
5
08.04.23
Easterhegg 2023
K1/3
Printing something (testing the setup)
// main.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello World!")
}
// go run ./...
@hanemile
https://emile.space/events/2023/04-easterhegg/
6
08.04.23
Easterhegg 2023
K1/3

Making an HTTP request

@hanemile
https://emile.space/events/2023/04-easterhegg/
7
08.04.23
Easterhegg 2023
K1/3
package main

import (
        "fmt"
        "io"
        "net/http"
)

func main() {
        fmt.Println("hello world")

        resp, err := http.Get("https://emile.space")
        if err != nil {
                fmt.Println("Some error: ", err)
        }

        defer resp.Body.Close()

        body, err := io.ReadAll(resp.Body)
        if err != nil {
                fmt.Println("Some error: ", err)
        }

        fmt.Println(body)
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
8
08.04.23
Easterhegg 2023
K1/3
The relevant parts of making an HTTP request
    resp, err := http.Get("http://example.com/")
    defer resp.Body.Close()
    if err != nil {
        // ...
    }

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        // ...
    }

    fmt.Println(string(body))
@hanemile
https://emile.space/events/2023/04-easterhegg/
9
08.04.23
Easterhegg 2023
K1/3

Reading a file

@hanemile
https://emile.space/events/2023/04-easterhegg/
10
08.04.23
Easterhegg 2023
K1/3
import (
    "os"
    "strings"
)

...

    dat, err := os.ReadFile("./wordlist.txt")
    if err != nil {
        // ...
    }
    fmt.Print(string(dat))
@hanemile
https://emile.space/events/2023/04-easterhegg/
11
08.04.23
Easterhegg 2023
K1/3

Combine it!

@hanemile
https://emile.space/events/2023/04-easterhegg/
12
08.04.23
Easterhegg 2023
K1/3
        // read file
        dat, err := os.ReadFile("./wordlist.txt")
        if err != nil {
            fmt.Println("Some error: ", err)
        }

        words := strings.Split(string(dat), "\n")

        // loop over words
        for i, word := range words {
            fmt.Printf("http request nr. %d to word %s ", i, word)

            url := fmt.Sprintf("https://emile.space/%s", word)

            // make the request
            resp, err := http.Get(url)
            ...
@hanemile
https://emile.space/events/2023/04-easterhegg/
13
08.04.23
Easterhegg 2023
K1/3

SPEED

@hanemile
https://emile.space/events/2023/04-easterhegg/
14
08.04.23
Easterhegg 2023
K1/3

Cleanup: Functions!

@hanemile
https://emile.space/events/2023/04-easterhegg/
15
08.04.23
Easterhegg 2023
K1/3
func request(id int, url string) {
        resp, err := http.Get(url)
        if err != nil {
                fmt.Println("Some error: ", err)
        }

        defer resp.Body.Close()

        body, err := io.ReadAll(resp.Body)
        if err != nil {
                fmt.Println("Some error: ", err)
        }

        fmt.Printf("[%d] req to url %s (%d)\n", id, url, len(body))
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
16
08.04.23
Easterhegg 2023
K1/3

"Channel"

https://gobyexample.com/channels

@hanemile
https://emile.space/events/2023/04-easterhegg/
17
08.04.23
Easterhegg 2023
K1/3
// https://gobyexample.com/channel-synchronization
package main

import (
    "fmt"
    "time"
)

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")
    done <- true
}

func main() {
    done := make(chan bool, 1)
    go worker(done)
    
    // something else could be doing stuff here at the same time as the worker
    
    <-done
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
18
08.04.23
Easterhegg 2023
K1/3

using this

@hanemile
https://emile.space/events/2023/04-easterhegg/
19
08.04.23
Easterhegg 2023
K1/3
...
func worker(wordChan chan string) {
    for {
        url := <-wordChan
        request(url)
    }
}
...

func main() {
    ...
    wordChan := make(chan string, 10)
    for i := 1; i < 4; i++ {
        go worker(wordChan)
    }
    ...
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
20
08.04.23
Easterhegg 2023
K1/3
func worker(id int, wordChan chan string, doneChan chan bool) {
    out:
    for {
        select {
        
        case url := <-wordChan:
            url = fmt.Sprintf("https://emile.space/%s", url)
            request(id, url)
            
        case <-time.After(3 * time.Second):
            fmt.Printf("worker %d couldn't get a new url after 3 seconds, quitting\n", id)
            break out
            
        }
    }
    doneChan <- true
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
21
08.04.23
Easterhegg 2023
K1/3
func main() {
    // read wordlist
    dat, err := os.ReadFile("./wordlist1.txt")
    if err != nil {
        fmt.Println("Some error: ", err)
    }

    words := strings.Split(string(dat), "\n")

    // create workers
    wordChan := make(chan string, 10)
    doneChan := make(chan bool, 4)
    for i := 1; i < 4; i++ {
        go worker(i, wordChan, doneChan)
    }

    // fill word channel with all the words we want to fuzz
    fmt.Println("Filling wordChan")
    for _, word := range words {
        wordChan <- word
    }

    // check that all the workers are done before ending
    for i := 1; i < 4; i++ {
        <-doneChan
    }
}
@hanemile
https://emile.space/events/2023/04-easterhegg/
22
08.04.23
Easterhegg 2023
K1/3
    // create workers
    wordChan := make(chan string, 10)
    doneChan := make(chan bool, 4)
    for i := 1; i < 4; i++ {
        go worker(i, wordChan, doneChan)
    }

    // fill word channel with all the words we want to fuzz
    for _, word := range words {
        wordChan <- word
    }
    

    // check that all the workers are done before ending
    for i := 1; i < 4; i++ {
        <-doneChan
    }
@hanemile
https://emile.space/events/2023/04-easterhegg/
23
08.04.23
Easterhegg 2023
K1/3

https://emile.space/events/2023/04-easterhegg/

(Das war's vorerst)

@hanemile
https://emile.space/events/2023/04-easterhegg/
24