[1] https://docs.python.org/3/library/audit_events.html
[2] https://daddycocoaman.dev/posts/bypassing-python38-audit-hoo...
21–30 of 70 posts
[1] https://docs.python.org/3/library/audit_events.html
[2] https://daddycocoaman.dev/posts/bypassing-python38-audit-hoo...
I know for a fact a lot of cybersecurity automation mind share is in Python. Curious to see if this new wave of Python malware will make it into any big cybersecurity vendors. I've performed due diligence on a number of cybersecurity vendors that I wouldn't qualify as having good security posture for stuff like this.
Is it just me, or does this read like a friendly howto for a would-be python malware author?
It's a well known problem that many languages (Python, Ruby, Node) have notoriously insecure trust chains in their dependency management frameworks. If more malware is hitting the Python ecosystem, I think it's just a matter of time until someone manages to publish a tainted version of `requests` or some similarly popular Python lib. I know for a fact a lot of cybersecurity automation mind share is in Python. Curious…
This is a very interesting article, and it is somewhat surprising to see Python entering the malware space more in recent years. Other compiled languages with sophisticated runtimes and cross platform support fit in quite well (Go especially) but to see Python is quite interesting. I guess these actors are at a point where they can churn it out relatively quickly, and are not too worried about the code being reversed…
In short, they shipped a python interpreter that understood rc4 encrypted pyc/opcode files.
I was going to mention Python 3.8's audit hooks[1] as a possible way to catch some of these issues, (like web requests, for example) but when I went to Google to find the link, it also came up with an article explaining how to bypass the audit hooks[2]... [1] https://docs.python.org/3/library/audit_events.html [2] https://daddycocoaman.dev/posts/bypassing-python38-audit-hoo...
In fact, I even implemented the variant of audit hooks that informed PEP-551 and deployed those to production for a major platform.
I think that if you were to use audit hooks, you might want to combine them with a code signing mechanism. I worked on two of these for different platforms, and they add another strong layer of defence.
In light of that, the bypass in the article seems somewhat contrived, especially considering that there are at least three alternate techniques you could employ to accomplish the same goal that would be meaningfully more innocuous than using `ctypes.windll`. If you're going to use `ctypes` or `pywin32` or the like, then you might as well write a C-extension module to patch out the audit hooks directly (as Batuhan Taşkaya shows using a simple trampoline toy library I wrote, `libhook`: https://speakerdeck.com/isidentical/hack-the-cpython?slide=3...).
Better techniques:
1. Joe Jevnik and my `tuple_setitem` which uses poisoned bytecode and the lack of bounds checks on `LOAD_FAST`/`GETLOCAL`. (Pure Python.)
https://gist.github.com/llllllllll/b1ac68a6b77535a64c0b13bfd...
2. My `tuple_setitem` using `numpy` raw memory access via `numpy.lib.stride_tricks.as_strided`. (Requires only `numpy`.)
https://twitter.com/dontusethiscode/status/12513186248470855...
3. Using the `/proc` filesystem on Linux, which gives arbitrary intraprocess read/write access (independent of page permissions.) (Requires only `open(..., 'w')`.)
https://twitter.com/dontusethiscode/status/12818444226285854... https://gist.github.com/dutc/2cc5de0d2f8877b8f463b86e8bd5231...
There are also a couple of techniques you could employ to carry one of these payloads past code signing, some of which are very well known, like the insecurity of `pickle` deserialisation, and some of which are… less well known.
(I have also prototyped using the above exploits to "lift" C code into a Python interpreter, in case there are OS-level defences around `dlopen`.)
However, even taking these into account, I'm a big believer of the value of Python 3.8 audit hooks at PEP-551, but they are technique that requires quite a bit of extra work to effectively employ.
If you're interested in trying to implement audit hooks and these other mechanisms for locking down your execution environment (e.g., you want to mitigate exploits in Python systems, which may run as PID-1 in a containers, where these exploits may try to bring in malware that could exfiltrate data…) please feel free to reach out to me by e-mail or Twitter.
I would be happy to share more with any organisations that are large enough to consider locking things down at this level.
A lot of exploits are two-stage. Stage one is usually the vulnerability, usually written in C given the low-level and tightly controlled instructions required. The exploit breaks security to run an executable or otherwise gain control. Stage two is usually downloading a python executable to grab the goods.
There's nothing especially sinister about the selection of Python for this case over other interpreted languages. Malware authors are just regular developers - they don't want to spend hours trying to hack together a C binary to dump a database when six lines of Python will do it. Python just runs on a lot of platforms, has a lot of mature drop-in libraries, and decent documentation. They use it for the same reason we use it.
The article just makes it sound like malware developers are using modern packaging tools to turn that two-stage exploit into a single-stage. That doesn't strike me as particularly surprising. Teams tend to gravitate towards specializing in one tool when they can. I'd obviously prefer to write a bunch of python than do the same in C, when performance isn't a huge concern (It's the other guy's CPU, after all).
Just seems like a minor observation, rather than some doom trend.
See PupyRAT, a full-on multi-os admin tool mainly written in Python (2 unfortunately, also it's buggy and outdated), it's a great example. They use a C wrapper around their remote admin tool that is written in Python. Their (C) loader downloads the provided Python payload from an http link, stores it in a specific memory address that gets executed right after. Because it's in memory, it doesn't touch the disk, Unless you are using the Windows payload (which provides multiple options to hide the program using a set of windows' exploits).
I think a lot of people will read 'python malware' and assume packages; that's not what this is about. A lot of exploits are two-stage. Stage one is usually the vulnerability, usually written in C given the low-level and tightly controlled instructions required. The exploit breaks security to run an executable or otherwise gain control. Stage two is usually downloading a python executable to grab the goods. There's n…