shrapnel

package module
v0.0.0-...-c37e809 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2024 License: MIT Imports: 14 Imported by: 0

README ¶

💥 Shrapnel

Explode and implode nested encoding

Example

example/example.go

package main

import (
	"bytes"
	"fmt"
	"io"
	"os"

	shrapnel "github.com/B00TK1D/shrapnel"
)

func main() {

	// Open input.txt and read the contents
	f, err := os.Open("input.txt")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	input, err := io.ReadAll(f)
	if err != nil {
		panic(err)
	}

	// Create a new shrapnel object
	original := shrapnel.Fragment{
		Contents: input,
	}

	// Explode the input
	original.Explode(shrapnel.AllExploders...)

	// Print the original signature
	//original.Print()
	fmt.Printf("Original signature:\t%x\n", original.Signature)

	//fmt.Println("----------------------------------------------------")

	// Apply a converter that changes "user" to "newthing"
	original.Apply(func(input []byte) []byte {
		return bytes.ReplaceAll(input, []byte("triple"), []byte("quadruple"))
	})

	// Print the results
	//original.Print()

	// Implode the input
	original.Implode()

	fmt.Println("----------------------------------------------------")

	original.Print()

	fmt.Println("----------------------------------------------------")

	fmt.Println(string(original.Contents))

	// Print the results
	fmt.Println(string(original.Contents))
	fmt.Printf("New signature:\t\t%x\n", original.Signature)
}

Documentation ¶

Index ¶

Constants ¶

This section is empty.

Variables ¶

View Source
var Base64Exploder = Exploder{
	Transformer: TransformerFactory(b64.StdEncoding.DecodeString, b64.StdEncoding.EncodeToString),
	Filter:      FilterChainGenerator(isAscii, isMinLength(4)),
	Extract:     regexExtractorGenerator(`[a-zA-Z0-9///+]+=?=?`),
}
View Source
var BrotiliExploder = Exploder{
	Transformer: Transformer{
		Transform: func(input []byte) []byte {
			reader := bytes.NewReader(input)
			breader := brotli.NewReader(reader)

			output, err := io.ReadAll(breader)
			if err != nil {
				return []byte{}
			}

			return output
		},
		Reverse: func(input []byte) []byte {
			var buf bytes.Buffer
			bwriter := brotli.NewWriter(&buf)
			bwriter.Write(input)
			bwriter.Close()
			return buf.Bytes()
		},
	},
	Filter: FilterChainGenerator(isAscii, isMinLength(4)),
	Extract: func(input []byte) ([][]byte, Signature) {

		if bytes.HasPrefix(input, []byte{0x78, 0x9c}) {
			return [][]byte{input}, Signature{}
		}
		return [][]byte{}, Signature{}
	},
}
View Source
var GzipExploder = Exploder{
	Transformer: Transformer{
		Transform: func(input []byte) []byte {
			reader := bytes.NewReader(input)
			gzreader, err := gzip.NewReader(reader)
			if err != nil {
				return []byte{}
			}

			output, err := io.ReadAll(gzreader)
			if err != nil {
				return []byte{}
			}

			return output
		},
		Reverse: func(input []byte) []byte {
			var buf bytes.Buffer
			gzwriter := gzip.NewWriter(&buf)
			gzwriter.Write(input)
			gzwriter.Close()
			return buf.Bytes()
		},
	},
	Filter: FilterChainGenerator(isAscii, isMinLength(4)),
	Extract: func(input []byte) ([][]byte, Signature) {

		if bytes.HasPrefix(input, []byte{0x1f, 0x8b}) {
			return [][]byte{input}, Signature{}
		}
		return [][]byte{}, Signature{}
	},
}
View Source
var HexExploder = Exploder{
	Transformer: TransformerFactory(hex.DecodeString, hex.EncodeToString),
	Filter:      FilterChainGenerator(isAscii, isMinLength(4)),
	Extract:     regexExtractorGenerator(`[a-fA-F0-9]{2,}`),
}
View Source
var HtmlExploder = Exploder{
	Transformer: TransformerFactory(html.UnescapeString, html.EscapeString),
	Filter:      FilterChainGenerator(isAscii, isMinLength(4)),
	Extract:     regexExtractorGenerator(`&#\d{2,};`),
}
View Source
var HttpHeaderExploder = Exploder{
	Transformer: TransformerFactory(nil, nil),
	Filter:      isAscii,
	Extract: func(input []byte) ([][]byte, Signature) {

		signature := Signature{}
		headerContents := [][]byte{}
		messages := httpHeaderRegex.FindAll([]byte(input), -1)

		for _, message := range messages {
			headers := strings.Split(string(message), "\r\n")

			for i, header := range headers {
				if i == 0 {

					if strings.HasPrefix(header, "HTTP") {

						signature.append(Signature([]byte(header)))
					} else {

						signature.append(Signature([]byte(strings.Split(header, " ")[0])))
						signature.append(Signature([]byte(strings.Split(header, " ")[2])))
					}
					continue
				}

				splitHeader := strings.Split(header, ":")
				if len(splitHeader) < 2 {
					continue
				}
				signature.append(Signature([]byte(strings.Split(header, ":")[0])))
				headerContents = append(headerContents, []byte(strings.Join(strings.Split(header, ":")[1:], ":")))
			}
		}

		return headerContents, signature
	},
}
View Source
var JsonExploder = Exploder{
	Transformer: TransformerFactory(nil, nil),
	Filter:      isAscii,
	Extract: func(input []byte) ([][]byte, Signature) {
		var contents [][]byte
		signature := Signature{}

		objects := jsonRegex.FindAll(input, -1)

		keyRegex := regexp.MustCompile(`"([^"]+)"\s*:\s*`)
		valueRegex := regexp.MustCompile(`\s*:\s*"?(.+?)"?\s*(?:,|})`)

		for _, object := range objects {
			keys := keyRegex.FindAllSubmatch(object, -1)
			values := valueRegex.FindAllSubmatch(object, -1)
			for _, key := range keys {
				signature.append(Signature(key[1]))
			}
			for _, value := range values {
				if len(value) < 2 {
					continue
				}
				if value[1][0] == '[' || value[1][0] == '{' {

					continue
				}
				contents = append(contents, value[1])
			}
		}

		return contents, signature
	},
}
View Source
var UrlExploder = Exploder{
	Transformer: TransformerFactory(url.QueryUnescape, url.QueryEscape),
	Filter:      FilterChainGenerator(isAscii, isMinLength(4)),
	Extract:     regexExtractorGenerator(`%[A-Fa-f0-9]{2}`),
}
View Source
var ZlibExploder = Exploder{
	Transformer: Transformer{
		Transform: func(input []byte) []byte {
			reader := bytes.NewReader(input)
			zreader, err := zlib.NewReader(reader)
			if err != nil {
				return []byte{}
			}

			output, err := io.ReadAll(zreader)
			if err != nil {
				return []byte{}
			}

			return output
		},
		Reverse: func(input []byte) []byte {
			var buf bytes.Buffer
			zwriter := zlib.NewWriter(&buf)
			zwriter.Write(input)
			zwriter.Close()
			return buf.Bytes()
		},
	},
	Filter: FilterChainGenerator(isAscii, isMinLength(4)),
	Extract: func(input []byte) ([][]byte, Signature) {

		if bytes.HasPrefix(input, []byte{0x78, 0x9c}) {
			return [][]byte{input}, Signature{}
		}
		return [][]byte{}, Signature{}
	},
}

