A talk given at 44Con 2012 and Nordic Security Con 1 where scalable post-exploitation strategies are discussed, and a cross platform RPC based Python based post-exploitation framework is presented.
ongoing research in extending attack techniques • Came from real world needs of being able to manage complex, long term attack engagements for customers 3
scale well • In the development process • In the ability to be effective against diverse targets • Pen-test frameworks use this approach - Software engineering nightmare
that would run everywhere! • Cross platform, Interpreted Languages such as Java or Python could help here • They also help address some of the software engineering worries
it • Lots of distributed system approaches that may help out here e.g. RPC • Can also help with reducing complexity in the implant, pushing it to the server
persistent native binary code • Harder analysis on both platter & wire • A distributed implant architecture, RPC based • Split the task & the decision • ‘Reach back’ rather than ‘bake in’ 33
Language runtime, not on the target platform Dispatch Bytecode IL Process Loop IL implant Return Object Server Process Task process Tasks IL source IL bytecode RPC&
the programmer is compiled to a simple bytecode representation This is what the .pyc’s/.pyo’s are • Python bytecode is portable between platforms & architectures As long as major & minor versions are the same (micro can vary) 36
• import statement is used to access them & resolve their dependency tree • An import hook is custom importer that can be used to find & load modules in non-standard ways Importer protocol defined in PEP302 37
in the *** Worth a whole talk in itself, see ‘Import this, that and the other thing’ by Brett Cannon PyCon2010 – it’s excellent • Python 3.x reduces this pain via importlib • Not available in Python 2.x so you need to implement from scratch using PEP 302 Available since v2.3 to better customize the __import__ builtin Given 2.x is in the widest use this is what I did 38
Finder Tends to be pretty straightforward Locate the module/package code A Loader More complex Compile to bytecode if needed Insert module into namespace Execute top level code Lots of annoying metadata bookkeeping 39
+ ZIP Import Hook Stage 2 RPC Import Hook & Mainloop Tasking bytecode Binary Injector / Userland Exec Native task • Self-Bootstrapping • Stage 0 is the only persistent part of the implant. Tiny & generic • Simple event-loop that GETs bytecode over SSL & runs it from memory • This is used to bootstrap the Stage 1 import hook ….
+ ZIP Import Hook Stage 2 RPC Import Hook & Mainloop Tasking bytecode Binary Injector / Userland Exec Native task • Stage 1 Import Hook - In memory import of a zip over SSL • Zip imports supported since Py2.3 • but only from the filesystem not memory • Re-implement the stdlib zipfile module in Python
bytecode bundles to be sent, executed and automatically have dependencies resolved remotely without touching disk Write completely standard Python Much quicker to write than C/ASM Much easier to debug/QA Non-stdlib packages easily usable 46
IP’s are often used but generally a bad choice when managing many targets • Instead we use SYSUUID from SMBIOS Fairly easy to get at from Pure Python on Unixes, Linux & OSX Pain in the a** on Windows but can be done via Ctypes 47
persistent connection At random intervals checks-in to RPC endpoint(s) Pending tasks can be sent as A task ID to import, resolve & execute All tasks can operate in own thread or child • Nothing needs to touch disk • Result objects cached & returned next check-in 48
executes on the target Service: The logic that processes the result of the payload, executes on the server • Payloads are pure Python bytecode • Determination of next task happens at the server If compromise detected we leak minimal MO Allows easy updating of goal oriented logic No need to define goal at asset creation time 50
+ ZIP Import Hook Stage 2 RPC Import Hook & Mainloop Common Task Bytecode Binary Injector / Userland Exec Native task • A Common Task is one that is pure Python bytecode E.g. Search for files named ‘pk.pem’ • There is a balance to be struck between stealth & efficiency when splitting tasks Task searching for ‘secret.doc’ can leak MO Exfiltrating every filename to match to ‘secret.doc’ at the server would use bandwidth
+ ZIP Import Hook Stage 2 RPC Import Hook & Mainloop Tasking bytecode Binary Injector / Userland Exec Native task • A Native Task is one that executes native code Some tasks are too low level/ specific for Python • A number of options depending on OS Ctypes, PyObjC, Subprocess • Potential issues Forensically noisy Native functions may be hooked • One solution userland execution …….
image with a new one Without calling OS (Execve, loadlibrary etc) Without having to load from disk • Useful in a number of scenarios Antiforensics Non-exec filesystem mounts Wanting to inject native code from a IL VM! 53
X Think PyELF for OS X Nicely sidesteps code-signing controls • Send a Mach-O binary over the wire to a Python userland exec task, & inject it into an existing process 55
MachO bundle to do webcam capture • isight.bundle hasn’t worked since 64bit Snow Leopard • Relies on Quicktime.framework • 32 bit only • So we wrote a new one for the demo using QTKit (32 & 64 bit supported) 57
• Baking-in capabilities can leak your intent • Interpreted languages can help with scale • Distributed architectures can help with separating action from reason
current toolsets dictate and limit you, critique, innovate & change them to suit your needs Customers • Understand the difference between, and value of Pen-Testing vs Attack Teaming