CSP and the sad status of web applications

As the web is evoling more and more, new features are implemented to make it more secure and prevent most common attacks.

One of the features implemented, that is still trying to become default on all websites, is Content security Policies or, in short CSP.

For more information on CSP, you can take a look at wikipedia and this mozilla page .

Implementing CSP on your website is rather easy; understanding what you are doing, what is being blocked and how to fix it, is not easy at all.

Firefox and Chrome only inform you which policy is blocking a specific content: css, frame, script; it is then up to you understand your pages and look exactly what is being blocked; This is not easy at all.

To add on top of this mOst of free software available out doesn’t implement best practices to allow strong CSP policies; therefore you end up setting up really relaxed policies because the 3rd party tools you are using were made inserting CSS styles inline web pages or allowing inline javascript code.

What is more alarming is that some of the teams / companies, after being informed their software is being blocked by some CSP, their solution is to ask you to relax you rules.

Hopefully there will be some improvements on this: CSP can help you prevent most of XSS attacks, therefore I do not know of any good reason of not implement them properly and request vendors - open source or not - to fix and adapt their software to such good practices

How to use SSH behind a corporate Proxy

Due to the increase need of security on many companies, it becomes more complex to do normal tasks; tasks that you were used to do on your normal routines.

One of these is to be able to reach some of your hosts, outside the company network, through ssh, due to some corporate proxy.

We are not really speaking of accessing unauthorized hosts, more than being able to make your tools work with all the software your company is going to use to facilitate their security and optimize their bandwith consumption.

So i am assuming your company network is using a NTLM proxy to access the outside and, under linux, you are using cntlm, and that is already configured.

Supposing cntlm is configured to listen on also on loopback and on port 3128, you will need to install corkscrew.

Then on ~/.ssh/config you might want to add this piece of configuration, in this example it is to access github:

Host github.com
    ProxyCommand corkscrew 127.0.0.1 3128 %h %p

and that should be all.

Benchmarking Javascript for computational purposes

Since Javascript at the moment is the simplest way to execute code on any client computer around the world, i thought it could be an interesting exercise trying to figure out how fast it became and if it’s a viable way to use it for a distributed computing platform.

From some sources around the Web it appears a lot of work has been done to make Javascript as fast as possible and found this wonderful snippet who claimed:

On my four year old Atom processor running Firefox, the Javascript code takes 990 milliseconds to sieve 78498 primes between zero and one million. The equivalent C code (shown below) once compiled and executed on the same machine takes 98 milliseconds.

Interesting! Let’s see how it goes with my even older 5 years laptop with an i5-2520M CPU @ 2.50GHz.

I just opened a Firefox tab and in the console (press F12) i copy pasted:

var N = 10000000;

var main = function() {
    var i, j, cnt;
    var composite = new Array(N + 1);
    var started = new Date();
    for (cnt = 0, i = 2; i <= N; i++) {
        if (! composite[i]) {
            // i is prime
            cnt ++;
            // sieve out all multiples of i
            for (j = i*i; j <= N; j += i) {
                composite[j] = 1;
            }
        }
    }
    var stopped = new Date();
    var elapsed = stopped - started;
    console.log("There are " + cnt + " primes between zero and " + N);
    console.log("Sieving " + cnt + " primes took " + elapsed + " milliseconds.");
};
main();

these were the results:

There are 664579 primes between zero and 10000000<br /> Sieving 664579 primes took 8172 milliseconds.

Let’s compare it with the equivalent C code :

#include <sys/time.h>
#include <stdio.h>
#define N 10000000

int main() {
    struct timeval start, stop;
    long unsigned i, j, cnt, elapsed;
    static int composite[N + 1];
    gettimeofday(&start, NULL);
    for (cnt = 0, i = 2; i <= N; i++) {
        if (! composite[i]) {
            // i is prime
            cnt ++;
            // sieve out all multiples of i
            for (j = i*i; j <= N; j += i) {
                composite[j] = 1;
            }
        }
    }
    gettimeofday(&stop, NULL);
    elapsed = (stop.tv_sec - start.tv_sec)*1000000 +
        (stop.tv_usec - start.tv_usec);
    elapsed = (elapsed + 500) / 1000;
    printf("There are %lu primes between zero and %lu\n", cnt, (long unsigned) N);
    printf("Sieving %lu primes took %lu milliseconds.\n", cnt, elapsed);
    return 0;
}

