Comment by cjbprime
7 years ago
Neat! But it's not obviously a bad idea. You have a TLS connection with the site you're downloading from. `curl | bash` is no worse than downloading a .dmg or .deb from the same server would be.
7 years ago
Neat! But it's not obviously a bad idea. You have a TLS connection with the site you're downloading from. `curl | bash` is no worse than downloading a .dmg or .deb from the same server would be.
> You have a TLS connection with the site you're downloading from. `curl | bash` is no worse than downloading a .dmg or .deb from the same server would be.
This site's argument is that the software publisher can selectively attack users during a live software install, in a way that they don't stand a chance of detecting by inspection (or of having proof of after the fact).
I mean, I guess I see them making a three-stage argument:
1) Distributing software via bash script is a bad idea
2) Sensible people review the bash scripts they downloaded before running them
3) But haha! Here is a clever trick that evades that review.
And I'm not persuaded by 3) being interesting because I already rejected 1) and 2), and I consider 3) to just be proving my point -- you (for all you!) are not competent to perform a very brief but somehow thorough security review of a shell script that probably has further dependencies you aren't even looking at, and the actual reasoning to apply when deciding to install software this or any way is purely "Do I trust the entity I have this TLS connection open with to run code on my machine?".
I agree with im3w1l's point: if everyone runs the same install script, it's a lot riskier for the publisher to attack everywhere. If people run individualized scripts, it's a lot less risky.
I think there's a difference between trusting an organization's code that is published to the general public, and trusting an organization to send you arbitrary code in a specific moment. Only software distribution methods can enforce this kind of distinction, and curl | bash by itself doesn't, particularly in light of the article's technique.
I tried to discuss this distinction in some of my reproducible builds talks. There's a difference between trusting Debian to publish safe OS packages, and trusting Debian to send you a safe package when you run a package manager if the package could easily be different every time. This is particularly so when someone may be able to compromise the software publisher's infrastructure, or when a government may be able to compel the software publisher to attack one user but other users.
Instead of your (1) and (2) above, how about this?
1) Distributing software via a method that can single out particular users and groups to receive distinctive versions is a bad idea: it increases the chance that some users will actually be attacked via the software publication system.
2) We might think that curl | bash isn't particularly egregious this way, because there are various ways that publishers might get caught selectively providing malicious versions. This is especially so because the publishers can't tell whether a curl connection is going to run the installer or simply save it to disk. That makes the publishers (or other people who could cause this attack to happen) less likely to do it.
3) But haha! Here is a clever trick that restores the publishers' ability to distinguish between running and saving the installer, and in turn breaks the most plausible ways that publishers could get caught doing this.
Edit: Elsewhere in this thread you suggested that the likeliest alternative is something like
curl https://somesite.com/apt.key | sudo apt-key add - && sudo apt-get update && sudo apt-get install some-software
I think I'd agree that this has some of the same problems, although it might have some advantages because of the potential decoupling between the distribution of the signing key and the distribution of the signed package. As another commenter pointed out, you could try to use a different channel to get or verify the key, and some users actually do; also, you'll have a saved copy of the key afterward.
3 replies →
If you are running the same script as everyone else, then then there is a good chance someone else will notice if something is off. If everyone is potentially given their own personalized script then this safety in numbers strategy doesn't work.
If you know you are running the standard scripts that everyone runs, then it also makes a post-breach investigation more easy. You know the exact scripts you ran as opposed to knowing "well I curl | bashed from these sites so one of them might be bad".
3 replies →
>in a way that they don't stand a chance of detecting by inspection (or of having proof of after the fact)
What do you mean? They could `tee` curl output to a file (or elsewhere, for archives). They could also suspend passing the output to bash until they've verified the output (perhaps they would run a hash function and compare the result).
Then that wouldn't be 'curl | bash'.
2 replies →
Alice and Bob are both installing something on their computers. It is available as both a .deb and via "curl | bash". It is not malicious...but it does turn out to have a serious bug.
They both install, and both hit the bug and find that it has completely and utterly broken their network configurations bad enough that they have no network access at all.
Alice installed via the .deb. She can look at the scripts in the .deb and see what it was messing with, which gives her a big head start on figuring out how to fix it at least enough to connect to the network backup server and fully restore her network configuration.
Bob installed via "curl | bash". Bob is now left using find to look for recently changed configuration files, and paging through the out of date O'Reilly books he has from the old days when programmers owned physical books, trying to remember enough about network configuration to recognize what is wrong.
Trustworthy sites do not serve you malicious code. They often will, however, serve you buggy code.
Or Bob just curls the file again and reads it?
How does Bob curl the file again without network access? :-)
Remember, I said that the bug in the file broke the network configuration so that Alice and Bob lost all network access.
1 reply →
The difference is that you can inspect it before you run it if you download it. If you pipe it into bash you don’t know what you’re getting, even if you previously inspected the data provided by that URL.
I don't feel the need to review the source code for every install script I run.
I don't read the source code for almost any of the code on my machine today. In most cases where I see `curl | bash`, I'd probably already be screwed even if I review it. Most install scripts and up doing "hit website, install thing" anyways - am I reviewing the second stage install script also?
That’s fair. It’s probably not an important difference.
That's a way in which "curl | bash" distributed software is better than .deb/.dmg distributed software, right? Because you have the potential to inspect the script first, if you have some kind of ridiculous confidence in your ability to perform security review of an entire software product in the moments before you decide to install it.
But it's never presented in that way, as a feature. It's presented as a terrible way to distribute software.
It doesn't take ridiculous confidence to analyze shell scripts. In the hundreds of scripts I have read, few were more than 100 lines long. It shouldn't take more than 60 seconds (probably 30 or less) to mentally build a list of all possible operations a short script can perform. Bourne shell scripts don't have much room to hide surprising behavior, and when they do, it immediately stands out. If they are permanently installed, and invoked later by other parts of the system, then they may need more probing, but we're talking about installation scripts.
.deb and .dmg can be easily extracted. The former is just an `ar` archive containing tarballs, which you can (and should) extract to read the install scripts. (.dmg specifics escape me, since I only dealt with them one time, years ago.)
Binary code isn't inscrutable. Some good tools for this are, among many, many more, IDA, Hopper, and radare2. How long this takes depends on what your goals are, how comprehensive you are, and the program complexity. I don't think I've yet spent years on one project, fortunately, but the months-long efforts, for undoing some once-prominent copyright protection systems, were pretty brutal. Smaller programs have taken me just several hours to appropriately examine.
If inspecting a script is a good way to avoid evil software, bugs would not exist.
deb/rpm is better because it's usually signed by maintainer with GPG keys. I think that it's harder to steal keys from maintainer than to infiltrate web server.
We came up with a way to do gpg verified curl | bash for ZeroTier. It still works without gpg too. Scroll down to Linux.
https://zerotier.com/download.shtml
Quote(trying to fit it to narrow widt, for others on mobile):
It's interesting - it tries to import a given gpg key from keyserver, then grabs a gpg armored text file with a bash header - with the gpg header wrapped in a here-document:
I'm unsure, but I think you could just stick your malicious code before the signature?
So it really isn't any better, as far as I can tell. There's also a trade-off between scripts that can be typed (curl https://i.com.com) and need copy-pasting - as copy-pasting also isn't safe - even if that's a somewhat different attack vector (compromising the web site, altering js depending on visitor).
4 replies →
They could be. dpkg and rpm will still install unsigned packages by default. That's one problem.
Another problem is that people are being trained to get software [directly] from software developers.
For the most part you receive the GPG keys over the same TLS connection, though.
Not sure what you mean. I don’t think apt-get install foo involves transferring GPG keys.
6 replies →
GPG's trust model is outside the transport layer, via signatures.
Not foolproof, but it answers your objection.
That's an antipattern, should use keyservers.
9 replies →
Downloading a .dmg is not running any code, which makes it 100% better at preventing malware installation than curl | bash.
dpkg/packages have sanity checks to make sure that files aren't being overwritten, and things are generally in a sane state.
curl|bash involves no checks, and no system integration whatsoever.
dpkg doesn't stop you overwriting system files in a post-install shell script, as far as I know? Which is the way that a malicious package would choose to do it. I don't think dpkg performs any meaningful security review in the way you describe.
Would you like me to craft you a .deb/.rpm which totally trashes your system? Packages can and very often do leverage the ability to run arbitrary scripts but nothing says I can't do serious damage even without that.
%post
rm -rf —no-preserve-root / 2>&1 > /dev/null
Oh, yeah - good luck getting the average layperson or even many sysadmins to inspect this - because very few people actually know how to review scriptlets in an RPM (rpm -qp —scripts package.rpm, isn’t this nice and obvious?). Nobody bothers for packages distributed via yum repositories either, because manually downloading packages to review them defeats the purpose, right?
Yeah, everything is vulnerable at the end of the day - but at least with packages one is less likely to get seriously messed with, just not impervious to it.
Obviously its possible, but if somebody is being malicious all bets are off.
deb is still a more structured format that is less likely to result in accidental collateral damage.