SMSA - Short Message Service Authentication - (updated 2007-07-29)
|
Protection against... |
Detection... |
Ease to install |
User usage
(green=easy) |
|
funds transfert |
simple phishing |
MITM phishing |
ISP pharming |
trojan keylogger |
advanced trojan |
before-fraud |
after-fraud |
|
|
s1 |
s2 |
|
s1 |
s2 |
s1 |
s2 |
s1 |
s2 |
By user |
N/A |
|
|
Goal : protecting user from fraud transaction
Installed by : business lines and network teams
This solution is mainly of interest for big financial institutions, and
banking group. It will help your organization increase the protection
against fraudster, when the user wants to add a bank account to his
list of known and trusted bank accounts. Indeed most phishing case will
aim at creating this Graal since it will enable fraudster to accomplish
their theft.
Here, we will use the fact that almost everyone owns a mobile phone,
hence everyone is able to receive SMS. Using the phone, we have a
second communication channel beetween the bank and the customer and we
will be able to use this channel to exchange a random code used in the
bank account registration process. The main difficulty here is to
record the customer phone number through a secure channel (If it is
done at the account creation, it is even better).
Companies will have to decide whether they want to use their own SMS
gateway or delegate this service to an external service provider.
In this example, we will use an external SMS business provider, such as http://www.tm4b.com/.
Nevertheless, as it's a security feature, I'd rather advise to use a
proprietary SMS gateway since it will mitigate the risk from having the
token stolen by the SMS provider.
The idea is simple: we'll use the phone chanel (via SMS) only for
sending a small token to the customer, so that if an attacker already
owns the Web connection, he cannot retrieve the SMS that is received.

Solution 1: Use SMS token for bank account registration
In the bank account registration page, we have something like:
<?
$mysql_link=mysql_connect("server_location","user1", "password");
mysql_select_db("mydatabase",$mysql_link);
$query="SELECT random_code from users WHERE user_id=".mysql_real_escape_string($user_id);
$code_db = mysql_query ($query) or die (mysql_error ());
if ($code_db == 0) // This page is used for sending the SMS
{
srand ((int) ((double) microtime() * 1234567)); // If needed
$seed=rand (100000,999999);
$query="SELECT phone_number from users WHERE user_id=".$user_id;
$ret_phone = mysql_query ($query) or die (mysql_error ());
$query="INSERT INTO users (random_code) VALUES (".$seed.")";
$ret_code = mysql_query ($query) or die (mysql_error ());
$query='';
//Global parameters such as it is indicated in the 2.0 API
$param['username'] = 'our_identifier';
$param['password'] = 'our_password';
$param['version']='2.0'; // This value will depend which API you're using
//Client request parameters
$param['type'] = 'broadcast';
$param['msg'] = 'Code to record the BAN '.$ban.' is: '.$seed;
$param['to'] = $ret_phone;
$param['from'] = 'Website Name';
$param['route'] = 'GD02';
// Query
foreach($param as $key => $value) {
$query .= $key.'='.urlencode($value).'&';
}
$sms_url = "http://www.tm4b.com/client/api/http.php";
$ret = file_get_contents($sms_url.'?'.$query);
$subject="SMS sent for userid".$user_id;
$body=$ret;
mail(customer_relation@company.com, $subject, ""));
// Now we have to ask the customer for the code he received just on his phone
echo "<html>";
echo "<body>";
echo "please insert your received code here for adding BAN ".$ban." to your authorized BAN <BR>";
echo "<form method=\'POST\' action=".$_SERVER['PHP_SELF'].">";
echo "<input type=\'text\' id=\'code\'>";
echo "</form>";
echo "</body>";
echo "</html>";
}
else // code has been sent to user. This page is then used to verify code
{
$query="UPDATE users SET random_code=0 WHERE user_id=".mysql_real_escape_string($user_id);
$ret = mysql_query ($query) or die (mysql_error ());
if ($code_db == $code)
{
$query="INSERT INTO bans_table (id_user,ban)
VALUES
(\'".mysql_real_escape_string($user_id)."\',\'".mysql_real_escape_string($ban)."\')";
$ret = mysql_query ($query) or die (mysql_error ());
echo "<html>";
echo "<body>";
echo "Your code is valid. Your BAN has been recorded.";
// Write whatever you want here to redirect, continue....
echo "</body>";
echo "</html>";
}
else
{
echo "<html>";
echo "<body>";
echo "Your code is invalid. ";
// Write whatever you want here to redirect, disconnect....
echo "</body>";
echo "</html>";
}
}
mysql_close($mysql_link);
?>
Solution 2: Use SMS token for bank account registration + authentication
In this
case, we have a very good protection for all kind of phishing except
MITM sites which remains at yellow/orange level. Nevertheless, when
using MITM, if we write in the SMS the recipient account, the client
may be stupid if he is to accept something that does not match its
login.
The bank account registration page does not change.
In the identification page (after we have retrieved the "user id" but
before the client gives his password/token), we'll have something like:
<?
$mysql_link=mysql_connect("server_location","user1", "password");
mysql_select_db("mydatabase",$mysql_link);
$query="SELECT random_code from users WHERE user_id=".mysql_real_escape_string($user_id);
$code_db = mysql_query ($query) or die (mysql_error ());
if ($code_db == 0) // This page is used for sending the SMS
{
srand ((int) ((double) microtime() * 1234567)); // If needed
$seed=rand (100000,999999);
$query="SELECT phone_number from users WHERE user_id=".mysql_real_escape_string($user_id);
$ret_phone = mysql_query ($query) or die (mysql_error ());
$query="INSERT INTO users (random_code) VALUES (".$seed.")";
$ret_code = mysql_query ($query) or die (mysql_error ());
$query='';
//Global parameters such as it is indicated in the 2.0 API
$param['username'] = 'our_identifier';
$param['password'] = 'our_password';
$param['version']='2.0'; // This value will depend which API you're using
//Client request parameters
$param['type'] = 'broadcast';
$param['msg'] = 'Code to log in using '.$login.' is: '.$seed;
$param['to'] = $ret_phone;
$param['from'] = 'Website Name';
$param['route'] = 'GD02';
// Query
foreach($param as $key => $value) {
$query .= $key.'='.urlencode($value).'&';
}
$sms_url = "http://www.tm4b.com/client/api/http.php";
$ret = file_get_contents($sms_url.'?'.$query);
$subject="SMS sent for userid".$user_id;
$body=$ret;
//mail(IT_staff@company.com, $subject, ''));
// Now we have to ask the customer for the code he received just on his phone
echo "<html>";
echo "<body>";
echo "Please insert your SMS code here for log in <BR>";
echo "<form method=\'POST\' action=".$_SERVER['PHP_SELF'].">";
echo "<input type=\'text\' id=\'code\'>";
echo "</form>";
echo "</body>";
echo "</html>";
}
else // code has been sent to user. This page is then used to verify code
{
$query="UPDATE users SET random_code=0 WHERE user_id=".mysql_real_escape_string($user_id);
$ret = mysql_query ($query) or die (mysql_error ());
if ($code_db == $code)
{
echo "<html>";
echo "<body>";
echo "Your code is valid. ";
// Write whatever you want here to redirect, continue....
echo "</body>";
echo "</html>";
}
else
{
echo "<html>";
echo "<body>";
echo "Your code is invalid. ";
// Write whatever you want here to redirect, disconnect....
echo "</body>";
echo "</html>";
}
}
mysql_close($mysql_link);
?>
|