여러 번 Linux 시스템에서 사용자 비밀번호를 변경하려고 시도했으며 새 비밀번호가 이전 비밀번호와 비슷할 때 OS가 너무 비슷하다고 불평했습니다.
나는 항상 궁금했다. 시스템은 이것을 어떻게 아는가? 암호가 해시로 저장되었다고 생각했습니다. 이것은 시스템이 유사성을 위해 새 비밀번호를 비교할 수있을 때 이전 비밀번호가 실제로 일반 텍스트로 저장됨을 의미합니까?
여러 번 Linux 시스템에서 사용자 비밀번호를 변경하려고 시도했으며 새 비밀번호가 이전 비밀번호와 비슷할 때 OS가 너무 비슷하다고 불평했습니다.
나는 항상 궁금했다. 시스템은 이것을 어떻게 아는가? 암호가 해시로 저장되었다고 생각했습니다. 이것은 시스템이 유사성을 위해 새 비밀번호를 비교할 수있을 때 이전 비밀번호가 실제로 일반 텍스트로 저장됨을 의미합니까?
답변:
를 사용할 때 이전 비밀번호 와 새 비밀번호를 모두 제공해야하므로 passwd
드라이브의 어딘가에 비밀번호 를 쓰지 않고도 메모리에서 일반 텍스트로 쉽게 비교할 수 있습니다.
실제로 비밀번호는 마지막으로 저장 될 때 해시되지만 비밀번호가 입력 될 때까지 비밀번호를 입력하는 도구는 STDIN에서 읽는 동안 다른 프로그램이 키보드에 입력 한 항목에 액세스 할 수있는 것처럼 비밀번호에 직접 액세스 할 수 있습니다.
이것은 도구 의 배경에서 사용되는 PAM 시스템 의 기능입니다 passwd
. PAM은 최신 Linux 배포판에서 사용됩니다.
보다 구체적으로, pam_cracklib
몇 가지 약점을 기반으로 암호를 거부하여 매우 취약하게 만드는 PAM 용 모듈입니다.
안전하지 않은 것으로 간주 될 수있는 너무 유사한 암호는 아닙니다. 소스 코드는 암호가 회문 또는 무엇 편집 거리가 두 단어 사이인지 등을 확인할 수 있습니다 무엇의 다양한 사례를 가지고 있습니다. 아이디어는 사전 공격에 대해 암호를 더 잘 보호하는 것입니다.
적어도 우분투에서 "너무 비슷한"메시지가 나왔습니다 언제 : "... 문자의 절반 이상이 다른 문자입니다 ..." (자세한 내용은 아래 참조). @slhck 답변에 명확하게 설명 된 PAM 지원 덕분에.
PAM을 사용하지 않는 다른 플랫폼의 경우 다음과 같은 경우 "너무 유사"메시지가 나타납니다. "... 문자의 절반 이상이 다른 문자입니다 ..." (자세한 내용은 아래 참조)
이 문장을 직접 확인하기 위해 소스 코드를 확인할 수 있습니다. 방법은 다음과 같습니다.
"passwd"프로그램은 passwd 패키지에 포함되어 있습니다 :
verzulli@iMac:~$ which passwd
/usr/bin/passwd
verzulli@iMac:~$ dpkg -S /usr/bin/passwd
passwd: /usr/bin/passwd
우리는 오픈 소스 기술을 다루면서 소스 코드에 제한없이 액세스 할 수 있습니다. 그것을 얻는 것은 다음과 같이 간단합니다.
verzulli@iMac:/usr/local/src/passwd$ apt-get source passwd
나중에 관련 코드 조각을 쉽게 찾을 수 있습니다.
verzulli@iMac:/usr/local/src/passwd$ grep -i -r 'too similar' .
[...]
./shadow-4.1.5.1/NEWS:- new password is not "too similar" if it is long enough
./shadow-4.1.5.1/libmisc/obscure.c: msg = _("too similar");
"obscure.c"에 대한 빠른 검사는 이것을 제공합니다 (관련 코드 조각 만 잘라 붙여 넣습니다).
static const char *password_check (
const char *old,
const char *new,
const struct passwd *pwdp)
{
const char *msg = NULL;
char *oldmono, *newmono, *wrapped;
if (strcmp (new, old) == 0) {
return _("no change");
}
[...]
if (palindrome (oldmono, newmono)) {
msg = _("a palindrome");
} else if (strcmp (oldmono, newmono) == 0) {
msg = _("case changes only");
} else if (similar (oldmono, newmono)) {
msg = _("too similar");
} else if (simple (old, new)) {
msg = _("too simple");
} else if (strstr (wrapped, newmono) != NULL) {
msg = _("rotated");
} else {
}
[...]
return msg;
}
따라서, 우리는 이전과 새로운 검사가 둘 다 유사한 경우에 유사한 "유사한"기능이 있다는 것을 알고 있습니다. 스 니펫은 다음과 같습니다.
/*
* more than half of the characters are different ones.
*/
static bool similar (const char *old, const char *new)
{
int i, j;
/*
* XXX - sometimes this fails when changing from a simple password
* to a really long one (MD5). For now, I just return success if
* the new password is long enough. Please feel free to suggest
* something better... --marekm
*/
if (strlen (new) >= 8) {
return false;
}
for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
if (strchr (new, old[i]) != NULL) {
j++;
}
}
if (i >= j * 2) {
return false;
}
return true;
}
C 코드를 검토하지 않았습니다. 함수 정의 직전에 주석을 신뢰하는 것으로 제한했습니다 :-)
PAM과 NON-PAM 인식 플랫폼의 차이점은 다음과 같은 구조의 "obscure.c"파일에 정의되어 있습니다.
#include <config.h>
#ifndef USE_PAM
[...lots of things, including all the above...]
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */
passwd
오래된 암호와 새 암호 를 요구 한다는 사실이 답 입니다. 이 답변의 나머지 부분은 관련이 없습니다.
대답은 생각보다 훨씬 간단합니다. 실제로 트릭을 설명하면 사라지기 때문에 거의 마법으로 자격이 있습니다.
$ passwd
Current Password:
New Password:
Repeat New Password:
Password changed successfully
새 비밀번호가 비슷하다는 것을 알고 있습니다. 바로 이전 비밀번호를 입력했기 때문입니다.
다른 답변은 옳지 만 이전 암호를 제공하지 않아도 작동 할 수 있습니다.
실제로, 제공 한 새 비밀번호와 유사한 비밀번호를 생성하여 해시 한 다음이 해시 중 하나가 이전 비밀번호와 일치하는지 확인할 수 있습니다. 이 경우 새 비밀번호는 이전 비밀번호와 비슷한 것으로 판단됩니다! :)
n
) 의 3을 3으로 조합 62 * (n!)/(6 * (n - 3)!)
하여 12 자 길이 암호의 경우 13540입니다. 그러나 누군가 다른 것에 대해 생각하면 방정식이 쓸모가 없습니다. 왜 귀찮습니까?