This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: [idea] use the Microsoft Antimalware Scan Interface
Type: enhancement Stage:
Components: Interpreter Core, Windows Versions: Python 3.6
process
Status: open Resolution:
Dependencies: 27417 Superseder:
Assigned To: Nosy List: Alexander Riccio, paul.moore, steve.dower, theller, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2016-01-17 09:44 by Alexander Riccio, last changed 2022-04-11 14:58 by admin.

Messages (19)
msg258455 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-01-17 09:44
I'm really not sure what it'd look like, or how it'd work, but CPython should take advantage of Microsoft's Antimalware Scan Interface, which is new to Windows 10. It's designed for applications like interpreters, which can execute u trusted code that may not be visible to antimalware.
msg258456 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-01-17 09:49
See "Windows 10 to offer application developers new malware defenses" https://blogs.technet.microsoft.com/mmpc/2015/06/09/windows-10-to-offer-application-developers-new-malware-defenses/ for an example of how AMSI works with PowerShell.

I think the applicability to CPython is self-evident.
msg258457 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-01-17 09:50
See also: "Security Focus: Defending PowerShell with the Anti-Malware Scan Interface (AMSI)" http://blogs.technet.com/b/poshchap/archive/2015/10/16/security-focus-defending-powershell-with-windows-defender.aspx
msg258458 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-01-17 10:07
When I say "I'm really not sure what it'd look like, or how it'd work" I mean at the C level. At a higher level, there are many places that I imagine are good places to use AMSI: Perhaps expressions passed in from the command line (-c) should be scanned; maybe pip packages should be scanned on installation, and maybe untrusted packages should be scanned right before execution...

Then it's a matter of calling the AMSI APIs in the right places; I don't know where those are.
msg258469 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-01-17 14:30
I actually have a prototype of this already, though I haven't benchmarked the impact yet.

Brett and I were concerned that the applicability wasn't apparent enough given the cost involved, so we've been (slowly) preparing a PEP, mainly to have that record of why it's been added. I'll assign to myself, and keep an eye on python-dev for follow-up.
msg269538 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-29 18:23
This now depends on issue27417, since we can't enable AMSI without enabling COM, and doing that has a number of back-compat implications.
msg269570 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2016-06-30 10:04
Strong -1 on anything that scans my locally-written scripts by default. There's no reason or justification for that.

