v0.1 - initial commit
This commit is contained in:
+59
@@ -0,0 +1,59 @@
|
||||
package winpwn
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// FindXORKey finds a single byte k such that XORing data with the
|
||||
// repeating key k produces no byte present in badChars -- the search step
|
||||
// behind pwntools' encoders.xor, scoped to a single-byte key (the common
|
||||
// case: avoiding \x00/\x0a/\x0d in a payload that itself gets typed/parsed
|
||||
// as text before reaching the target). Returns an error if no byte in
|
||||
// 0..255 works, which can happen if badChars is large enough that every
|
||||
// possible key XORs at least one data byte into a forbidden value.
|
||||
func FindXORKey(data []byte, badChars []byte) (byte, error) {
|
||||
var bad [256]bool
|
||||
for _, b := range badChars {
|
||||
bad[b] = true
|
||||
}
|
||||
|
||||
candidate:
|
||||
for k := 0; k < 256; k++ {
|
||||
key := byte(k)
|
||||
if bad[key] {
|
||||
continue // the key itself ends up nowhere in the output, but
|
||||
// disallowing it too keeps the result usable as a literal
|
||||
// byte elsewhere in the same payload (e.g. a decoder stub
|
||||
// that embeds the key as an immediate).
|
||||
}
|
||||
for _, b := range data {
|
||||
if bad[b^key] {
|
||||
continue candidate
|
||||
}
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
return 0, fmt.Errorf("no single-byte XOR key avoids all %d bad chars for this %d-byte input", len(badChars), len(data))
|
||||
}
|
||||
|
||||
// EncodeXOR finds a single-byte XOR key avoiding badChars (via FindXORKey)
|
||||
// and returns data encoded with it, plus the key itself. Decode by XORing
|
||||
// again with the same key (see Xor in fiddling.go) -- this is the
|
||||
// data-level half of pwntools' bad-character avoidance; it does not emit a
|
||||
// self-decoding stub, so the receiving side needs to already know how to
|
||||
// undo it (e.g. the target's own code does the XOR, or your script decodes
|
||||
// a leaked buffer before parsing it).
|
||||
func EncodeXOR(data []byte, badChars []byte) (encoded []byte, key byte, err error) {
|
||||
key, err = FindXORKey(data, badChars)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return Xor(data, []byte{key}), key, nil
|
||||
}
|
||||
|
||||
// HasBadChars reports whether data contains any byte in badChars -- the
|
||||
// quick check before bothering with an encoder at all.
|
||||
func HasBadChars(data []byte, badChars []byte) bool {
|
||||
return bytes.ContainsAny(data, string(badChars))
|
||||
}
|
||||
Reference in New Issue
Block a user