One criticism of Windows was folks being encouraged (by websites) to download custom .exe file to Desktop and double click.

In response to this, a wave a security products and some access control changes, put a stop to that.

Some users missed the convenience.

Could this ever happen on Linux / Unix?

Yes!

Here is an extract from the install instructions for a Google publicised project:

curl -L get.yeoman.io | bash

Seems the nix community is in too great a hurry to put convenience before security.

I point out some of the reasons why not in the next section.

Internet pipe to Bash – why not?

To suggest such an install procedure, is to ignore many of the security lessons from the past decade.

Possible risks 1: Fat fingered redirect

By advising the user invoke curl with -L flag, the developer is encouraging users to trust any locally coded redirection.

The reason curl advises of redirection is to allow the end user to verify any redirection themselves rather than trusting what redirection is entered at the remote site.

What would happen if a bogus redirect was inserted by mistake, or by a malicious insider? If it only happened for an hour would the company think it important enough to inform the developer population?

Possible risks 2: Shifting sands

Exactly how do you personally know that the code that was there yesterday is the same code as today?

Does it come in a package with checksums and a well understood inbuilt verification of checksum feature?

Can you manually download a verification checksum from a different mirror server, than the actual code download?

Possible risks 3: Compromised server

Compromised servers are always a risk for any internet hosted software.

Hosting code through acceptance in a distribution like Debian or Red Hat, allows a small company to leverage the infrastructure provided.

It also elevates untrusted software somewhat, due to the integration build process, qa review, and hosting infrastructure which such distributions provide.

Bitbucket, Gitorious, Google code and Github offer some minor improvement from self hosting a project yourself.

Then there is Pypi, CPAN, and other convenience collections, which whilst not offering massive assurance, at least mitigate the next problem described.

Possible risks 4: Dns hijack / redirection

Dns cache poisoning is all too common unfortunately.

Whilst this project is getting some backing from Google, it would be unwise to assume that it (and any mirrors?) employ DNSSEC to mitigate Cache poisoning. If they did employ DNSSEC effectively, would that be on the original http endpoint or the redirected http endpoint?

Commentary and other examples:

In fairness to the developers, there are some additional install notes, and in particular there is some hints for Debian / Ubuntu folks that include this line:

sudo npm install -g yeoman

However, those install instructions also suggest at the start, that you should still do an initial pipe bash, in case you had a previous install present.

Doing that initial pipe bash, then switching to more traditional package management techniques, does not mitigate any of the risks described earlier.

It may be that developers are being encouraged to do this sort of hacky curl stuff by seeing this entry from the npm site:

curl https://npmjs.org/install.sh | sh

The observant amongst you will notice that there is no -L flag here, so strike off one of those risks listed earlier.

What comes after the pipe symbol ( | )? Does that make any difference from the other example?

That answer is left as an exercise for the reader.

Further examples (added after article first written):

Advertisements

Chkrootkit and other tools that scan for rootkits sometimes report a python related ‘.path’ file as suspect.

Example:

/usr/lib/pymodules/python2.6/.path

The script/binary responsible for creating that file is /usr/sbin/update-python-modules

from the Debian & Ubuntu package python-support

code extract from /usr/sbin/update-python-modules

There is no harm in understanding how to adapt chkrootkit or alternatives to ignore a list of locally recognised false positives, however some might consider this ‘false positive’ a bug.

Security is a mindset, rather than any single action

My opinion. Swill it around a bit … do you agree?

Layers and lack of control:

A new starter is given access to live servers and asked to code up some simple shell scripts, to automate a bit of hosting setup and/or cron tasks.

#!/bin/bash

Not having deep experience with Ubuntu Servers, the new starter immediately dives in and tries to write scripts that use the extended (non posix) features of the bash login shell.

Bash Arrays or let count=count+1 are examples.

So the task progresses and the bashisms are in.

Another task is taken on and completed again using bash extensions similar to those mentioned above.

Now another administrator is asked to add those tasks to a daemon process or startup script.

But the scripts don’t work!

Hacker Solution: Change the default system shell from /bin/dash to /bin/bash

task1, task2, ..., use in daemon/cron

What is highlighted in Red are the human failings.

The creation of a daemon process / cron should not trigger a policy change on a server.