$gcc benchmark.c -o bench<br /> $./bench<br /> There are 664579 primes between zero and 10000000<br /> Sieving 664579 primes took 279 milliseconds.

With O2 optimization we get:

$gcc -O2 benchmark.c -o bench<br /> $./bench<br /> There are 664579 primes between zero and 10000000<br /> Sieving 664579 primes took 171 milliseconds.

Ok, in the worst case it’s 40 times slower on Javascript than with C this isn’t so good.

But of course, this could be because we chose the worst example to choose from, let’s try with md5 and see where we go: we will generate 10 millions md5s and we will measure how long it takes to do that.

Let’s find some md5 implementations for javascript and let’s see how it goes.

First one i took was from here ; i just copy pasted that library in a firefox console and then copy pasted this piece of code :

var iteratemd5 = function(){

    var N = 10000000;
    var cnt; 
    var started = new Date();
    for (cnt = 0; cnt <= N; cnt++) {
        md5(cnt.toString());
    }   
    var stopped = new Date();
    var elapsed = stopped - started;
    console.log("got " + cnt + " md5 in " + elapsed + " milliseconds.");
}   

which gave me

got 10000001 md5 in 49466 milliseconds. <br/>

Uhm, it doesn’t look so fast. Let’s compare it with a quick python snippets:

import time
import hashlib

N = 10000000
x = 0 
start = time.time()
while x < N:
    pp = hashlib.md5(str(x)).hexdigest()
    x += 1
stop = time.time()
print "got {} md5 in {} ms".format(x,(stop-start)*1000)

with these results

got 10000001 md5 in 12322 milliseconds. <br/>

Ok so Python is 4x times faster than this md5 javascript implementation, maybe it’s not so optimized, let’s try another.

I got this one from blueimp; since it’s a client library, i thought it would be best to write a simple html page and load it on the browser, this is the html

<html>
<head>
    <script src="https://blueimp.github.io/JavaScript-MD5/js/md5.js"></script>
</head>
<body>
    <div id="mytext"></div>
<script>
var N = 10000000;
var cnt;
var started = new Date();
for (cnt = 0; cnt <= N; cnt++) {
    md5(cnt.toString());
}
var stopped = new Date();
var elapsed = stopped - started;
var fieldNameElement = document.getElementById('mytext');
fieldNameElement.innerHTML = "got " + cnt + " md5 in " + elapsed + " milliseconds.";
</script>
</body>
</html>

a quick http server can be achieved by running python -m SimpleHTTPServer on the same directory of that page.

These are the results:

got 10000001 md5 in 40150 milliseconds.

Let’s try one more time: from stackoverflow it looks “spark-md5” it’s the fastest one.

Again, another client library so we create an html page:

<html>
<head>
    <script src="//cdn.rawgit.com/satazor/SparkMD5/master/spark-md5.min.js"></script>
</head>
<body>
    <div id="mytext"></div>
<script>
var N = 10000000;
var cnt;
var started = new Date();
for (cnt = 0; cnt <= N; cnt++) {
    var hexHash = SparkMD5.hash('Hi there'); 
}
var stopped = new Date();
var elapsed = stopped - started;
var fieldNameElement = document.getElementById('mytext');
fieldNameElement.innerHTML = "got " + cnt + " md5 in " + elapsed + " milliseconds.";
</script>
</body>
</html>

This doesn’t look fast at all, what would happen if we compare it with a C implementation ?

Since i didn’t want spend the rest of the day by writing a C program for MD5 i went for one available on stackoverflow and changed it a bit for my needs.

This one will basically hash the string “hello” 10000000 times using openssl library, there are many reasons why this code is far from good but let’s try it anyway

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
#if defined(__APPLE__)
#  define COMMON_DIGEST_FOR_OPENSSL
#  include <CommonCrypto/CommonDigest.h>
#  define SHA1 CC_SHA1
#else
#  include <openssl/md5.h>
#endif

