SessionID introduce and usage

漏洞原理

  • 当用户第一次访问服务程序时,服务器端会给用户创建一个独立的会话Session
    并且生成一个SessionID
  • SessionID在响应浏览器的时候会被加载到cookie中,并保存到浏览器中。
  • 当用户再一次访问服务程序时,请求中会携带着cookie中的SessionID去访问服务器。
  • 服务器会根据这个SessionID去查看是否有对应的Session对象,有则使用,没有就新创建一个Session

漏洞介绍

  • 如果SessionID的构造原理太简单,就很容易被别人仿造。
  • 仿造了SessionID之后应用到cookie,即可无登录访问被害者服务。

漏洞复现

  • 使用DVWA靶场的Weak Session IDs作为演示场景。

Low

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id'])) {
$_SESSION['last_session_id'] = 0;
}
$_SESSION['last_session_id']++;
$cookie_value = $_SESSION['last_session_id'];
setcookie("dvwaSession", $cookie_value);
}
?>

审计

  • 使用POST上传参数时候,设置SessionID
  • 若设置过,则使用上一次的SessionID直接+1,若未设置,则初始化为0
  • 这样的SessionID太过简单,并且很容易冲突,无法标识单一个体。

攻击

  • 找到每次dvwaSession的变化规律,使用BurpSuite抓包查看dvwaSession
  • 使用他人的dvwaSession以及其他cookie内容,尝试删除cookie后登录。

  • 能够登录,说明cookie构造成功(虽然是自己已经看到的)。

Medium

代码

1
2
3
4
5
6
7
8
9
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = time();
setcookie("dvwaSession", $cookie_value);
}
?>

审计

  • 使用时间函数获取当前时间作为cookie,故同一时间的会话将会发生冲突。
  • 其余设置同Low

time( ) : int 返回当前的GMT时间,即Unix纪元起到现在的秒数。

攻击

  • 使用时间戳在线转换器构造时间点,诱骗受害者在该时间点击,形成SessionID碰撞(感觉不太可能)。
  • 或者在受害者最近一次登录后,通过获取其登入时间点,构造时间戳。
  • 使用预测的dvwaSession登入即可。

High

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
if (!isset ($_SESSION['last_session_id_high'])) {
$_SESSION['last_session_id_high'] = 0;
}
$_SESSION['last_session_id_high']++;
$cookie_value = md5($_SESSION['last_session_id_high']);
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], false, false);
}

?>

审计

  • 基本内容同Low,在累加的基础上增加了md5加密。

setcookie( string $name , string $value = “” , int $expires = 0 , string $path = “” , string $domain = “” , bool $secure = false , bool $httponly = false ) : bool 即定义一条cookie,名为name,值为value,失效期为expires(GMT时间),path为有效的服务器路径,domain为有效的域名,secure表示是否建立HTTPS连接,httponly表示是否只通过HTTP协议访问。

攻击

  • 找到明文规律后,构造dvwaSession实现无登录访问。

漏洞防御

  • 使用DVWAImpossible级别进行审计。

代码

1
2
3
4
5
6
7
8
9
<?php

$html = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cookie_value = sha1(mt_rand() . time() . "Impossible");
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], true, true);
}
?>

审计

  • 使用SHA1加密,使得SessionID难以破译。
  • 明文内容为随机数+GMT时间+字符串,增加了伪造的难度。
  • 但仍存在SessionID冲突的情况。

sha1( string $string , bool $binary = false ) : string计算字符串的SHA-1散列,binaryTRUE时为二进制,FALSE时为十六进制。

mt_rand( int $min , int $max ) : int 使用Mersenne Twister的算法生成随机数,若有参数则介于minmax,若无参数则生成0mt_getrandmax()之间的随机数。