-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 786bfc6
Showing
16 changed files
with
972 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
name: Install Frida Devkit | ||
description: Install Frida Devkit | ||
inputs: | ||
arch: | ||
required: true | ||
path: the architecture of the devkit | ||
os: | ||
required: true | ||
path: the target operating system of the devkit | ||
version: | ||
required: true | ||
path: the version of the devkit | ||
outdir: | ||
required: true | ||
path: where to save header and dylib | ||
runs: | ||
using: composite | ||
steps: | ||
- run: | | ||
mkdir /tmp/frida-core-devkit && cd /tmp/frida-core-devkit | ||
wget https://github.com/frida/frida/releases/download/${{ inputs.version }}/frida-core-devkit-${{ inputs.version }}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz -O - | tar --extract --xz | ||
mkdir -p ${{ inputs.outdir }}/include | ||
mkdir -p ${{ inputs.outdir }}/lib | ||
cp frida-core.h ${{ inputs.outdir }}/include | ||
cp libfrida-core.* ${{ inputs.outdir }}/lib | ||
rm -rf /tmp/frida-core-devkit | ||
shell: bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
name: Release | ||
on: | ||
push: | ||
tags: | ||
- v*.*.* | ||
|
||
jobs: | ||
release: | ||
strategy: | ||
matrix: | ||
frida_version: ["16.1.3"] | ||
runs-on: macos-latest | ||
steps: | ||
- | ||
name: Checkout | ||
uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
- | ||
name: Set up Go | ||
uses: actions/setup-go@v4 | ||
- | ||
name: Fetch all tags | ||
run: git fetch --force --tags | ||
- | ||
name: Download Frida macOS_amd64 | ||
uses: ./.github/actions/install-frida-devkit | ||
with: | ||
arch: x86_64 | ||
os: macos | ||
version: ${{ matrix.frida_version }} | ||
outdir: /tmp/data/macos_amd64 | ||
- | ||
name: Download Frida macOS_arm64 | ||
uses: ./.github/actions/install-frida-devkit | ||
with: | ||
arch: arm64 | ||
os: macos | ||
version: ${{ matrix.frida_version }} | ||
outdir: /tmp/data/macos_arm64 | ||
- | ||
name: Run GoReleaser | ||
uses: goreleaser/goreleaser-action@v4 | ||
with: | ||
distribution: goreleaser | ||
version: latest | ||
args: release --clean | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
before: | ||
hooks: | ||
- go mod tidy | ||
builds: | ||
- id: macos_amd64 | ||
binary: furlzz | ||
env: | ||
- CGO_ENABLED=1 | ||
- CGO_LDFLAGS=-L/tmp/data/macos_amd64/lib | ||
- CGO_CFLAGS=-I/tmp/data/macos_amd64/include | ||
goos: | ||
- darwin | ||
goarch: | ||
- amd64 | ||
flags: | ||
- -trimpath | ||
ldflags: -s -w | ||
- id: macos_arm64 | ||
binary: furlzz | ||
env: | ||
- CGO_ENABLED=1 | ||
- CGO_LDFLAGS=-L/tmp/data/macos_arm64/lib | ||
- CGO_CFLAGS=-I/tmp/data/macos_arm64/include | ||
goos: | ||
- darwin | ||
goarch: | ||
- arm64 | ||
flags: | ||
- -trimpath | ||
ldflags: -s -w | ||
checksum: | ||
name_template: 'checksums.txt' | ||
changelog: | ||
sort: asc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"github.com/frida/frida-go/frida" | ||
"github.com/spf13/cobra" | ||
"io" | ||
"os" | ||
"time" | ||
) | ||
|
||
var crashCmd = &cobra.Command{ | ||
Use: "crash", | ||
Short: "Run the application with crash", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
sfile, err := cmd.Flags().GetString("session") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
l.Infof("Reading session file %s", sfile) | ||
s, err := NewSession(sfile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
crash, err := cmd.Flags().GetString("crash") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
inpf, err := os.Open(crash) | ||
if err != nil { | ||
return err | ||
} | ||
defer inpf.Close() | ||
|
||
input, _ := io.ReadAll(inpf) | ||
|
||
l.Infof("Read %s from crash file", string(input)) | ||
|
||
dev := frida.USBDevice() | ||
if dev == nil { | ||
return errors.New("no USB device detected") | ||
} | ||
defer dev.Clean() | ||
|
||
sess, err := dev.Attach(s.App, nil) | ||
if err != nil { | ||
return err | ||
} | ||
defer sess.Clean() | ||
|
||
l.Infof("Attached to %s", s.App) | ||
|
||
script, err := sess.CreateScript(scriptContent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
script.On("message", func(message string) { | ||
l.Infof("script output: %s", message) | ||
}) | ||
|
||
if err := script.Load(); err != nil { | ||
return err | ||
} | ||
defer script.Clean() | ||
|
||
l.Infof("Loaded script") | ||
|
||
l.Infof("Sleeping for two seconds and triggering crash") | ||
|
||
time.Sleep(2 * time.Second) | ||
|
||
_ = script.ExportsCall("fuzz", s.Method, string(input)) | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
func init() { | ||
crashCmd.Flags().StringP("session", "s", "", "session path") | ||
crashCmd.Flags().StringP("crash", "c", "", "crash file") | ||
|
||
rootCmd.AddCommand(crashCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"github.com/fatih/color" | ||
"github.com/frida/frida-go/frida" | ||
"github.com/nsecho/furlzz/mutator" | ||
"github.com/spf13/cobra" | ||
"os" | ||
"strings" | ||
"time" | ||
) | ||
|
||
var fuzzCmd = &cobra.Command{ | ||
Use: "fuzz", | ||
Short: "Fuzz URL scheme", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
var validInputs []string | ||
var err error | ||
|
||
base, err := cmd.Flags().GetString("base") | ||
if err != nil { | ||
return err | ||
} | ||
if base == "" { | ||
return errors.New("base URL cannot be empty") | ||
} | ||
|
||
input, err := cmd.Flags().GetString("input") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if input == "" && strings.Contains(base, "FUZZ") { | ||
return errors.New("input directory cannot be empty when using FUZZ keyword") | ||
} | ||
|
||
if strings.Contains(base, "FUZZ") { | ||
validInputs, err = readInputs(input) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
runs, err := cmd.Flags().GetUint("runs") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fn, err := cmd.Flags().GetString("function") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
timeout, err := cmd.Flags().GetUint("timeout") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
method, err := cmd.Flags().GetString("method") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
l.Infof("Fuzzing base URL \"%s\"", base) | ||
if strings.Contains(base, "FUZZ") { | ||
l.Infof("Read %d inputs from %s directory", | ||
len(validInputs), input) | ||
} else { | ||
l.Infof("Fuzzing base URL") | ||
} | ||
|
||
if runs == 0 { | ||
l.Infof("Fuzzing indefinitely") | ||
} else { | ||
l.Infof("Fuzzing with %d mutated inputs", runs) | ||
} | ||
|
||
if timeout != 0 { | ||
l.Infof("Sleeping %d seconds between each fuzz case", timeout) | ||
} | ||
|
||
app, err := cmd.Flags().GetString("app") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if app == "" { | ||
return errors.New("error: app cannot be empty") | ||
} | ||
|
||
dev := frida.USBDevice() | ||
if dev == nil { | ||
return errors.New("no USB device detected") | ||
} | ||
defer dev.Clean() | ||
|
||
sess, err := dev.Attach(app, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
l.Infof("Attached to %s", app) | ||
|
||
var lastInput string | ||
|
||
sess.On("detached", func(reason frida.SessionDetachReason, crash *frida.Crash) { | ||
l.Infof("Session detached; reason=%s", reason.String()) | ||
out := crashSHA256(lastInput) | ||
err := func() error { | ||
f, err := os.Create(out) | ||
if err != nil { | ||
return err | ||
} | ||
f.WriteString(lastInput) | ||
return nil | ||
}() | ||
if err != nil { | ||
l.Errorf("Error writing crash file: %v", err) | ||
} else { | ||
l.Infof("Written crash to: %s", out) | ||
} | ||
s := Session{ | ||
App: app, | ||
Base: base, | ||
Function: fn, | ||
Method: method, | ||
} | ||
if err := s.WriteToFile(); err != nil { | ||
l.Errorf("Error writing session file: %v", err) | ||
} else { | ||
l.Infof("Written session file") | ||
} | ||
os.Exit(1) | ||
}) | ||
|
||
script, err := sess.CreateScript(scriptContent) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
script.On("message", func(message string) { | ||
l.Infof("script output: %s", message) | ||
}) | ||
|
||
if err := script.Load(); err != nil { | ||
return err | ||
} | ||
|
||
l.Infof("Loaded script") | ||
|
||
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, mutated.Input) | ||
if timeout > 0 { | ||
time.Sleep(time.Duration(timeout) * time.Second) | ||
} | ||
} | ||
return nil | ||
}, | ||
} | ||
|
||
func init() { | ||
fuzzCmd.Flags().StringP("app", "a", "Gadget", "Application name to attach to") | ||
fuzzCmd.Flags().StringP("base", "b", "", "base URL to fuzz") | ||
fuzzCmd.Flags().StringP("input", "i", "", "path to input directory") | ||
fuzzCmd.Flags().StringP("function", "f", "", "apply the function to mutated input (url, base64)") | ||
fuzzCmd.Flags().StringP("method", "m", "delegate", "method of opening url (delegate, app)") | ||
fuzzCmd.Flags().UintP("runs", "r", 0, "number of runs") | ||
fuzzCmd.Flags().UintP("timeout", "t", 1, "sleep X seconds between each case") | ||
|
||
rootCmd.AddCommand(fuzzCmd) | ||
} |
Oops, something went wrong.