How to add content verification using hmac in PHP

Many times a requirement arises where we are supposed to expose an API for intended users, who can use these API endpoints to GET/POST data on our servers. But how do we verify that only the intended users are using these API’s and not any hacker or attacker. In this blog post, I will show you the most elegant way of adding content verification using hash_hmac (Hash-based Message Authentication Code) in PHP. This will allow us to restrict possible misuse of our API by simply issuing an API key for intended users.

Here are the steps for adding content verification using hmac in PHP:

  • Issue $private_key and $public_key for users allowed to post data using our API. You can use the method similar to one described here for generating public and private keys.
  • Users having these keys can now use following sample script (hmac-sender.php) to submit data:
            // User Public/Private Keys
            $private_key = 'private_key_user_id_9999';
            $public_key = 'public_key_user_id_9999';
    
            // Data to be submitted
            $data = 'This is a HMAC verification demonstration';
    
            // Generate content verification signature
            $sig = base64_encode(hash_hmac('sha1', $data, $private_key, TRUE));
    
            // Prepare json data to be submitted
            $json_data = json_encode(array('data'=>$data, 'sig'=>$sig, 'pubKey'=>$public_key));
    
            // Finally submit to api end point
            submit_to_api_end_point("http://yoursite.com/hmac-receiver.php?data=".urlencode($json_data));
  • At hmac-receiver.php, we validate the incoming data in following fashion:
            function get_private_key_for_public_key($public_key) {
                    // extract private key from database or cache store
                    return 'private_key_user_id_9999';
            }
    
            // Data submitted
            $data = $_GET['data'];
            $data = json_decode(stripslashes($data), TRUE);
    
            // User hit the end point API with $data, $signature and $public_key
            $message = $data['data'];
            $received_signature = $data['sig'];
            $private_key = get_private_key_for_public_key($data['pubKey']);
            $computed_signature = base64_encode(hash_hmac('sha1', $message, $private_key, TRUE));
    
            if($computed_signature == $received_signature) {
                    echo "Content Signature Verified";
            }
            else {
                    echo "Invalid Content Verification Signature";
            }
    

Where to use such verification?
This is an age old method for content verification which is used widely in a variety of applications. Below are a few places where hmac verification finds a place:

  • If you have exposed an API for your vendors to submit requested data
  • If you are looking to enable third party applications in your website. Similar to developer application model of facebook.

Hope you liked the post. Do leave your comments.
Enjoy!

Web Security : Using crumbs to protect your PHP API (Ajax) call from Cross-site request forgery (CSRF/XSRF) and other vulnerabilities

Have your API calls ever being used directly by someone without your permission? If yes, read on to find out how can we protect our API’s from such spammers and hackers. Before we go ahead and see a possible solution for this, lets try to list out a few cases, when our API’s can be accessed without our permissions.

Common cases of vulnerable API/Ajax calls

  • Ajax calls having no user authentication: This is the first place where a spammer will try to find out a loop hole. Take this example, suppose I created a group chat plugin for my blog. Since it’s a group chat plugin, I don’t really want the blog viewers to register before they can write a messages. Blog viewer only need to provide their name, email and url (just like wordpress comments). Thereafter, they can write messages which are submitted on the server side using ajax calls. And here is the “problem”. Anyone can pick up the ajax url, write a curl script, post the required parameters and fill up my database with millions of messages.
  • Ajax calls having user authentication: One day I realize my group chat plugin has received more than 1 million messages last night (all spams). Hence I decide to make my blog viewers to register before they can post a message on the group chat plugin, simply because someone is filling up my database by simulating ajax calls through a curl script. Anyone can write a script, since these ajax call do not authenticate the user making the call. But are my ajax calls safe after forcing users to register? NO, a registered user too can simulate these ajax calls and passing authentication by sending the right cookies.