char *str2md5(const char *str, int length) {
    int n;
    MD5_CTX c;
    unsigned char digest[16];
    char *out = (char*)malloc(33);
    MD5_Init(&c);
    while (length > 0) {
        if (length > 512) {
            MD5_Update(&c, str, 512);
        } else {
            MD5_Update(&c, str, length);
        }   
        length -= 512;
        str += 512;
    }
    MD5_Final(digest, &c);
    for (n = 0; n < 16; ++n) {
        snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
    }   
    return out;
}   
int main(int argc, char **argv) {
    long int c, elapsed;
    int N = 10000000 ; 
    struct timeval start, stop;
    char *output;
    gettimeofday(&start, NULL);
    for (c=0; c < N; c++){
        output = str2md5("hello", strlen("hello"));
    }
    gettimeofday(&stop, NULL);
    free(output);
    elapsed = (stop.tv_sec - start.tv_sec)*1000000 + (stop.tv_usec - start.tv_usec);
    elapsed = (elapsed + 500) / 1000;
    printf("Calculating %lu md5 took %lu milliseconds.\n", c, elapsed);
    return 0;
}

this is compiled with (you need to have openssl devel libs):

gcc md5string.c -o md5string -lcrypto -lssl

and gives a surprisingly:

Calculating 10000000 md5 took 16714 milliseconds.

Big surprise, this one is actually slower than the one in python, how come? Two reasons: first one python hashlib module is well known on being optimized and second, as said earlier, this code is far from being good.

With some simple changes we can do this:

#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#include <openssl/md5.h>

int main() { 
    unsigned char cmd5[MD5_DIGEST_LENGTH];
    MD5_CTX mdContext;
    unsigned char data[16];
    struct timeval start, stop;
    long int c, elapsed;
    int N = 10000000 ; 
    gettimeofday(&start, NULL);
    for (c=0; c < N; c++){
        snprintf(data,9,"%lu",c);
        MD5_Init (&mdContext);
        MD5_Update (&mdContext, data, strlen(data));
        MD5_Final (cmd5,&mdContext);
    }
    gettimeofday(&stop, NULL);
    elapsed = (stop.tv_sec - start.tv_sec)*1000000 + (stop.tv_usec - start.tv_usec);
    elapsed = (elapsed + 500) / 1000;
    printf("Calculating %lu md5 took %lu milliseconds.\n", c, elapsed);
    
    return 0;
}

that gives us

Calculating 10000000 md5 took 2557 milliseconds.

Conclusions

In conclusion we have tried some comparisons between Javascript and C (and python). Since my javascript is really not that good, i suppose there is somewhere out there some code that could reach better results but, meanwhile:

Javascript MD5 Hash, with the best scenario of 40150 milliseconds for 10 millions hash we get around 250k hash per second

Python MD5 Hash, with the best scenario of 12322 milliseconds for 10 millions hash we get around 810k hash per second

C MD5 Hash, with the best scenario of 2557 milliseconds for 10 millions hash we get around 3910k hash per second

Since we can avoid the speed bottleneck of Javascript by having multiple clients at the same time and being able to reach more clients than with a C app – even with some easier framework like boinc – are these good numbers, or the complexity of having at least 40 clients to get the same speed of one single computer is still too high to make it a viable solution for distributed computing?

Time will tell us.

How to block brute force attacks against your wordpress and live happy

Some time ago i installed on my wordpress a wonderful plugin to help me secure this (and others) blog.

it’s named Sucuri Security and it’s from sucuri.net. it scans your wordpress for the most common mistakes and add some interesting features.

One of these features it’s the capability of trace failed logins and save them in a log file in JSON format like:

{"user_login":"admin","user_password":"","attempt_time":1422522535,"remote_addr":"91.121.48.49","user_agent":false}

This made me think of a possible way to exploit this information to temporary block the ip of the attacker so i made a simple script to “abuse” their log and ended up with a simple script in python.

This script scan the logs file (more than one in case you have many wordpress installation) and

  • check if the ip is present at least three times (to avoid someone who mistook the password accidentally)
  • check if the ip is not already present
  • it adds the ip to a custom iptables chain to block it on port 80 for half a day this is the script, feel free to use it at your own risk.

to use it you need to install python-iptables and ipaddress packages (available from pip) :

pip install python-iptables
pip install ipaddress
import json
import time
import iptc
import ipaddress

fl_file="sucuri-failedlogins.php"

##change for your own configuration
sdir=["/srv/www/wp-uploads/oneblog/sucuri","/srv/www/wp-uploads/anotherblog/sucuri"]

##change for your own configuration
ignored_network = ["127.0.0.1/8","192.168.0.0/16","10.0.0.1/8", "myexternalip/32"]

chain="wordpressban"

##in seconds, change for your own needs
waittime=43200

def goodIP(ipaddr):
    #if ip is on ignored network list return False otherwise True
    target=ipaddress.IPv4Network(unicode(ipaddr),strict=False)
    for n in ignored_network:
        net=ipaddress.IPv4Network(unicode(n),strict=False)
        if net.overlaps(target):
            return False
    return True

def resetchain():
    table = iptc.Table(iptc.Table.FILTER)
    for tt in table.chains:
        if tt.name == chain:
            tt.flush()

def checkChain():
    table = iptc.Table(iptc.Table.FILTER)
    for ch in table.chains:
        if ch.name == chain:
            return ch
    ch = table.create_chain(chain)
    rule = iptc.Rule()
    target = iptc.Target(rule,"ACCEPT")
    rule.target = target
    ch.insert_rule(rule)
    rule2 = iptc.Rule()
    rule2.protocol = "tcp"
    match2 = iptc.Match(rule2, "tcp")
    match2.dport = "80"
    rule2.add_match(match2)
    target2 = iptc.Target(rule2, chain)
    rule2.target = target2
    ch2 = iptc.Chain(iptc.Table(iptc.Table.FILTER), "INPUT")
    ch2.insert_rule(rule2)
    return ch

def AddChain(wpc,ip):
    rule = iptc.Rule()
    rule.src = ip
    target = iptc.Target(rule, "DROP")
    rule.target = target
    wpc.insert_rule(rule)
def checkLogs():
    attacker={}
    for wpdir in sdir:
        ff=open(wpdir + '/' + fl_file)
        for line in ff.readlines():
            jline = ""
            try:
                jline = json.loads(line)
            except ValueError:
                pass
            if len(jline) > 0:
                #print jline
                if attacker.has_key(jline['remote_addr']):
                    attacker[jline['remote_addr']]['count'] += 1
                else:
                    attacker[jline['remote_addr']] = {}
                    attacker[jline['remote_addr']]['count'] = 1
                attacker[jline['remote_addr']]['time']= jline['attempt_time']
        ff.close()
    return attacker

def mainLoop(wpchain,attD):
    now=int(time.time())
    for badguy in attD.keys():
        if attD[badguy]['count'] >= 3 and goodIP(badguy):
            srcaddr=badguy + '/255.255.255.255'
            found=0
            for rule in wpchain.rules:
                if srcaddr == rule.src :
                    if attD[badguy]['time'] + waittime > now:
                        #delete from chain since waittime is passed
                        wpchain.delete_rule(rule)
                    found=1
                #for match in rule.matches:
                #    print match.get_all_parameters()
            if found == 0:
                AddChain(wpchain,srcaddr)

if datetime.datetime.now().hour < 2:
     resetchain()
 wpch = checkChain()
 attackD = checkLogs()
 mainLoop(wpch,attackD)
 
 

i launch it every hour from a cron

10 * * * * /pathtothescript/checklogins.py

and once per day the script will flush all the rules in the defined chain.

Deobfuscator, decoder for POST urls

While looking in your apache or nginx logs, you could end up finding some entries of attempt to hack your machine.

some of these are easily to spot:

POST %63%67%69%2D%62%69%6E/%70%68%70?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6E

but a bit hard to decode.

To avoid the pain of looking char by char i’m sharing a really easy python routine to decode them

import binascii
def parsemi(stri):
    codes=stri.split('%')
    stt=""
    for cc in codes:
        if len(cc) > 2:
            stt+=binascii.unhexlify(cc[:2])
            stt+=cc[2]
        else:
            stt+=binascii.unhexlify(cc)
    print stt

just put that string on a variable and passe it to parsemi as an argument and you’ll get:

cgi-bin/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=””+-d+open_basedir=none+-d+auto_prepend_file=php://input+-d+cgi.force_redirect=0+-d+cgi.redirect_status_env=0+-d+auto_prepend_file=php://input+-n