There are several good reasons why Ubuntu switched to dash as the default shell over 5 years ago.

From my personal point of view, bash is too complex, and is better suited to the task of a ‘login shell’ rather than a ‘system shell’ / ‘process shell’

The more complex a piece of software…

  • the more likely a new security hole can be found
  • the more likely a move of versions will result in breakage

The phrase “Keep it simple stupid” feel appropriate here.

Human failings – how could this happen?

The intricacies of posix standard shell scripts are not the first thing a new Linux System Administrator will learn.

Should they be? Well that depends on whether you see certification as important

Pushing your new Linux System Administrator to become Red Hat (RHCE) certified, is one way of introducing them to standards and the context of operational tasks

Here is an unofficial introduction to the sort of thing that RHCE might expect.

How many years into Linux System Administration should the Administrator know about the Single Unix Specification? It all depends on your organisation and how you wish to operate.

In most organisations, the implementation of a new daemon / startup task could never trigger a policy change at the server level.

Some organisations that have no firm security policies and no configuration management documentation, might well fail to stop the actions accompanied by red indicators in my diagram.

This is an organisational / human failing and has nothing to do with the specifics of the technology. It could interchangeably be Linux, or Solaris, or Windows that lacked the human controls to prevent such a change.

Bash is secure – it is rare that there are any new exploits:

Bash changes infrequently (which is good), and most exploits in the last 10 years have been around insecure temporary file creation.

That does not mean that using a non-interactive shell (/bin/dash) is unnecessary, if you need interactive features and feel lost without non-posix bashisms, then do use bash as your login shell.

From experience, the folks who use the more intricate / esoteric features of bash, are usually lacking in knowledge of sed / awk / python.

Using bash to do serious scripting (string processing in particular) is not too different than, using a hammer to knock in a screw. It’ll work, but there are better tools for the job.

Links and Further Reading:

Having recently taken delivery of a new VPS, I logged on and immediately set about, securing the setup.

Changing the root password sounds obvious, but there are alternatives:

  • Blocking root access via ssh.
  • Turning off password authentication and using known keys only.

Doing either of the above might have you thinking that the strong password the datacentre setup for you can now stay – but wait!

VPS, cloud servers, and some dedicated servers are often provisioned from templates.

Those templates may have set the password early in the build process, before secure hashing was fully configured.

 

At a glance – is the root password in /etc/shadow sufficiently hashed?

Here is an example which shares some characteristics with what I found on my newly provisioned server:

root:Npge08pfz4wuk:15000:0:730:7:::

If you are accustomed to working with /etc/passwd and /etc/shadow, you will have spotted the problem already …

The second field is way too short!

It should instead look something like this:

root:$6$OBEzW/iiKRe/ww$vfnfEFg41l1dK4zE4YM9PiRKs7ic5lvg1WgFWgi.VF0O/MYCZPELqedCmSybFQ5.0twYbc1fU6VnXqdACqELj0:15000:0:730:7:::

The second field beginning $6 indicates that the password has been hashed using SHA2 (512), often abbreviated to sha512

If you just want to printout the shadow password entries for those users that can login then use this command:

egrep -v '.*:\*|:\!' /etc/shadow | awk -F: '{print $2}'

and just double-check that all lines output begin $6

If not, then issue a passwd command and input a new password for the problem user (root or otherwise)

Providing your system is not outdated the proper sha512 hashing should be in place. When you regenerate the password with passwd, you should now see the second field in /etc/shadow a lot wider, and no longer a security issue.

 

The third field in /etc/shadow – pre-populated for you during build:

Days since Jan 1, 1970 that password was last changed

That third field will probably be set to 15000 or a number of that magnitude.

Too large a number would see ‘in future’ complaints being registered in a log file in /var/log/

 

Links and Further reading:

The link below gives an example of using mkpasswd to fix things.

However do be aware that echoing passwords to pipe into a secondary command is not considered ideal, due to the process details being visible in plain text to other users who might be running ‘top’

Python can also be used to generate replacement passwords – although again be careful what might be viewable by other users whilst your process is running:

python -c "import crypt, getpass, pwd; print crypt.crypt('passwordunhashed', '\$6\$SALTsalt\$')"