Functions ¶

func Parallel ¶

func Parallel[T any](visitor func([][]byte) T, fragments ...Fragment) ([]T, error)

func ParallelBottom ¶

func ParallelBottom[T any](visitor func([][]byte) T, fragments ...Fragment) ([]T, error)

func TransformerGenerator ¶

func TransformerGenerator(Transform interface{}) func([]byte) []byte

Types ¶

type Exploder ¶

type Exploder struct {
	Extract     Extractor
	Transformer Transformer
	Filter      Filter
}

type Extractor ¶

type Extractor func([]byte) ([][]byte, Signature)

type Filter ¶

type Filter func([]byte) bool

func FilterChainGenerator ¶

func FilterChainGenerator(Filters ...Filter) Filter

type Fragment ¶

type Fragment struct {
	Signature Signature
	Contents  []byte
	// contains filtered or unexported fields
}

func (*Fragment) Apply ¶

func (e *Fragment) Apply(visitor func([]byte) []byte)

func (*Fragment) Explode ¶

func (e *Fragment) Explode(exploders ...Exploder)

func (*Fragment) Flatten ¶

func (e *Fragment) Flatten() []byte

func (*Fragment) Implode ¶

func (e *Fragment) Implode()

func (*Fragment) Print ¶

func (e *Fragment) Print()

type Signature ¶

type Signature []byte

type Transformer ¶

type Transformer struct {
	Transform func([]byte) []byte
	Reverse   func([]byte) []byte
}

func TransformerFactory ¶

func TransformerFactory(t interface{}, r interface{}) Transformer

Directories ¶

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL