Preface前言
HTTP是一种无状态的连接,会话状态的保持只能通过服务器端的SESSION来维持。SESSION认证依赖于颁发给用户的一个唯一的ID号。用户浏览器向服务器发送一个ID,服务器端存在该会话ID则认为该用户和会话用户为同一人。恶意攻击者可以通过嗅探网络中的COOKIE信息冒用其它用户的SESSION ID,从而冒充合法用户,这就是SESSION劫持。
COOKIE除了保存会话ID,还常常用于记住密码功能,避免繁琐的登录。大部分网站都将帐号密码保存于COOKIE中,这增加了风险:COOKIE传输过程中被第三方窥探、COOKIE文件被恶意拷贝、离线构造COOKIE破解密码……这一切都应该归于COOKIE欺骗。
现有的办法是使用SSL安全传输,但增加了开销,大部分网站都无法承担整站SSL带来的巨大资源消耗,往往是登录页使用SSL,其它页面依旧是透明的HTTP。这对SESSION劫持毫无用处
Solution解决办法
原理:COOKIE可以伪造,IP可能更换,要唯一的标记一台计算机最合理的方式应该是标记其物理地址。
PHP获取物理地址可以通过以下方法
获取网卡的MAC地址原码;目前支持WIN/LINUX系统
获取机器网卡的物理(MAC)地址
**/
class GetMacAddr{
var $return_array = array(); // 返回带有MAC地址的字串数组
var $mac_addr;
function GetMacAddr($os_type){
switch ( strtolower($os_type) ){
case "linux":
$this->forLinux();
break;
case "solaris":
break;
case "unix":
break;
case "aix":
break;
default:
$this->forWindows();
break;
}
$temp_array = array();
foreach ( $this->return_array as $value ){
if (
preg_match("/[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f]/i",$value,
$temp_array ) ){
$this->mac_addr = $temp_array[0];
break;
}
}
unset($temp_array);
return $this->mac_addr;
}
function forWindows(){
@exec("ipconfig /all", $this->return_array);
if ( $this->return_array )
return $this->return_array;
else{
$ipconfig = $_SERVER["WINDIR"]."\system32\ipconfig.exe";
if ( is_file($ipconfig) )
@exec($ipconfig." /all", $this->return_array);
else
@exec($_SERVER["WINDIR"]."\system\ipconfig.exe /all", $this->return_array);
return $this->return_array;
}
}
function forLinux(){
@exec("ifconfig -a", $this->return_array);
return $this->return_array;
}
}
$mac = new GetMacAddr(PHP_OS);
function getMAC(){
global $mac;
return $mac->mac_addr;
}
以上代码包含到目标页面中,调用getMAC()即可获得MAC地址,以下是具体实现
一、COOKIE欺骗的防范
假设用户名为pwd
1.设置COOKIE
用户名用明文方便数据库检索,密码值为 用户名+密码+MAC地址 的md5值
setCookie("usesrname",$username,time()+3600);
setCookie("pwd",md5(pwd.getMAC()),time()+3600);
2.验证COOKIE
假设存在数据库对象是$db
$sql="Select……From …… WHERE `username`='" .$user."' and MD5(CONCAT(`username`,`password`,'".getMAC()."'))='{$_COOKIE['password']}'";
if($db->query($sql)){
//登录成功
}else{
//登录失败
}
总结:COOKIE文件与网卡地址绑定,复制、截取都无法登录,COOKIE文件无法窥探用户信息,哈希值无法构造破解。
二、SESSION劫持的防范
SESSION劫持的防范比较简单。
用户登录后,在SESSION中存储一个MAC值即可,每次验证该值是否与实际地址相同:
if(登录成功){
……
$_SESSION['MAC']=getMAC();
……
}
验证
if($_SESSION['MAC']==getMAC())
//合法
else
//不合法
总结:适用于不安全网络传输,恶意用户嗅探到SESSION ID也无法登录
。
网友评论