通达OA前台任意用户伪造登录分析
source link: https://y4er.com/post/tongda-fake-user/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
通达OA前台任意用户伪造登录分析
2020-04-24通达OA又爆洞了
通达OA历史版本下载:https://cdndown.tongda2000.com/oa/2019/TDOA11.4.exe
解密工具:https://pan.baidu.com/s/1c14V6pi
拿到UID为1及管理员的SESSION直接登陆
在logincheck_code.php中UID可控,当UID为1时,用户默认为admin管理员。 在其后180行左右将信息保存到SESSION中。那么只要绕过了18行的exit()就可以了。
$CODEUID = $_POST["CODEUID"];
$login_codeuid = TD::get_cache("CODE_LOGIN" . $CODEUID);
if (!isset($login_codeuid) || empty($login_codeuid)) {
$databack = array("status" => 0, "msg" => _("参数错误!"), "url" => "general/index.php?isIE=0");
echo json_encode(td_iconv($databack, MYOA_CHARSET, "utf-8"));
exit();
}
login_codeuid 从redis缓存中TD::get_cache()
获取"CODE_LOGIN" . $CODEUID
,搜索下可不可控
跟进general\login_code.php
<?php
include_once "inc/utility_all.php";
include_once "inc/utility_cache.php";
include_once "inc/phpqrcode.php";
$codeuid = $_GET["codeuid"];
$login_codeuid = TD::get_cache("CODE_LOGIN" . $codeuid);
$tempArr = array();
$login_codeuid = (preg_match_all("/[^a-zA-Z0-9-{}\/]+/", $login_codeuid, $tempArr) ? "" : $login_codeuid);
if (empty($login_codeuid)) {
$login_codeuid = getUniqid();
}
$databack = array("codeuid" => $login_codeuid, "source" => "web", "codetime" => time());
$dataStr = td_authcode(json_encode($databack), "ENCODE");
$dataStr = "LOGIN_CODE" . $dataStr;
$data = QRcode::text($dataStr, false, "L", 4);
$data = serialize($data);
if (($data != "") && ($data != NULL)) {
if (unserialize($data)) {
$matrixPointSize = 1.5;
QRimage::png(unserialize($data), false, $matrixPointSize);
}
else {
$im = imagecreatefromstring($data);
if ($im !== false) {
header("Content-Type: image/png");
imagepng($im);
}
}
}
TD::set_cache("CODE_LOGIN" . $login_codeuid, $login_codeuid, 120);
$databacks = array("status" => 1, "code_uid" => $login_codeuid);
echo json_encode(td_iconv($databacks, MYOA_CHARSET, "utf-8"));
echo "\r\n\r\n\r\n";
?>
当$login_codeuid
为空时会getUniqid()
生成一个存入redis缓存并且在最后echo出来。所以我们可以通过直接get请求general\login_code.php
拿到CODEUID
使用之前的CODEUID即可绕过if条件的exit()。
很蠢的错误。通达真的不考虑抛弃全局变量覆盖吗?
拓展下的话,尝试寻找下通过get_cache()获取的变量影响到sql语句什么的。另外不同版本可能有一些不一样,比如11.3根本没走redis验证- -。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK