John the Ripper 와 비밀번호 솔팅

Kali LinuxBeginner
지금 연습하기

소개

사이버 보안 분야에서 사용자 자격 증명을 보호하는 것은 매우 중요합니다. 비밀번호는 저장될 때 일반 텍스트로 유지되는 경우가 거의 없습니다. 대신, 일반적으로 해싱 (hashing) 되어, 단방향 암호화 함수를 사용하여 고정된 크기의 문자열로 변환됩니다. 이를 통해 공격자가 데이터베이스에 접근하더라도 비밀번호에 직접 접근하는 것을 방지할 수 있습니다. 하지만 단순한 해시는 충분하지 않습니다. 공격자는 미리 계산된 해시 테이블 (레인보우 테이블, rainbow tables) 이나 무차별 대입 공격 (brute-force attacks) 을 사용하여 비밀번호를 크랙할 수 있습니다.

이때 "솔팅 (salting)"이 등장합니다. 솔팅은 비밀번호를 해싱하기 전에 고유하고 무작위적인 문자열 ("솔트", salt) 을 비밀번호에 추가하는 기법입니다. 이 솔트는 해시와 함께 저장됩니다. 사용자가 로그인하려고 할 때, 동일한 솔트를 검색하여 입력된 비밀번호와 결합한 후 해싱하고, 결과 해시를 저장된 해시와 비교합니다.

이 실험실에서는 비밀번호 솔팅의 개념을 탐구하고, 보안 강화를 위한 중요성을 이해하며, John the Ripper 와 같은 강력한 비밀번호 크랙 도구가 솔트된 해시와 어떻게 상호 작용하는지 관찰할 것입니다. 솔트된 해시를 식별하는 방법, John the Ripper 가 이를 처리하는 방식, 그리고 솔팅이 비밀번호 크랙 난이도에 미치는 상당한 영향을 파악하게 될 것입니다. 마지막으로, 실제 비밀번호 저장 방식에서 솔팅이 어떻게 구현되는지에 대한 통찰력을 얻게 될 것입니다.

솔팅 (Salting) 개념 이해하기

이 단계에서는 비밀번호 솔팅의 기본 개념과 비밀번호 보안 강화에 왜 중요한지 배웁니다.

비밀번호에 "솔팅"을 할 때, 해싱하기 전에 고유하고 무작위적인 문자열 (솔트) 이 비밀번호에 추가됩니다. 이는 두 사용자가 정확히 동일한 비밀번호를 가지고 있더라도, 각각 다른 솔트가 사용되었기 때문에 저장된 해시 값은 다를 수 있음을 의미합니다. 이는 고정된 해시에 의존하는 미리 계산된 레인보우 테이블 (rainbow tables) 을 효과적으로 무력화합니다. 또한, 공격자는 가능한 모든 비밀번호 가능한 모든 솔트에 대한 해시를 계산해야 하므로, 단순히 가능한 모든 비밀번호만 계산하는 것보다 무차별 대입 공격 (brute-force attacks) 이 더 어려워집니다.

솔트된 해시의 예를 살펴보겠습니다. ~/project 디렉토리에 생성된 salted_passwords.txt 파일을 엽니다.

cat ~/project/salted_passwords.txt

다음과 유사한 출력을 볼 수 있습니다.

user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
user2:5f4dcc3b5aa765d61d8327deb882cf99
user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

user1, user3, user4의 줄을 주목하십시오. 이 줄에는 $6$salt12345$ 또는 $6$another_salt$와 같은 섹션이 포함되어 있습니다. $6$은 사용된 해싱 알고리즘 (이 경우 SHA-512) 을 나타내며, 두 번째와 세 번째 $ 기호 사이의 문자열 (salt12345 또는 another_salt) 이 솔트입니다. 세 번째 $ 뒤의 나머지 문자열은 솔트와 결합된 비밀번호의 실제 해시입니다. user2의 줄은 나중에 비교에 사용할 솔트되지 않은 MD5 해시입니다.

핵심은 각 솔트된 해시가 고유한 솔트를 가지고 있어, 동일한 미리 계산된 테이블을 사용하여 여러 비밀번호를 동시에 크랙하기 어렵다는 것입니다.

솔트된 해시 (Salted Hashes) 식별하기

이 단계에서는 일반적인 형식을 기반으로 솔트된 해시를 식별하는 방법을 배웁니다. 이러한 형식을 인식하는 것은 비밀번호 크랙 또는 방어 접근 방식을 이해하는 첫 번째 단계입니다.

다양한 해싱 알고리즘과 시스템은 솔트된 해시를 저장하기 위해 다양한 형식을 사용합니다. 그러나 많은 일반적인 형식, 특히 Linux 시스템에서 사용되는 형식은 솔트가 해시 문자열 내에 직접 포함되어 있으며 종종 $와 같은 특수 문자로 구분되는 패턴을 따릅니다.

salted_passwords.txt 파일을 다시 살펴보고 솔팅을 나타내는 패턴을 구체적으로 찾아보겠습니다.

cat ~/project/salted_passwords.txt

이전 단계에서 관찰한 바와 같이:

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword
  • user4:$6$short$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:shortpass

이 줄들은 $6$ 접두사 (SHA-512 crypt 를 나타냄) 뒤에 솔트 문자열 (예: salt12345, another_salt, short) 이 오고, 그 뒤에 실제 해시가 오는 것을 명확하게 보여줍니다. 이 구조는 솔트된 해시의 강력한 지표입니다.

반면에 user2의 줄은 다음과 같습니다.

  • user2:5f4dcc3b5aa765d61d8327deb882cf99

이것은 단순한 MD5 해시입니다. 구분 기호나 내장된 솔트가 없어 솔트되지 않은 해시로 쉽게 식별할 수 있습니다.

솔트된 해시와 솔트되지 않은 해시를 신속하게 구별하는 능력은 보안 전문가 및 침투 테스터에게 매우 중요합니다. 이는 적용할 수 있는 크랙 전략을 결정하기 때문입니다.

John the Ripper 의 솔트된 해시 처리 관찰하기

이 단계에서는 인기 있는 비밀번호 크랙 도구인 John the Ripper 를 사용하여 솔트된 해시와 솔트되지 않은 해시를 어떻게 처리하는지 관찰합니다. 이를 통해 솔팅의 실제적인 영향을 보여줄 것입니다.

먼저 간단한 단어 목록 (wordlist) 을 사용하여 salted_passwords.txt의 비밀번호를 크랙해 보겠습니다. 이 시연을 위해 작고 사용자 정의된 단어 목록을 사용할 것입니다.

~/project 디렉토리에 wordlist.txt라는 단어 목록 파일을 만들고 몇 가지 일반적인 비밀번호를 추가합니다.

echo "password" > ~/project/wordlist.txt
echo "user1password" >> ~/project/wordlist.txt
echo "anotherpassword" >> ~/project/wordlist.txt
echo "shortpass" >> ~/project/wordlist.txt
echo "123456" >> ~/project/wordlist.txt

이제 이 단어 목록을 사용하여 salted_passwords.txt 파일에 대해 John the Ripper 를 실행합니다.

john --wordlist=~/project/wordlist.txt ~/project/salted_passwords.txt

John the Ripper 가 해시를 분석합니다. 비밀번호를 크랙하려고 시도함을 나타내는 출력을 볼 수 있습니다. 솔트되지 않은 MD5 해시이고 단어 목록에 "password"가 있기 때문에 user2의 비밀번호를 빠르게 찾을 가능성이 높습니다. 해당 평문 (plaintext) 이 단어 목록에 있다면 솔트된 비밀번호도 찾을 것입니다.

예상 출력은 다음과 같습니다.

Using default input encoding: UTF-8
Loaded 4 password hashes with no different salts to crack (crypt, generic crypt(3) [MD5/Blowfish/SHA1/SHA256/SHA512/XSHAa/XSHAab/bcrypt/scrypt])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password         (user2)
user1password    (user1)
anotherpassword  (user3)
shortpass        (user4)
4g 0:00:00:00 DONE (2023-10-27 10:30) ...
Session completed.

John 이 완료된 후에는 --show 옵션을 사용하여 크랙된 비밀번호를 볼 수 있습니다.

john --show ~/project/salted_passwords.txt

이 명령은 John 이 성공적으로 크랙한 모든 비밀번호를 표시합니다.

user2:password (user2)
user1:user1password (user1)
user3:anotherpassword (user3)
user4:shortpass (user4)

4 password hashes cracked, 0 left

John the Ripper 는 내장된 솔트를 포함하여 다양한 해시 형식을 처리하도록 설계되었습니다. 크랙 프로세스 중에 솔트를 자동으로 추출하여 사용합니다. 그러나 각 비밀번호에 고유한 솔트가 존재하면, 특히 대규모 공격에서 크랙에 필요한 계산 노력이 크게 증가합니다.

솔팅이 크랙에 미치는 영향 이해하기

이 단계에서는 솔팅이 비밀번호 크랙을, 특히 대규모 공격에 대해 훨씬 더 어렵게 만드는 이유에 대한 이해를 공고히 할 것입니다.

salted_passwords.txt 파일의 user2 항목을 생각해 봅시다: user2:5f4dcc3b5aa765d61d8327deb882cf99. 이것은 "password"라는 비밀번호에 대한 솔트되지 않은 MD5 해시입니다. 공격자가 솔트되지 않은 MD5 해시 데이터베이스를 얻는다면 다음과 같은 작업을 할 수 있습니다.

  1. 레인보우 테이블 (Rainbow Tables) 사용: 일반적인 비밀번호에 대한 사전 계산된 해시 테이블입니다. "password"가 테이블에 있다면, 해당 해시 5f4dcc3b5aa765d61d8327deb882cf99도 거기에 있을 것이며, 평문을 즉시 검색할 수 있습니다.
  2. 여러 비밀번호 동시 크랙: 많은 사용자가 동일한 약한 비밀번호 (예: "123456") 를 가지고 있다면, 그들의 솔트되지 않은 해시는 동일할 것입니다. 공격자는 해당 해시의 한 인스턴스만 크랙하면 이를 공유하는 모든 사용자의 비밀번호를 알 수 있습니다.

이제 솔트된 해시를 살펴보겠습니다.

  • user1:$6$salt12345$abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ./:user1password
  • user3:$6$another_salt$zyxwuvtsrqponmlkjihgfedcba9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA./:anotherpassword

user1user3이 정확히 같은 비밀번호를 가지고 있더라도, 솔트 (salt12345another_salt) 가 다르기 때문에 해시는 다를 것입니다. 이는 공격자에게 몇 가지 중요한 영향을 미칩니다.

  • 레인보우 테이블 무용지물: 각 해시는 솔트 때문에 고유하므로, 사전 계산된 레인보우 테이블은 효과가 없습니다. 공격자는 가능한 모든 솔트에 대한 레인보우 테이블이 필요할 것이며, 이는 계산적으로 불가능합니다.
  • 해시별 개별 크랙: 공격자는 각 솔트된 해시를 개별적으로 크랙해야 합니다. 100 명의 사용자가 동일한 비밀번호를 가지고 있지만 각자 고유한 솔트를 가지고 있다면, 공격자는 각 고유한 해시 - 솔트 쌍에 대해 100 번의 별도 크랙 작업을 수행해야 합니다. 이는 성공적인 공격에 필요한 시간과 리소스를 극적으로 증가시킵니다.
  • 무차별 대입 (Brute-Force) 의 어려움: 무차별 대입 공격의 경우, 공격자는 각 잠재적 비밀번호를 해당 특정 솔트와 결합한 후 해싱 및 비교해야 합니다. 이는 솔트되지 않은 해시에 비해 복잡성을 더하고 크랙 프로세스를 상당히 늦춥니다.

본질적으로 솔팅은 단일 크랙 문제를 여러 독립적인 크랙 문제로 변환하여, 대규모 비밀번호 유출을 공격자에게 훨씬 더 어렵고 시간이 많이 소요되도록 만듭니다.

비밀번호 저장 시 솔팅 구현하기

이 단계에서는 실제 비밀번호 저장 시스템에서 솔팅이 어떻게 구현되는지에 대한 개념적 이해를 얻게 됩니다. 전체 시스템을 구축하지는 않겠지만, 핵심 구성 요소를 살펴보게 될 것입니다.

사용자가 비밀번호를 설정하거나 변경할 때, 보안 시스템은 일반적으로 다음 단계를 수행합니다.

  1. 무작위 솔트 (Salt) 생성: 암호학적으로 안전한 무작위 솔트가 생성됩니다. 이 솔트는 각 사용자 및 각 비밀번호 변경마다 고유해야 합니다.
  2. 비밀번호와 솔트 결합: 사용자의 평문 비밀번호가 생성된 솔트와 연결됩니다.
  3. 결합된 문자열 해싱: 결합된 비밀번호와 솔트 문자열은 강력하고 느린 해싱 알고리즘 (예: bcrypt, scrypt, Argon2 또는 예제에서 본 SHA-512 crypt) 을 통과합니다. 느린 해싱 알고리즘은 무차별 대입 공격을 더욱 시간 소모적으로 만들기 때문에 선호됩니다.
  4. 해시와 솔트 저장: 결과 해시와 솔트는 함께 데이터베이스에 저장됩니다. 솔트는 비밀일 필요가 없으며, 그 목적은 해시의 고유성을 보장하는 것입니다.

사용자가 로그인하려고 할 때:

  1. 저장된 솔트 검색: 시스템은 데이터베이스에서 사용자의 계정과 관련된 솔트를 검색합니다.
  2. 입력된 비밀번호와 저장된 솔트 결합: 사용자가 입력한 비밀번호가 검색된 솔트와 결합됩니다.
  3. 결합된 문자열 해싱: 이 결합된 문자열은 등록 중에 사용된 것과 동일한 해싱 알고리즘을 사용하여 해싱됩니다.
  4. 해시 비교: 새로 계산된 해시가 저장된 해시와 비교됩니다. 일치하면 비밀번호가 올바른 것입니다.

mkpasswd 명령을 사용하여 솔트된 해시 생성을 시뮬레이션해 보겠습니다. 이 명령은 whois 패키지의 일부이며 crypt(3) 스타일의 해시를 생성할 수 있습니다.

먼저 whois가 설치되어 있는지 확인합니다.

sudo apt install -y whois

이제 사용자 정의 솔트 "mysalt"를 사용하여 비밀번호 "mysecretpassword"에 대한 SHA-512 솔트된 해시를 생성합니다.

mkpasswd -m sha-512 "mysecretpassword" -s "mysalt"

다음과 유사한 출력을 볼 수 있습니다.

$6$mysalt$some_long_hash_string_here

출력 $6$mysalt$some_long_hash_string_here는 솔트된 해시입니다. $6$은 SHA-512 를 나타내고, mysalt는 제공한 솔트이며, 나머지는 실제 해시입니다. 실제 시스템에서는 솔트가 수동으로 제공되는 것이 아니라 무작위로 생성됩니다.

이것은 기본적인 프로세스를 보여줍니다. 현대 애플리케이션은 이러한 세부 사항을 추상화하는 라이브러리와 프레임워크를 사용하지만, 고유한 솔트를 생성하고, 이를 비밀번호와 결합하고, 해싱하고, 둘 다 저장하는 기본 원칙은 안전한 비밀번호 저장의 초석으로 남아 있습니다.

요약

이번 실습을 통해 비밀번호 솔팅과 비밀번호 보안 강화에 있어 솔팅의 중요한 역할에 대한 포괄적인 이해를 얻었습니다. 솔팅은 해싱 전에 비밀번호에 고유하고 무작위적인 문자열 (솔트) 을 추가하는 것을 포함하며, 동일한 비밀번호에 대해서도 각 해시를 고유하게 만든다는 것을 배웠습니다.

특징적인 형식, 종종 $와 같은 구분 기호와 내장된 솔트 문자열을 포함하는 솔트된 해시를 성공적으로 식별했습니다. John the Ripper 를 사용한 실제 관찰을 통해 이 강력한 도구가 솔트된 해시와 솔트되지 않은 해시를 모두 처리하는 방법, 그리고 결정적으로 솔팅이 각 해시별로 크랙 프로세스를 수행하도록 강제하여 공격자의 계산 노력을 크게 증가시킨다는 것을 보았습니다.

마지막으로, 비밀번호 저장 시스템에서 솔팅의 개념적 구현을 탐구했으며, 솔트와 비밀번호를 생성, 결합, 해싱 및 저장하는 단계를 이해했습니다. 이 지식은 시스템 방어 또는 공격 방법론 이해와 관련이 있는 모든 사이버 보안 전문가에게 필수적입니다.

각 비밀번호 해시를 고유하게 만듦으로써 솔팅은 레인보우 테이블 공격의 위협을 효과적으로 완화하고 무차별 대입 시도를 극적으로 늦추어 강력한 비밀번호 보안을 위한 필수적인 기술이 됩니다.