20 comments

[ 4.4 ms ] story [ 48.8 ms ] thread
This project was built during Defcon Israel's recent 24 hour hackathon. Any feedback would be appreciated.
I have a question. Can you do this with Java/C#/Ruby/Javascript etc? What makes this so special?
It makes installing random things from PyPi more of an issue of trust (though it has always been this way, even people didn't realize it).
Exactly. When you install my package, I can infect other packages and have them execute arbitrary code without you realizing it. This is by no means unique to python, and in fact can happen whenever you run any program. It just shows the dangers of running things you don't really trust. Doing this in python is, however, slightly harder to detect, as you are changing the pyc file and not the py file itself. Someone who looks at the source will notice nothing amiss, and in fact if the update the source the pyc will be rebuilt cleanly (until it gets reinfected). Javascript and ruby are not generally byte-compiled and so you would have to change the source to infect them. Other languages that compile either to bytecode or executables can be just as easily be infected.
The real way to make it undetectable would be to somehow distribute your package so that its own .pyc file has the code to infect others, but the source file doesn't. Otherwise, it just takes a glance at the code to see what's going on.
For ruby you could likely do something similar using rubinius which can precompile .rb files to .rbc files prior to execution.

Though they discourage the use of the .rbc files directly so not sure this is much to worry about as they change the bytecode format often enough.

It doesn't make it more of an issue. Installing any Python package already requires "arbitrary code execution" -- which is the big problem with Python packaging. (And hopefully will be fixed by distutils2 which uses a setup.cfg to install packages rather than relying on executing setup.py.)
How is the setup.py any different than say, Perl's Makefile.PL files?
Yeah but I bet the thread owner wouldn't be the first person the implement a trojan to infect pyc files would he? If someone reeeeally wanted to mess up Pythonista's karma they'd have done some MITM attacks infecting the eggs a long time ago.

Seriously, when is PyPI going to serve behind SSL? Oh wait, that's not secure too. Nevermind.

Signed .eggs (can be handled just like signed rars) and .pyc files would be a feasible and proven way to address this. Sure, even that can be subverted if the private key is compromised, but at least a random trojan can't infect it anymore.
How do u propose PyPI or the package maintainers/users deal with key exchange? I'm not aware of anything that allows u to sign Python code now, at least not commonly used anyway. Python's state of packaging is kinda sad really. It's even worse then Javaland.
In the same way as the android store, for example; force package maintainers to sign their packages before uploading. This can be done with a self-signed key, as long as the signature proves the files originate from the maintainer.

Of course, tooling for this would have to be written, or maybe even the jar-signing tools could be used (as eggs and jars are both zip files with metadata).

I'm not sure how this would work as I have no experience with the Android App Store so I could be really wrong here but please do correct me.

AFAIK, a typical code signing process required these steps:

1) Get a cert/key whatever, you can generate your own or some server can generate it for you. As long as both of you trust it, it's ok. 2) You sign your code and upload it to the server 3) When a client requests for the code, the client establish a secure channel with the server and then the server will send the key over with the data to the client. The client decrypts it. If you do this, the cert/key is usually generated by the server. 4) Or the key is somehow stored on the client side beforehand. This is logistical nightmare and potential security hole if the key is properly protected.

Since no sane person will choose 4) to distribute Python packages you can download from PyPI, you are stuck with 3). Guess what. You still need SSL. Am I wrong here, did I miss anything?

Hey, my point was not that SSL is not needed. By all means, convert the whole web to SSL!

I was just trying to propose a way to make the PyPi repository somewhat more secure by making sure the maintainer signs the packages. This increases security somewhat (for example, if the server is compromised) in addition to SSL.

Good packagers should only be uploading Python source, not compiled bytecode or eggs.
BTW, I think people should set up their own trusted local cheeseshop and only install from there if security is a big issue for them. I heard Morgan Stanley is using a lot of Python now. I wonder how they deal with this. AFAIK there's not any decent alternative PyPI implementations out there. I'm using DjangoPyPI but man that is a POS.
why not infect .py files directly?
Because in general you're more likely to check and/or update the .py files than .pyc files, I'd say.

Btw, a nice (GUI) tool for examining/disassembling pyc files is: http://code.google.com/p/pychrysanthemum/ (it supports all the different python and bytecode versions without having to mess around with opcodes.py files...)

more likely, as 10^-20 is more likely than 10^-30?

when was the last time you have read python files of installed 3rd party software to find viruses and trojans?

and even if you bothered, by simple obfuscation you would need to be an expert to identify a trojan in a python file.

In addition a simple way to find or clean up such a virus would be to compile .pyc files from their sources during a virus scan.

in short that can't be the reason.

This Trojan requires the ability to execute arbitrary code and write to files - so it's not in itself any kind of exploit. It's just malicious Python code.