Skip to content

md5로 저장된 낡은 md5 해시된 비번을 pbkdf2(md5_hash)로 저장하기 #2421

@hackmod

Description

@hackmod

커뮤니티의 낡은 md5 비번은 안전하지 않으며 방통위의 지적사항에 해당됩니다.
모듈을 조금 고쳐서 낡은 md5 해시를 pbkdf2(old_md5_hash)로 고치게끔 해보았습니다.

마땅히 올릴 곳이 없어 이곳에 올리니 필요하신 분 참고해서 고쳐서 쓰시기 바랍니다.

fix_md5.php // xe-core 최상위 디렉토리에 복사하여 $ php fix_md5.php 실행함.

<?php
/**
 * MD5 Fixer by hackyminer@gmail.com
 *
 * @license: MIT
 * @description: fix old MD5 passwords
 */
define('__XE__',   TRUE);
require dirname(__FILE__) . '/config/config.inc.php';

$oContext = Context::getInstance();
$oContext->init();

$oDB = &DB::getInstance();
$query = $oDB->_query("select * from xe_member_expired where password not like 'sha256%'");
//$query = $oDB->_query("select * from xe_member where password not like 'sha256%'");
//$query = $oDB->_query("select * from xe_member_expired where password not like 'sha256%' limit 2");
$result = $oDB->_fetch($query);

$o = new Password();
$algo = 'pbkdf2';

if (!is_array($result)) {
    $tmp = $result;
    $result = array();
    $result[] = $tmp;
}

foreach ($result as $u) {
    $oldhash = $u->password;
    $newhash = $o->createHash($oldhash, $algo);
    echo $u->user_id,"\t",$u->member_srl,"\t",$oldhash,"\t",$newhash,"\t", $u->denied,"\n";
    //continue;

    $member_srl = $u->member_srl;

    // Execute insert or update depending on the value of member_srl
    $args = new stdClass;
    $args->member_srl = $member_srl;
    $args->password = $newhash;
    $args->denied = $u->denied;
    $output = executeQuery('member_expire.updateMemberPassword', $args);
    //$output = executeQuery('member.updateMemberPassword', $args);
    if(!$output->toBool()) {
        echo $output->getMessage();
        echo "Fail to update password for member=",$u->member_srl,"/",$u->user_id,"\n";
        exit(-1);
    }
}

echo "Total ", sizeof($result), " users password info updated\n";

/* EOF */

member_expire 모듈에 남아있는 낡은 md5 해시를 업데이트 하려면 다음과 같은 query xml을 복사해 넣어줍니다. modules/member_expire/queries/updateMemberPassword.xml

<query id="updateMemberPassword" action="update">
    <tables>
        <table name="member_expired" />
    </tables>
    <columns>
        <column name="password" var="password" notnull="notnull" />
        <column name="denied" var="denied" />
    </columns>
    <conditions>
        <condition operation="equal" column="member_srl" var="member_srl" notnull="notnull" filter="number" />
    </conditions>
</query>

마지막으로, 이를 지원하기 위해 고쳐야 할 Password.php 모듈 파일

diff --git a/classes/security/Password.class.php b/classes/security/Password.class.php
index 6ab5947..b354acb 100644
--- a/classes/security/Password.class.php
+++ b/classes/security/Password.class.php
@@ -155,7 +155,20 @@ class Password
                                $hash = explode(':', $hash);
                                $hash[3] = base64_decode($hash[3]);
                                $hash_to_compare = $this->pbkdf2($password, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
-                               return $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+                               $check1 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+                               if ($check1) return $check1;
+
+                               // saved hash is pbkdf2(md5(password));
+                               $tmp = md5($password);
+                               $hash_to_compare = $this->pbkdf2($tmp, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
+                               $check2 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+                               if ($check2) return $check2;
+
+                               // saved hash is pbkdf2(md5(sha1(md5(password))));
+                               $tmp = md5(sha1(md5($password)));
+                               $hash_to_compare = $this->pbkdf2($tmp, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3]));
+                               $check3 = $this->strcmpConstantTime($hash_to_compare, $hash[3]);
+                               return $check3;

                        case 'bcrypt':
                                $hash_to_compare = $this->bcrypt($password, $hash);
  • 꽤 오래전 낡은 코드에는 비번을 md5(sha1(md5(password)))로 저장하게끔 했던 흔적이 있습니다. 이 방식은 관리자가 의도적으로 useSha1을 켰을때만 사용되고 있었으나, 혹시 몰라 추가해 두었습니다.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions