I was surfing on the net and i was looking for a responsive / easy-to-use CMS framework in order to bringing my blog to life! with a bit of luck i found a CMS called NibbleBlog, it was XML based (nice feature!), lightweight and easy-to-use...so it was jsut perfect in order to start a blog!
Since i'm a security researcher before put anything on my server i want always perform a vulnerability assessment in order to better know how secure it was :D, after some hours of researching and much false positive i found a really intresting feature called blacklist, it allows to block certain client by ip address, it's a very useful feature to prevent spam.
Where troubles begins
As any other modern CMS NibbleBlog was provided with a Dashboard used by the Administrator to edit/add/modify contents. this Dashboard was protected by authentication, below the code from login.class.php
* Verify the username and password are correct
public function verify_login($args)
// Check the file FILE_SHADOW=shadow.php
// Check empty username and password
// Check username
// Generate the password hash
$hash = sha1($args['password'].$_USER['salt']);
// Check password
$this->db_users->set(array('username'=>$args['username'], 'session_fail_count'=>0, 'session_date'=>time()));
// Set brute force
// Increment the failed count and last failed session date
$user = $this->db_users->get(array('username'=>$args['username']));
$count = $user['session_fail_count'] + 1;
$this->db_users->set(array('username'=>$args['username'], 'session_fail_count'=>$count, 'session_date'=>time()));
As we can see from the above code whenever admin try to login usign a bad password an integer is incremented and when it reach the value of 5 the blacklist is automatically triggered.
In order to ban a client NibbleBlog need to get the right IP from a client even if it's behind a proxy, this is done in the file net.class.php, below the code
This seems to be pretty secure due to the usage of filter_var function, anyway if we use a valid IP into X-Forwarded-For header we are able to spoof any random IP address!. Any unauthenticated user can trigger this piece of code, in order to succesfully exploit the attack we also need a valid ip address to spoof (why not the admin one!). NibbleBlog is shipped with a weak configuration which allow allow to spoof content of xml files simply by browsing them, below a real life example
The following content is reachable at /content/private/users.xml and contains all failed user login attempt even if they are not banned, now we all know that al least once we use the wrong password so you have a 50% chance that admin ip address is there!
With all of these info in mind we can start our attack, in order to do this we must try to login 6 times with a bad password using header X-Forwarded-For with a spoofed IP like below
POST /admin.php HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:40.0) Gecko/20100101 Firefox/40.0
Accept-Encoding: gzip, deflate
After the fifth request we will se the following message, this means that the
attack was successful! Nibbleblog security error - Blacklist protection
The fix for this vulnerability is pretty easy, just modify the following lines