Possible solutions and their flaws
If you look around on web, you will find a bunch of solution to such problems. But then every solution have it’s own problem which forces you not to use them. Listed below are 2 possible solutions to our problem:

  • Using X-Requested-With to protect ajax calls: All famous javascript frameworks like JQuery, YUI, Mootools etc sends an additional header parameter while making an XHR request. These libraries set “X-Requested-With=XMLHttpRequest” header, which can then be used on the server side to detect if the call was made through an ajax call. But a programmer can easily pass these headers using a curl script, making the server believe that the call was made through an XHR request.
  • Using HTTP Referrer: This solution comes in handy for cases when a spammer/hacker try to POST data into your site’s. We can check for the referrer page, before we go ahead and accept the POST data. If the POST data is coming from a page within your site, you go ahead and accept the data, otherwise reject it. But this solution again have it’s shortcomings. HTTP Referrer can be tampered in certain browsers using javascript and they can also be stripped away by some proxies and firewalls.

Using crumbs
Finally the idea is to have crumbs. A unique electronic key which is shared between server and client, and which have a short life time. But how are these useful? Suppose, in my group chat module, upon page load i generate a crumb whose life time is 30 minutes (tunable). Why 30 minutes? Because, I assume my blog viewers to either engage into the group chat module or leave that specific blog post within 30 minutes.

Now whenever a user writes a message, this crumb is passed back to the server side. If user writes a message before 30 minutes, this crumb will be validated and user shout submitted. (30 minutes should take care of 99.99% of the cases). In response, server api sends back the new crumb which should be sent back with the next ajax call.

Now when a spammer try to simulate the ajax request using curl calls, he will not be able to succeed because of the absence of the crumb. But he can capture the crumb from the site and simulate the effect, right? YES he can, but we can take care of this by reducing the life time of the generated crumb.

Generating crumbs using PHP
Here are the two functions, I use to generate and verify crumbs in PHP:

        // user for whom crumb is to be generated
        $uid = "mailsforabhinav@gmail.com";

        // usually $salt = DB_PASSWORD . DB_USER . DB_NAME . DB_HOST . ABSPATH;
        $salt = "abcdefghijklmnopqrstuvwxyz";

        function challenge($data) {
                global $salt;
                return hash_hmac('md5', $data, $salt);
        }

        function issue_crumb($ttl, $action = -1) {
                global $uid;

                // ttl
                $i = ceil(time() / $ttl);

                // log
                echo "Generating crumb at time:".time().", i:".$i.", action:".$action.", uid:".$uid.PHP_EOL;

                // return crumb
                return substr(challenge($i . $action . $uid), -12, 10);
        }

        function verify_crumb($ttl, $crumb, $action = -1) {
                global $uid;

                // ttl
                $i = ceil(time() / $ttl);

                // log
                echo "Verifying crumb:".$crumb." at time:".time().", i:".$i.", action:".$action.", uid:".$uid.PHP_EOL;

                // verify crumb
                if(substr(challenge($i . $action . $uid), -12, 10) == $crumb || substr(challenge(($i - 1) . $action . $uid), -12, 10) == $crumb)
                        return true;
                return false;
        }

I can generate crumbs with a simple call:

$crumb = issue_crumb(300, "group_chat_module");

where $ttl = 300 (required), $action = “group_chat_module” (optional, defaults to -1)

Later on I can verify the crumb using another call:

var_dump(verify_crumb(300, $crumb, "group_chat_module"));

I hope this helps you protecting your API’s. Let me know of better methods to stop such attacks.
Enjoy!

Warning for Google Chrome Users : Chrome’s ‘Save As’ Flaw Could Give Attackers Control

Bach Khoa Internetwork Security, a security-research firm in Vietnam, claims to be the first to discover a critical vulnerability in Google’s Chrome browser.

“This is the first critical Chrome vulnerability permitting [a] hacker to perform a remote code-execution attack and take complete control of the affected system,” the firm wrote in its Sept. 5 advisory. While four Chrome vulnerabilities were discovered, Bach Khoa said the “Save As” flaw is the only one that can allow an attacker to launch remote attacks from a victim’s PC. Other vulnerabilities just crash the browser.

The vulnerability is caused by a boundary error when handling the “Save As” function. When a user saves a malicious page with a title tag in the HTML code, the program causes a  stack-based overflow, according to Bach Khoa. A hacker could construct a specially crafted Web page that contains malicious code, trick a user into visiting that Web site, and
convince the user to save the page. That will execute the code and give the attacker privileges to remotely use the infected system.

A Google spokesperson said, “”We have released a fix to address this vulnerability. Users will get this fix through an automated update to the browser, so they will not have to take any action to be protected.”

Well I haven’t got any fix till now, atleast I didn’t see my Google Chrome updating atleast.

Read more on this news….

Gain admin access on windows system using your guest account

Hello All,

Ever thought of how to get into your friend’s system and see the access denied files and folders? Or ever wanted to hack into someone’s admin account? Well here is a method which exploits yet another windows bug.

  1. Have you ever noticed that if you press your system’s SHIFT key >= 5 times continuously a pop up windows occurs with the name “Sticky Keys”? If it doesn’t pop up on your comp, then may be your shortcut is turned off. For enabling it, goto Control
    Panel -> Accessibility Options
    . In the accessibility options under the
    keyboard tab, in sticky keys , click on settings and enable the
    shortcut for sticky keys. And u can do this even with a guest account.
  2. Finally if the following 2 requirements are setup on your system, then you are all set to enter into your admin’s account.
  • On Pressing SHIFT >= 5 times, a pop up should appear.
  • The windows System32 directory should be writable.

Concept:
When u press, the SHIFT key >= 5 times, a file with the name “sethc.exe” is
executed.  You can verify this in TASK manager (don’t close the pop up
window). This file is located in C:WINDOWSsystem32 folder, or
where ever your windows is installed.

The Vulnerability

  1. When SHIFT key is pressed >=5 times, windows executes a file named
    “sethc.exe” located in system32 folder. It doesn’t even check if its the
    same file. Also it runs with the privilege of the CURRENT USER
    which is executing the file i.e if u have logged on as a guest then in
    the TASK manager under processes, it shows your user name as guest.
  2. The file executes even if u log off, and have the windows login screen is
    showed up, BUT THIS TIME SINCE NO USER HAS LOGGED IN IT RUNS WITH
    SYSTEM PRIVILEGE.

Exploitation
If u understand this much, then the exploitation is very simple for you. What we will do is that,
we pick cmd.exe , copy it at a folder other than system32, (because windows
won’t allow u to copy) rename it to sethc.exe, go to system32 folder,
and paste it. Windows will ask, “that another file exists, do u want to
replace?” and after pressing OK, you have replaced the sethc.exe with ur own
cmd.exe. Now if u press SHIFT key >=5 times, a command prompt will
pop-up.


Finally

  1. Now log-off or restart. When you reach the windows
    login screen, press the shift key >=5 times. A command prompt will
    pop up with SYSTEM privilege.
  2. Enter the normal commands as follows:
  3. net user username /add
  4. net user localgroup administrators username /add
  5. And a new user called username with admin privilege will be added.

And thats it, you have admin privilege of the system and you can do what ever you want to with it.

Hiding your fake admin profile
Now you surely don’t want the real admin to track you. Here is what you will have to do to hide yourself from login screens as well as from control panel

  1. Goto registry editor and open this place.
  2. [HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWinlogonSpecialAccountsUserList]
  3. Here create a new DWORD value, write its name as the “user name” that u created for your admin account.

Thats it now you are invisible but still admin of the system. Live as admin forever and keep screwing the real admin forever.



Last but not the least (IMPORTANT)
Windows has two type of login screens:

  1. Where the accounts are listed with some pictures.
  2. Where u have to write username and password.

After making the hidden account u will have to login through the 2nd step only. If ur login screen is of Type 1, press ALT-CTRL-DEL twice to get the 2nd type screen.

Thats it!!!

NOTE:
This is a sureshot way to gain admin, if u r a lamer or a newbie
then please do some googling.
I have written almost every detail.

Thanks for reading this far 🙂 Make a comment if you liked this one.

Thanks for digging and shouting it out to your friends.