MENU

SolusVM开发:从session和cookie中验证用户是否登录

最近从leonn的whmcs卖了十几台nat小鸡,销量还行,于是准备专门抽空搞一下这个,目前nat是用的我也忘了哪里来的(听说是vpsps的)shell脚本,预先定义好端口的,但是这样感觉很不方便,想换成用户自定义nat端口的方式,目前屌鸡有这个产品,但是价格对我来说稍贵,于是准备自己写一个,写的时候就遇到了登录验证的问题,昨晚总算解决,发一下SolusVM的验证方式.

因研究需要分析和解密的SolusVM文件

因为SolusVM使用ioncube加密,而官网也没有说明如何进行验证(官网文档有一个admin的api可以验证用户信息,但是在用户使用的角度来看,登录solusvm和使用nat功能需要输入2次账户密码不科学),官网有给出2013年的sdk,其中有一个验证是否登录的文件(也是加密的),而且根据说明使用它时也会提示错误,于是便解密了部分文件进行分析.

  • /usr/local/solusvm/includes/config.php
  • /usr/local/solusvm/includes/verify.php
  • /usr/local/solusvm/system/Libs/Crypt/LegacyCrypt.php
  • /usr/local/solusvm/www/login.php
  • /usr/local/solusvm/www/logout.php
  • /usr/local/solusvm/includes/solusvm.conf

分析

首先看login.php,里面和其它普通的登录流程一样,先从数据库找用户再验证密码是否正确,然后验证用户状态等,密码采用sha1算法,然后通过某个自定义函数生成了两段随机字符,通过LegacyCrypt.php里的LegacyCrypt类的encrypt进行加密(此类的实例化位置不知,login.php中没有实例化此类),然后用户id,用户ip和生成的2个随机字符存入session,加密后的2个随机字符存入cookie.

然后看LegacyCrypt.php,构造函数需要传递一个key,解密了几个login.php引用的文件没有找到,先忽略这个文件.

然后看verify.php,里面的验证基本和login.php一样,多了一些管理员和分销商还有根据预先设置对ip之类的验证.

到这里没有思路继续追踪了,于是先尝试打印session和cookie,打印结果中session结果为空,而且使用session_destroy()销毁session之后solusvm的账户仍然处于登录状态,cookie则为正常.

然后解密logout.php,里面也是普通的销毁session和cookie,然后对比verify.php,login.php,logout.php发现里面加载了几个相同的文件,逐个解密分析.最后找到config.php(代码在下面),

然后解密config.php,里面重新设置了session的位置(这就是为什么自己写的文件操作session无效的原因),同时还注意到,此文件还通过exec执行了几条字符串分割的命令,目标文件是solusvm.conf,通过变量名可以知道这文件里存着数据库连接信息,删除exec命令中的\转义字符然后运行得到的mysql账户密码可以通过mysql命令登录,得到的数据库名用mysqldump可以正常导出数据库信息,同时还注意到一个名为enckey的变量,前面分析了login,密码使用的是sha1算法,并不需要key,于是推断这个变量是给LegacyCrypt用的.

验证

知道了验证原理就很简单了,自己写一个test文件,引用config.php,然后打印session和cookie,通过浏览器打开,可以正常输出session和cookie,保存一下session和cookie两条登录时生成和加密的随机字符,然后写另一个test文件,引用config.php和LegacyCrypt.php文件并实例化LegacyCrypt类,实例化时传递config.php里的enckey,然后对之前打印出来的cookie进行解密,然后发现cookie解密后的值等于session的值,之前对enckey的用处的推断是正确的,此时solusvm的登录验证已经完全明确,可以根据分析写自己的登录验证了

cookie部分验证代码

$cookie_pass1 = $mcrypt->decrypt($_COOKIE['passone']);
$cookie_pass2 = $mcrypt->decrypt($_COOKIE['passtwo']);
if ($cookie_pass1 !== $_SESSION[pass1]) {
    session_destroy();
    header('Location: login.php');
    exit();
}

if ($cookie_pass2 !== $_SESSION[pass2]) {
    session_destroy();
    header('Location: login.php');
    exit();
}

config.php

<?php
$dn  = exec('' . "grep -m1 \$1: /usr/local/solusvm/includes/solusvm.conf | cut -d ':' -f 1");
$du  = exec('' . "grep -m1 \$1: /usr/local/solusvm/includes/solusvm.conf | cut -d ':' -f 2");
$dp  = exec('' . "grep -m1 \$1: /usr/local/solusvm/includes/solusvm.conf | cut -d ':' -f 3");
$dh  = exec('' . "grep -m1 \$1: /usr/local/solusvm/includes/solusvm.conf | cut -d ':' -f 4");
$ec  = exec('' . "grep -m1 \$1: /usr/local/solusvm/includes/solusvm.conf | cut -d ':' -f 5");
$pos = strpos($dh, '|');
if (false === $pos) {
    $_DBHOST = $dh;
} else {
    $host_split = explode('|', $dh);
    $_DBHOST    = $host_split[0] . ':' . $host_split[1];
}

$_DBUSER   = $du;
$_DBNAME   = $dn;
$_DBPASS   = $dp;
$_DBIGNERR = '0';
$enckey    = $ec;
unset($dn, $du, $dp, $dh, $ec);

$port         = '6767';
$session_path = '/usr/local/solusvm/sessions/';
ini_set('session.save_path', $session_path);
添加新评论

已有 1 条评论
  1. py py

    希望大佬优化一下手机版。
    手机solusVM对您插件的支持很不友好,必须横屏才能显示出NAT这个按钮
    而且在NAT端口设置页面也不能竖屏,一竖屏就一片空白