Maybe there's a point in having a way to submit an untrusted Python code snippet for scanning, but why would that need to be a core service, as opposed to a 3rd party module?
msg269582 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-30 13:02
AMSI is intended for local scanners that are entirely on your own machine, so code never goes anywhere, and everything that passes through the file system is already scanned because of hooks whether you wrote it or not (maybe you're thinking of SmartScreen?).

What this would add is scanning at the exec point in:

python -c exec(decrypt(open('file.bin', 'rb')))

Currently, malware scanners don't get to see the decrypted code, and I'm assured this is a common pattern for getting malware onto machines (yes, in Python).

That said, I fully expect the official releases to require a registry key to enable it (can't be env or CLI option or an attacker would just leave it out :) ). Wouldn't be on for normal use, but would be available for paranoid people.
msg269583 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2016-06-30 15:17
OK, so a 3rd party module providing a "safe_exec" function would make a good proof of concept, I assume. You could probably do that using comtypes or pywin32.

I'm not going to try to say what is or isn't a security threat, that's not my expertise. But I am puzzled as to why "use safe_exec rather than exec" isn't an option, but "use python with the malware scanning option enabled" is. Maybe it's like the Powershell execution policy model, though.

I still don't want it to scan my trusted scripts, though. More interpreter startup overhead? No thanks.

Anyway, thanks for the clarification. It's early days yet to be debating this level of detail, so I'll leave it there.
msg269585 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2016-06-30 15:35
> I am puzzled as to why "use safe_exec rather than exec" isn't an option

Because you're going to have a hard time convincing malware authors to use it.
msg269592 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2016-06-30 16:20
>> I am puzzled as to why "use safe_exec rather than exec" isn't an option

> Because you're going to have a hard time convincing malware authors to use it.

:-) So the malicious payload is the whole python command, not just file.bin. OK, fair enough. But in that case, why hook into exec? The malware author can execute arbitrary Python so doesn't *need* exec.

As I say, though, I'm not an expert in security threats, so I'm OK with accepting that there's a hole here and the proposal plugs it.
msg269598 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-30 16:43
> So the malicious payload is the whole python command, not just file.bin

Yeah, sorry that wasn't clear. Many vulnerabilities allow attackers to schedule process launches (e.g. via cron/Task Scheduler/etc.) without actually being able to add any files to the machine - Stuxnet took advantage of this, for example. So if Python is already there, you can schedule "python -c "import urllib, base64; exec(...)"" to download->decode->exec arbitrary code without touching the file system or network with obvious sources.

(Right now, I understand base64 is sufficient encryption, at least until the antimalware companies add signatures for base64-encoded scripts. Even then, the slightest customization of the original code is going to break base64 enough to avoid detection, whereas the signatures are flexible enough to handle variations to source code.)
msg269600 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2016-06-30 16:47
> But in that case, why hook into exec? The malware author can execute 
> arbitrary Python so doesn't *need* exec.

As I understand it, the malware is distributed in encrypted form (probably encrypted differently each time it propagates) so as to be given a green-light by anti-malware software, then decrypted and run via exec so that the bad code is never actually on disk, and thus never scanned.  Yes, the attacker can run arbitrary Python code, but if he just distributed the code in plain text, it could be detected and blocked.  The unpacking code is simple and generic enough that it can't be blocked.


As far as actually enabling AMSI, I'm +0.  I don't understand it well enough to be +1, and I share Paul's concerns about startup overhead.  I'm also unsure that AMSI actually affords any protection: what's to stop the attacker from distributing their own interpreter that just doesn't use AMSI?
msg269606 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-30 17:20
> what's to stop the attacker from distributing their own interpreter that just doesn't use AMSI?

AppLocker https://technet.microsoft.com/en-us/library/ee619725.aspx

(In short, restrict which executables can be run on a particular system by path/certificate/etc.)

Also a combination of ACLs and the fact that they may not be able to copy files onto the system directly anyway - see my post just before yours.
msg269607 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-06-30 17:25
And in case it's not clear, I *totally* recognize that AMSI is not for everyone. If you're running in a developer environment, your security is almost certainly so lax that it's irrelevant.

However, once you start getting serious about what's deployed on your production machines, Python gets ruled out very quickly because it lacks features like AMSI. Sysadmins don't want to enable a potential attack tool unless it's value drastically outweighs the risks (and on Windows, this is generally/currently not true), or there is sufficient insight into the behavior and use of the tool.

If we want Python to be seen as a production tool and not just a developer tool (which I do), we need to address these concerns.
msg269622 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2016-06-30 19:44
Thanks for the explanation. Based on what's been said, I'd have no objections to this, on a "you don't pay for what you don't use" basis - i.e., users who don't enable AMSI should not pay any cost for its existence.

I'd be extremely happy if Python was viewed as a high-quality option in the server management space, so if this helps in that goal, then that's good.
msg269712 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-07-02 13:59
It's not just Stuxnet, as at least one other Advanced Persistent Threat uses that tactic. An APT (likely Russian intelligence) recently used encoded PowerShell to break into the Democratic National Committe: https://www.crowdstrike.com/blog/bears-midst-intrusion-democratic-national-committee/

From that article:

> This one-line powershell command, stored only in WMI database, establishes an encrypted connection to C2 and downloads additional powershell modules from it, executing them in memory.

(As a fun coincidence, they also used py2exe to distribute other modules, which is kinda like a separate interpreter using safe_exec)
msg269713 - (view) Author: Alexander Riccio (Alexander Riccio) * Date: 2016-07-02 14:00
We might want to use some kind of Group Policy setting, for the same reason that many Windows security configuration options are there, and that DoD STIGs for Windows https://www.stigviewer.com/stig/windows_8_8.1/ are almost totally about configuring Group Policy settings.
msg275397 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2016-09-09 19:11
Would be nice to add this, but I have no immediate plans so I'm unassigning it.
History
Date User Action Args
2022-04-11 14:58:26adminsetgithub: 70325
2020-11-04 21:37:09brett.cannonsetnosy: - brett.cannon
2016-09-09 19:11:44steve.dowersetassignee: steve.dower ->
messages: + msg275397
2016-07-02 14:00:44Alexander Ricciosetmessages: + msg269713
2016-07-02 13:59:57Alexander Ricciosetmessages: + msg269712
2016-07-01 12:54:38thellersetnosy: + theller
2016-06-30 19:44:35paul.mooresetmessages: + msg269622
2016-06-30 17:25:43steve.dowersetmessages: + msg269607
2016-06-30 17:20:04steve.dowersetmessages: + msg269606
2016-06-30 16:47:22zach.waresetmessages: + msg269600
2016-06-30 16:43:44steve.dowersetmessages: + msg269598
2016-06-30 16:20:43paul.mooresetmessages: + msg269592
2016-06-30 15:35:37zach.waresetmessages: + msg269585
2016-06-30 15:17:10paul.mooresetmessages: + msg269583
2016-06-30 13:02:36steve.dowersetmessages: + msg269582
2016-06-30 10:04:07paul.mooresetmessages: + msg269570
2016-06-29 18:23:37steve.dowersetdependencies: + Call CoInitializeEx on startup
messages: + msg269538
2016-01-17 14:30:35steve.dowersetversions: + Python 3.6
nosy: + brett.cannon

messages: + msg258469

assignee: steve.dower
2016-01-17 10:07:07Alexander Ricciosetmessages: + msg258458
2016-01-17 09:50:46Alexander Ricciosetmessages: + msg258457
2016-01-17 09:49:03Alexander Ricciosetmessages: + msg258456
2016-01-17 09:44:11Alexander Ricciocreate