Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
hackmod opened this issue Mar 19, 2020 · 0 comments

Comments

@hackmod
Copy link
Contributor

hackmod commented Mar 19, 2020

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

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

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

<?php
/**
 * MD5 Fixer by [email protected]
 *
 * @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을 켰을때만 사용되고 있었으나, 혹시 몰라 추가해 두었습니다.
@xpressengine xpressengine deleted a comment from kms0219kms Jan 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant