From 713ee5cd64540f1721176b2ff3b94cbb141f113f Mon Sep 17 00:00:00 2001 From: CyberRoute Date: Thu, 15 Feb 2024 16:49:32 +0100 Subject: [PATCH] file reader pattern, credits for this to @evilsocket --- cmd/bruter/main.go | 21 ++++++++--------- pkg/fuzzer/reader.go | 49 +++++++++++++++++++++++++++++++++++++++ pkg/fuzzer/reader_test.go | 46 ++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 pkg/fuzzer/reader.go create mode 100644 pkg/fuzzer/reader_test.go diff --git a/cmd/bruter/main.go b/cmd/bruter/main.go index a807118..590b3f1 100644 --- a/cmd/bruter/main.go +++ b/cmd/bruter/main.go @@ -108,10 +108,18 @@ func main() { } defer file.Close() - list := readDictionary(file) + linesChan, _, err := fuzzer.Reader(file.Name(), 0) + if err != nil { + log.Fatal().Err(err).Msg("") + } + + list := make([]string, 0) + for line := range linesChan { + list = append(list, line) + } + total := len(list) shift := 1 - queue := createQueue(&app.Mu, *Domain, list, shift, total, *Verbose) queue.WaitDone() @@ -120,15 +128,6 @@ func main() { select {} } -func readDictionary(file *os.File) []string { - buffer := make([]byte, 500000) // 500K (almost) - EOB, err := file.Read(buffer) - if err != nil { - log.Fatal().Err(err).Msg("") - } - return strings.Split(string(buffer[:EOB]), "\n") -} - func createQueue(mu *sync.Mutex, domain string, list []string, shift, total int, verbose bool) *async.WorkQueue { queue := async.NewQueue(*Workers, func(arg async.Job) { ctx := arg.(*workerContext) diff --git a/pkg/fuzzer/reader.go b/pkg/fuzzer/reader.go new file mode 100644 index 0000000..e76bffc --- /dev/null +++ b/pkg/fuzzer/reader.go @@ -0,0 +1,49 @@ +package fuzzer + +import ( + "bufio" + "io" + "os" +) + +func Reader(filename string, noff int64) (chan string, int64, error) { + fp, err := os.Open(filename) + if err != nil { + return nil, 0, err + } + + // if offset defined then start from there + if noff > 0 { + // and go to the start of the line + b := make([]byte, 1) + for b[0] != '\n' { + noff-- + if _, err := fp.Seek(noff, io.SeekStart); err != nil { + fp.Close() + return nil, 0, err + } + if _, err := fp.Read(b); err != nil { + fp.Close() + return nil, 0, err + } + } + noff++ + } + + out := make(chan string) + go func() { + defer fp.Close() + defer close(out) + scanner := bufio.NewScanner(fp) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + if _, err := fp.Seek(0, io.SeekCurrent); err != nil { + return // Stop reading and return if seeking fails + } + out <- scanner.Text() + noff += int64(len(scanner.Bytes()) + 1) // Update noff + } + }() + + return out, noff, nil +} diff --git a/pkg/fuzzer/reader_test.go b/pkg/fuzzer/reader_test.go new file mode 100644 index 0000000..5dc8ccb --- /dev/null +++ b/pkg/fuzzer/reader_test.go @@ -0,0 +1,46 @@ +package fuzzer_test + +import ( + "os" + "reflect" + "testing" + + "github.com/CyberRoute/bruter/pkg/fuzzer" +) + +func TestReader(t *testing.T) { + // Create a temporary file with some content + tmpfile, err := os.CreateTemp("", "example") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpfile.Name()) // Clean up the file + + // Write some content to the file + content := "line1\nline2\nline3\n" + if _, err := tmpfile.WriteString(content); err != nil { + t.Fatal(err) + } + tmpfile.Close() + + // Test the Reader function with default offset (0) + ch, offset, err := fuzzer.Reader(tmpfile.Name(), 0) + if err != nil { + t.Fatal(err) + } + if offset != 0 { + t.Errorf("Expected default offset should be %d", offset) + } + + // Read all lines from the channel into a slice + var lines []string + for line := range ch { + lines = append(lines, line) + } + + // Verify the lines read from the channel + expectedLines := []string{"line1", "line2", "line3"} + if !reflect.DeepEqual(lines, expectedLines) { + t.Errorf("Expected lines %v, got %v", expectedLines, lines) + } +}