漏洞原因

弱类型问题

类型转换是无法避免的问题。例如需要将GET或者是POST的参数转换为int类型,或者是两个变量不匹配的时候,PHP会自动地进行变量转换。但是PHP是一个弱类型的语言,导致在进行类型转换的时候会存在很多意想不到的问题。

如果在用于密码比对,身份验证中没有对类型进行强处理,往往会导致对比成功,身份伪造等等。

常见的弱类型对比

  • 数字型与其对应的字符串
    • 0 == '0' => true
  • 0 与 不包含任何数字字符串
    • 0 == 'abc' => true
  • 数字型与其在前缀的字符串
    • 1 == '1abc' => true
  • 数学计算运算

    • '1e0'=='1e2' => true
    • "10" == "1e1" => true
    • ‘0e10’ == '0e1000' => true
    • '0x001'=='1' => true
    • md5('s878926199a') == 0 => true
    • empty
      • empty('0') == empty('0.0') false
      • empty('0') == empty(0.0) true
      • empty 返回 TRUE的情况:
        • 若变量不存在则返回 TRUE
        • 若变量存在且其值为""、0、"0"、NULL、、FALSE、array()、var $var; 以及没有任何属性的对象,则返回 TURE

产生弱类型的函数

  • strcmp
  • In_array
  • array_search
  • ....

漏洞分析

使用安全问题重置密码存在弱类型

if(empty($safequestion)) $safequestion = '';
    if(empty($safeanswer)) $safeanswer = '';
    if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer)
    {
        sn($mid, $row['userid'], $row['email'], 'N');
        exit();
    }
  • dedecms/member/resetpassword.php //78
    • $safequestion 用户输入的安全问题
    • $row['safequestion'] 数据库保存的安全问题
    • $safeanswer 用户输入的安全问题回答
    • $row['safeanswer'] 数据库保存的安全问题回答

如果该用户没有设置过任何安全问题。那么,

  • $row['safequestion'] = 0
  • 当 $safequestion = '0.0' 的时候
    • 第一个 if(empty($safequestion)) 不成立
    • 最后 if $row['safequestion'] == $safequestion 0 = '0.0' 成立
    • 而 $row['safeanswer'] 原本就为空 导致第二个条件 $row['safeanswer'] == $safeanswer
    • 从而进入SN函数,SN函数最后一个参数 Y 发送邮件,N不发送邮件

SN函数:

  • SN函数主要负责发验证和发送邮件。
  • 如果通过安全问题召回密码,那么直接构造修改URL的地址返回客户端直接修改

漏洞验证

利用前提条件

  • DEDE开启了会员功能
  • 修改密码的会员没有设置安全问题

修复建议

  • 把用户重制部分所有验证的部分替换成 '==' 替换成 '==='

漏洞原文

【漏洞分析】 织梦前台任意用户密码修改锦行 - 信息安全

点击收藏 | 2 关注 | 3
追加 于 2018年1月11日 14:15

JAVAScirpt 弱类型

  • 数字型与其对应的字符串
    • 0 == '0' => true
  • 数学计算运算
    • '0e10' == '0e1000' => true
    • ' 0x001'=='1' => true
    • 因为 '0e10' == '0e1000' => true 所以这里也存在MD5处理缺陷
  • 空值
    • JAVAScript 只有 null undefine 两种
    • [],0,'0'之类均等于 null ,只有变量未赋值才是null或者undefined
    • null == undefine => true
    • '' == null => false
    • {} ==[] => false 空数组和空对象也不相等
    • {} == function(){} =>false 空函数和空对象也不相等
  • NaN (Not a Number,非数) 表示未定义或者不可描述的数字 =。=
    • NaN == NaN => false
  • 函数类
    • 这里只测试了 indexOf
      • ['22'].indexOf(22) = -1 不存在
      • ['0e11'].indexOf(0)= -1 不存在
      • ['0e11'].indexOf('0e11')= 0 存在
    • 可以看到 这里均用了强制类型 看来 JavaScript 比 PHP 稍微严格一点

登录 后跟帖