Skip to content

Commit

Permalink
fix: return back to string inputs generation
Browse files Browse the repository at this point in the history
  • Loading branch information
NSEcho committed Sep 17, 2023
1 parent 89246f9 commit b3bdedf
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 105 deletions.
10 changes: 5 additions & 5 deletions cmd/fuzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var fuzzCmd = &cobra.Command{
Use: "fuzz",
Short: "Fuzz URL scheme",
RunE: func(cmd *cobra.Command, args []string) error {
var validInputs [][]byte
var validInputs []string
var err error

base, err := cmd.Flags().GetString("base")
Expand Down Expand Up @@ -112,7 +112,7 @@ var fuzzCmd = &cobra.Command{

l.Infof("Attached to %s", app)

var lastInput []byte
var lastInput string

sess.On("detached", func(reason frida.SessionDetachReason, crash *frida.Crash) {
l.Infof("Session detached; reason=%s", reason.String())
Expand All @@ -122,7 +122,7 @@ var fuzzCmd = &cobra.Command{
if err != nil {
return err
}
f.Write(lastInput)
f.WriteString(lastInput)
return nil
}()
if err != nil {
Expand Down Expand Up @@ -162,13 +162,13 @@ var fuzzCmd = &cobra.Command{
_ = script.ExportsCall("setup", method, uiapp, delegate)
l.Infof("Finished setup")

m := mutator.NewMutator([]byte(base), runs, fn, validInputs...)
m := mutator.NewMutator(base, runs, fn, validInputs...)
ch := m.Mutate()

for mutated := range ch {
lastInput = mutated.Input
l.Infof("[%s] %s\n", color.New(color.FgCyan).Sprintf("%s", mutated.Mutation), mutated.Input)
_ = script.ExportsCall("fuzz", method, string(mutated.Input))
_ = script.ExportsCall("fuzz", method, mutated.Input)
if timeout > 0 {
time.Sleep(time.Duration(timeout) * time.Second)
}
Expand Down
10 changes: 5 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ func Execute(sc string) error {
return rootCmd.Execute()
}

func readInputs(dirPath string) ([][]byte, error) {
func readInputs(dirPath string) ([]string, error) {
files, err := os.ReadDir(dirPath)
if err != nil {
return nil, err
}

var validInputs [][]byte
var validInputs []string

for _, fl := range files {
if fl.IsDir() {
Expand All @@ -54,13 +54,13 @@ func readInputs(dirPath string) ([][]byte, error) {
if err != nil {
return nil, err
}
validInputs = append(validInputs, data)
validInputs = append(validInputs, string(data))
}
return validInputs, nil
}

func crashSHA256(inp []byte) string {
func crashSHA256(inp string) string {
h := sha256.New()
h.Write(inp)
h.Write([]byte(inp))
return fmt.Sprintf("%x", h.Sum(nil))
}
6 changes: 3 additions & 3 deletions mutator/helpers.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package mutator

func (m *Mutator) getFuzzedInput() []byte {
func (m *Mutator) getFuzzedInput() string {
if m.multipleRounds {
if len(m.lastInput) == 0 {
if m.lastInput == "" {
m.lastInput = m.fetchInput()
}
return m.lastInput
}
return m.fetchInput()
}

func (m *Mutator) fetchInput() []byte {
func (m *Mutator) fetchInput() string {
if m.fuzzIdx == -1 || len(m.validInputs) == 0 {
return m.input
}
Expand Down
123 changes: 48 additions & 75 deletions mutator/mutations.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package mutator

import (
"bytes"
"strings"
"unicode"
)

type mutateFn func(m *Mutator) []byte
type mutateFn func(m *Mutator) string

var mutations = map[string]mutateFn{
"insert": insert,
Expand All @@ -18,103 +19,89 @@ var mutations = map[string]mutateFn{
}

// insert inserts random byte at random location inside the input
func insert(m *Mutator) []byte {
func insert(m *Mutator) string {
inp := m.getFuzzedInput()
pos := m.r.Intn(len(inp))
char := byte(m.r.Intn(255))

res := make([]byte, len(inp)+1)

k := 0

for i := 0; i < len(inp); i++ {
if i == pos {
res[k] = char
res[k+1] = inp[i]
k += 2
} else {
res[k] = inp[i]
k++
var char byte
for {
c := m.r.Intn(unicode.MaxASCII)
if unicode.IsPrint(rune(c)) {
char = byte(c)
break
}
}

return res
return inp[:pos] + string(char) + inp[pos:]
}

// del deletes random byte
func del(m *Mutator) []byte {
func del(m *Mutator) string {
inp := m.getFuzzedInput()
pos := m.r.Intn(len(inp))
res := make([]byte, len(inp)-1)

k := 0
for i := 0; i < len(inp); i++ {
if i == pos {
continue
}
res[k] = inp[i]
k++
}

return res
return inp[:pos] + inp[pos+1:]
}

// substitute substitutes byte at random position with random byte
func substitute(m *Mutator) []byte {
func substitute(m *Mutator) string {
inp := m.getFuzzedInput()
pos := m.r.Intn(len(inp))
char := byte(m.r.Intn(255))

res := make([]byte, len(inp))

var char byte
for {
c := m.r.Intn(unicode.MaxASCII)
if unicode.IsPrint(rune(c)) {
char = byte(c)
break
}
}
var res string
for i, c := range inp {
if i == pos {
res[i] = char
res += string(char)
} else {
res[i] = c
res += string(c)
}
}
return res
}

// byteOp takes random byte and random position inside the string
// and do arithmetic operation on them (+, -, *, /)
func byteOp(m *Mutator) []byte {
func byteOp(m *Mutator) string {
b := make([]byte, 1)
m.r.Read(b)
inp := m.getFuzzedInput()
pos := m.r.Intn(len(inp))

op := m.r.Intn(4)

res := make([]byte, len(inp))
res := make([]rune, len(inp))
for i, r := range inp {
if i == pos {
switch op {
case 0:
res[i] = r + b[0]
res[i] = r + rune(b[0])
case 1:
res[i] = r - b[0]
res[i] = r - rune(b[0])
case 2:
res[i] = r * b[0]
res[i] = r * rune(b[0])
default:
if b[0] != 0 {
res[i] = r / b[0]
res[i] = r / rune(b[0])
} else {
res[i] = r + b[0]
res[i] = r + rune(b[0])
}
}
} else {
res[i] = r
}
}

return res
return string(res)
}

// duplicateRange duplicates random range inside the original string random
// number of times
func duplicateRange(m *Mutator) []byte {
func duplicateRange(m *Mutator) string {
inp := m.getFuzzedInput()

start := m.r.Intn(len(inp))
Expand All @@ -128,76 +115,62 @@ func duplicateRange(m *Mutator) []byte {
}

rng := inp[start:end]
duplicatedBytes := bytes.Repeat(rng, countOfDuplications)

res := make([]byte, len(inp)+len(duplicatedBytes))

k := 0
for i := 0; i < end; i++ {
res[k] = inp[i]
k++
}

for i := 0; i < len(duplicatedBytes); i++ {
res[k] = duplicatedBytes[i]
k++
}

for i := end; i < len(inp); i++ {
res[k] = inp[i]
k++
}
res := ""
res += inp[:start]
res += strings.Repeat(rng, countOfDuplications)
res += inp[end:]

return res
}

// bitFlip flips the bit at random position inside random location inside input
func bitFlip(m *Mutator) []byte {
func bitFlip(m *Mutator) string {
inp := m.getFuzzedInput()

pos := m.r.Intn(len(inp))
bitPosition := m.r.Intn(8)

res := make([]byte, len(inp))
res := ""

for i, r := range inp {
if i == pos {
res[i] = r ^ (1 << bitPosition)
res += string(r ^ (1 << bitPosition))
} else {
res[i] = r
res += string(r)
}
}

return res
}

// bitmask applies random bitmask on random location inside the string
func bitmask(m *Mutator) []byte {
func bitmask(m *Mutator) string {
inp := m.getFuzzedInput()

pos := m.r.Intn(len(inp))
bm := m.r.Intn(255)

res := make([]byte, len(inp))
res := ""

for i, r := range inp {
if pos == i {
res[i] = inp[i] ^ uint8(bm)
res += string(inp[i] ^ uint8(bm))
} else {
res[i] = r
res += string(r)
}
}

return res
}

// duplicate duplicates original string random number of times (2 < 10)
func duplicate(m *Mutator) []byte {
func duplicate(m *Mutator) string {
inp := m.getFuzzedInput()

var count int
for count = m.r.Intn(10); count < 1; count = m.r.Intn(10) {
}

return bytes.Repeat(inp, count)
return strings.Repeat(inp, count)
}
20 changes: 10 additions & 10 deletions mutator/mutator.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package mutator

import (
"bytes"
"math/rand"
"strings"
"time"
)

func NewMutator(inp []byte, runs uint, fnName string, validInputs ...[]byte) *Mutator {
func NewMutator(inp string, runs uint, fnName string, validInputs ...string) *Mutator {
return &Mutator{
fuzzIdx: bytes.Index(inp, []byte("FUZZ")),
fuzzIdx: strings.Index(inp, "FUZZ"),
baseURL: inp,
input: inp,
fnName: fnName,
Expand All @@ -23,18 +23,18 @@ func NewMutator(inp []byte, runs uint, fnName string, validInputs ...[]byte) *Mu
type Mutator struct {
fuzzIdx int
runs uint
baseURL []byte
input []byte
lastInput []byte
baseURL string
input string
lastInput string
fnName string
ch chan *Mutated
r *rand.Rand
validInputs [][]byte
validInputs []string
multipleRounds bool
}

type Mutated struct {
Input []byte
Input string
Mutation string
}

Expand All @@ -55,7 +55,7 @@ func (m *Mutator) Mutate() <-chan *Mutated {
}

func (m *Mutator) mutateAndSend() {
var mutatedInput []byte
var mutatedInput string
var method string
mut := m.r.Intn(len(mutations) + 1)
// run random mutations random number of times
Expand Down Expand Up @@ -99,7 +99,7 @@ func (m *Mutator) mutateAndSend() {
}
} else {
m.ch <- &Mutated{
Input: bytes.Replace(m.baseURL, []byte("FUZZ"), mutatedInput, -1),
Input: strings.Replace(m.baseURL, "FUZZ", mutatedInput, -1),
Mutation: method,
}
}
Expand Down
Loading

0 comments on commit b3bdedf

Please sign in to comment.