사이버 보안에서 허니팟은 시스템을 손상시키려는 잠재적 공격자를 유인하고 감지하도록 설계된 미끼 시스템입니다. 마치 열린 곳에 놓인 꿀단지가 파리를 유인하는 것과 같습니다.

이 허니팟을 시스템을 위한 보안 카메라로 생각해 보세요. 보안 카메라가 누가 건물에 침입하려고 하고 어떻게 하고 있는지를 이해하는 데 도움을 주듯이, 이 허니팟은 누가 시스템을 공격하려고 하고 어떤 기법을 사용하는지 이해하는 데 도움을 줄 것입니다.

이 튜토리얼이 끝나면 Python으로 데모 허니팟을 작성할 수 있고 허니팟이 어떻게 작동하는지 이해하게 될 것입니다.

목차

허니팟의 종류 이해하기

자신만의 허니팟을 설계하기에 앞서, 다양한 종류를 빠르게 이해해 봅시다:

  1. 운영 허니팟: 이러한 종류의 허니팟은 실제 운영 환경에 배치되어 실제 보안 공격을 탐지하는 데 사용됩니다. 일반적으로 설계가 간단하고 유지 관리 및 배포가 용이하며, 위험을 줄이기 위해 제한된 상호작용을 제공합니다.

  2. 연구 허니팟: 이는 보안 연구자들이 공격 패턴을 연구하고, 이러한 패턴에 대한 실증 분석을 수행하며, 악성 코드 샘플을 수집하고, 이전에 발견되지 않은 새로운 공격 기법을 이해하기 위해 설정한 더 복잡한 시스템입니다. 이들은 운영 환경에서 애플리케이션처럼 행동하기보다는 전체 운영 체제나 네트워크를 에뮬레이트하는 경우가 많습니다.

이번 튜토리얼에서는 연결 시도와 기본 공격자 행동을 기록하는 중간 상호작용 허니팟을 구축할 것입니다.

개발 환경 설정 방법

Python에서 개발 환경을 설정하는 것부터 시작하겠습니다. 다음 명령어를 실행하세요:

import socket
import sys
import datetime
import json
import threading
from pathlib import Path

# 로그 디렉토리 구성
LOG_DIR = Path("honeypot_logs")
LOG_DIR.mkdir(exist_ok=True)

내장 라이브러리만 사용할 것이므로 외부 종속성을 설치할 필요는 없습니다. 로그는 honeypot_logs 디렉토리에 저장할 것입니다.

핵심 허니팟 구축 방법

기본 허니팟은 세 가지 구성 요소로 이루어집니다:

  1. 연결을 수락하는 네트워크 리스너

  2. 활동을 기록하는 로깅 시스템

  3. 공격자와 상호작용하는 기본 에뮬레이션 서비스

이제 핵심 허니팟 클래스를 초기화하는 것부터 시작합시다:

class Honeypot:
    def __init__(self, bind_ip="0.0.0.0", ports=None):
        self.bind_ip = bind_ip
        self.ports = ports or [21, 22, 80, 443]  # 모니터링 할 기본 포트
        self.active_connections = {}
        self.log_file = LOG_DIR / f"honeypot_{datetime.datetime.now().strftime('%Y%m%d')}.json"

    def log_activity(self, port, remote_ip, data):
        """Log suspicious activity with timestamp and details"""
        activity = {
            "timestamp": datetime.datetime.now().isoformat(),
            "remote_ip": remote_ip,
            "port": port,
            "data": data.decode('utf-8', errors='ignore')
        }

        with open(self.log_file, 'a') as f:
            json.dump(activity, f)
            f.write('\n')

    def handle_connection(self, client_socket, remote_ip, port):
        """Handle individual connections and emulate services"""
        service_banners = {
            21: "220 FTP server ready\r\n",
            22: "SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.1\r\n",
            80: "HTTP/1.1 200 OK\r\nServer: Apache/2.4.41 (Ubuntu)\r\n\r\n",
            443: "HTTP/1.1 200 OK\r\nServer: Apache/2.4.41 (Ubuntu)\r\n\r\n"
        }

        try:
            # 서비스에 적합한 배너 전송
            if port in service_banners:
                client_socket.send(service_banners[port].encode())

            # 공격자로부터 데이터 수신
            while True:
                data = client_socket.recv(1024)
                if not data:
                    break

                self.log_activity(port, remote_ip, data)

                # 가짜 응답 전송
                client_socket.send(b"Command not recognized.\r\n")

        except Exception as e:
            print(f"Error handling connection: {e}")
        finally:
            client_socket.close()

이 클래스에는 중요한 정보가 많이 포함되어 있으므로 각 기능을 하나씩 살펴보겠습니다.

__init__ 함수는 우리가 허니팟을 호스팅할 IP 및 포트 번호와 로그 파일의 경로 / 파일 이름을 기록합니다. 또한 허니팟에 대한 총 활성 연결 수를 기록할 것입니다.

log_activity 함수는 IP, 데이터 및 IP가 연결을 시도한 포트에 대한 정보를 수신합니다. 그런 다음 이 정보를 JSON 형식의 로그 파일에 추가합니다.

handle_connection 함수는 우리가 갖고 있는 다양한 포트에서 실행될 이러한 서비스를 모방할 것입니다. 허니팟은 포트 21, 22, 80 및 443에서 실행됩니다. 이러한 서비스는 각각 FTP, SSH, HTTP 및 HTTPS 프로토콜을 위한 것입니다. 따라서 허니팟과 상호작용하려는 공격자는 이러한 포트에서 이러한 서비스를 기대해야 합니다.

이러한 서비스의 동작을 모방하기 위해 실제로 사용되는 서비스 배너를 사용할 것입니다. 이 함수는 공격자가 연결할 때 적절한 배너를 먼저 전송한 다음 데이터를 수신하고 기록합니다. 허니팟은 또한 공격자에게 “명령을 인식할 수 없습니다”라는 가짜 응답을 보냅니다.

네트워크 리스너 구현

이제 들어오는 연결을 처리할 네트워크 리스너를 구현해 보겠습니다. 이를 위해 간단한 소켓 프로그래밍을 사용할 것입니다. 소켓 프로그래밍이 어떻게 작동하는지 잘 모른다면, 이 기사를 확인해 보세요에서 관련 개념을 설명하고 있습니다.

def start_listener(self, port):
    """Start a listener on specified port"""
    try:
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((self.bind_ip, port))
        server.listen(5)

        print(f"[*] Listening on {self.bind_ip}:{port}")

        while True:
            client, addr = server.accept()
            print(f"[*] Accepted connection from {addr[0]}:{addr[1]}")

            # 별도의 스레드에서 연결 처리하기
            client_handler = threading.Thread(
                target=self.handle_connection,
                args=(client, addr[0], port)
            )
            client_handler.start()

    except Exception as e:
        print(f"Error starting listener on port {port}: {e}")

start_listener 함수는 서버를 시작하고 제공된 포트에서 수신 대기합니다. 우리의 bind_ip0.0.0.0으로, 이는 서버가 모든 네트워크 인터페이스에서 수신 대기하고 있음을 나타냅니다.

이제 우리는 각 새로운 연결을 별도의 스레드에서 처리할 것입니다. 왜냐하면 여러 공격자가 허니팟과 상호 작용을 시도하거나 공격 스크립트나 도구가 허니팟을 스캔하는 경우가 있을 수 있기 때문입니다. 스레딩이 어떻게 작동하는지 잘 모른다면 이 기사를 확인해 보세요에서 Python의 스레딩과 동시성에 대해 설명하고 있습니다.

또한 이 함수를 핵심 Honeypot 클래스에 넣는 것을 잊지 마세요.

허니팟 실행하기

이제 우리의 허니팟을 시작할 main 함수를 만들어 보겠습니다.

def main():
    honeypot = Honeypot()

    # 각 포트에 대해 별도의 스레드에서 리스너 시작하기
    for port in honeypot.ports:
        listener_thread = threading.Thread(
            target=honeypot.start_listener,
            args=(port,)
        )
        listener_thread.daemon = True
        listener_thread.start()

    try:
        # 메인 스레드를 살아 있게 유지하기
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("\n[*] Shutting down honeypot...")
        sys.exit(0)

if __name__ == "__main__":
    main()

이 함수는 Honeypot 클래스를 인스턴스화하고 정의된 각 포트(21, 22, 80, 443)에 대한 리스너를 별도의 스레드로 시작합니다. 이제 우리의 실제 프로그램을 실행 중인 메인 스레드를 무한 루프에 넣어 계속 활성 상태로 유지할 것입니다. 이 모든 것을 스크립트로 작성하고 실행하세요.

허니팟 공격 시뮬레이터 작성하기

이제 일부 공격 시나리오를 시뮬레이션하여 허니팟을 목표로 삼아 JSON 로그 파일에 데이터를 수집해 보겠습니다.

이 시뮬레이터는 허니팟에 대한 몇 가지 중요한 측면을 보여주는 데 도움이 될 것입니다:

  1. 현실적인 공격 패턴: 시뮬레이터는 포트 스캐닝, 무차별 대입 시도 및 서비스별 익스플로잇과 같은 일반적인 공격 패턴을 시뮬레이션합니다.

  2. 변화하는 강도: 시뮬레이터는 시뮬레이션의 강도를 조정하여 허니팟이 다양한 부하를 처리하는 방식을 테스트합니다.

  3. 여러 공격 유형: 실제 공격자가 시도할 수 있는 다양한 유형의 공격을 보여주어 허니팟이 각 공격에 어떻게 반응하는지 이해하는 데 도움을 줍니다.

  4. 동시 연결: 시뮬레이터는 스레딩을 사용하여 귀하의 허니팟이 여러 개의 동시 연결을 처리하는 방식을 테스트합니다.

# honeypot_simulator.py

import socket
import time
import random
import threading
from concurrent.futures import ThreadPoolExecutor
import argparse

class HoneypotSimulator:
    """
    A class to simulate different types of connections and attacks against our honeypot.
    This helps in testing the honeypot's logging and response capabilities.
    """

    def __init__(self, target_ip="127.0.0.1", intensity="medium"):
        # 시뮬레이터를 위한 설정
        self.target_ip = target_ip
        self.intensity = intensity

        # 공격자가 자주 탐색하는 일반 포트
        self.target_ports = [21, 22, 23, 25, 80, 443, 3306, 5432]

        # 다양한 서비스에 대해 공격자가 사용하는 일반 명령어의 사전
        self.attack_patterns = {
            21: [  # FTP 명령어
                "USER admin\r\n",
                "PASS admin123\r\n",
                "LIST\r\n",
                "STOR malware.exe\r\n"
            ],
            22: [  # SSH 시도
                "SSH-2.0-OpenSSH_7.9\r\n",
                "admin:password123\n",
                "root:toor\n"
            ],
            80: [  # HTTP 요청
                "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n",
                "POST /admin HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n\r\n",
                "GET /wp-admin HTTP/1.1\r\nHost: localhost\r\n\r\n"
            ]
        }

        # 강도 설정은 시뮬레이션된 공격의 빈도와 양에 영향을 미칩니다
        self.intensity_settings = {
            "low": {"max_threads": 2, "delay_range": (1, 3)},
            "medium": {"max_threads": 5, "delay_range": (0.5, 1.5)},
            "high": {"max_threads": 10, "delay_range": (0.1, 0.5)}
        }

    def simulate_connection(self, port):
        """
        Simulates a connection attempt to a specific port with realistic attack patterns
        """
        try:
            # 새로운 소켓 연결 생성
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(3)

            print(f"[*] Attempting connection to {self.target_ip}:{port}")
            sock.connect((self.target_ip, port))

            # 배너가 있을 경우 가져오기
            banner = sock.recv(1024)
            print(f"[+] Received banner from port {port}: {banner.decode('utf-8', 'ignore').strip()}")

            # 포트에 따라 공격 패턴 전송
            if port in self.attack_patterns:
                for command in self.attack_patterns[port]:
                    print(f"[*] Sending command to port {port}: {command.strip()}")
                    sock.send(command.encode())

                    # 응답 대기
                    try:
                        response = sock.recv(1024)
                        print(f"[+] Received response: {response.decode('utf-8', 'ignore').strip()}")
                    except socket.timeout:
                        print(f"[-] No response received from port {port}")

                    # 명령어 사이에 현실적인 지연 추가
                    time.sleep(random.uniform(*self.intensity_settings[self.intensity]["delay_range"]))

            sock.close()

        except ConnectionRefusedError:
            print(f"[-] Connection refused on port {port}")
        except socket.timeout:
            print(f"[-] Connection timeout on port {port}")
        except Exception as e:
            print(f"[-] Error connecting to port {port}: {e}")

    def simulate_port_scan(self):
        """
        Simulates a basic port scan across common ports
        """
        print(f"\n[*] Starting port scan simulation against {self.target_ip}")
        for port in self.target_ports:
            self.simulate_connection(port)
            time.sleep(random.uniform(0.1, 0.3))

    def simulate_brute_force(self, port):
        """
        Simulates a brute force attack against a specific service
        """
        common_usernames = ["admin", "root", "user", "test"]
        common_passwords = ["password123", "admin123", "123456", "root"]

        print(f"\n[*] Starting brute force simulation against port {port}")

        for username in common_usernames:
            for password in common_passwords:
                try:
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(2)
                    sock.connect((self.target_ip, port))

                    if port == 21:  # FTP
                        sock.send(f"USER {username}\r\n".encode())
                        sock.recv(1024)
                        sock.send(f"PASS {password}\r\n".encode())
                    elif port == 22:  # SSH
                        sock.send(f"{username}:{password}\n".encode())

                    sock.close()
                    time.sleep(random.uniform(0.1, 0.3))

                except Exception as e:
                    print(f"[-] Error in brute force attempt: {e}")

    def run_continuous_simulation(self, duration=300):
        """
        Runs a continuous simulation for a specified duration
        """
        print(f"\n[*] Starting continuous simulation for {duration} seconds")
        print(f"[*] Intensity level: {self.intensity}")

        end_time = time.time() + duration

        with ThreadPoolExecutor(
            max_workers=self.intensity_settings[self.intensity]["max_threads"]
        ) as executor:
            while time.time() < end_time:
                # 다양한 공격 패턴 혼합
                simulation_choices = [
                    lambda: self.simulate_port_scan(),
                    lambda: self.simulate_brute_force(21),
                    lambda: self.simulate_brute_force(22),
                    lambda: self.simulate_connection(80)
                ]

                # 무작위로 공격 패턴 선택 및 실행
                executor.submit(random.choice(simulation_choices))
                time.sleep(random.uniform(*self.intensity_settings[self.intensity]["delay_range"]))

def main():
    """
    Main function to run the honeypot simulator with command-line arguments
    """
    parser = argparse.ArgumentParser(description="Honeypot Attack Simulator")
    parser.add_argument("--target", default="127.0.0.1", help="Target IP address")
    parser.add_argument(
        "--intensity",
        choices=["low", "medium", "high"],
        default="medium",
        help="Simulation intensity level"
    )
    parser.add_argument(
        "--duration",
        type=int,
        default=300,
        help="Simulation duration in seconds"
    )

    args = parser.parse_args()

    simulator = HoneypotSimulator(args.target, args.intensity)

    try:
        simulator.run_continuous_simulation(args.duration)
    except KeyboardInterrupt:
        print("\n[*] Simulation interrupted by user")
    except Exception as e:
        print(f"[-] Simulation error: {e}")
    finally:
        print("\n[*] Simulation complete")

if __name__ == "__main__":
    main()

이 시뮬레이션 스크립트에서 많은 작업이 진행되고 있으므로, 하나씩 나눠서 설명하겠습니다. 코드의 가독성을 높이기 위해 모든 함수와 작업에 대한 주석도 추가했습니다.

먼저 HoneypotSimulator라는 유틸리티 클래스를 소개합니다. 이 클래스에는 시뮬레이터의 기본 구성을 설정하는 __init__ 함수가 있습니다. 이 함수는 두 개의 매개변수를 받습니다: 대상 IP 주소(기본값은 localhost)와 강도 수준(기본값은 “medium”)입니다.

우리는 또한 세 가지 중요한 구성 요소를 정의합니다: 조사할 대상 포트(FTP, SSH, HTTP와 같은 일반 서비스), 각 서비스에 특정한 공격 패턴(로그인 시도 및 명령 등), 그리고 스레드 수와 타이밍 지연을 통해 시뮬레이션의 공격성을 제어하는 강도 설정입니다.

simulate_connection 함수는 특정 포트에 대한 개별 연결 시도를 처리합니다. 이 함수는 소켓 연결을 생성하고, 서비스 배너(예: SSH 버전 정보)를 가져오려고 시도한 후, 서비스 유형에 따라 적절한 공격 명령을 전송합니다. 우리는 일반적인 네트워크 문제에 대한 오류 처리를 추가했으며, 인간 상호작용을 모방하기 위해 명령 간에 현실적인 지연을 추가했습니다.

simulate_port_scan 함수는 정찰 도구처럼 작동하며, 우리의 대상 목록에 있는 각 포트를 체계적으로 점검합니다. 이는 nmap와 같은 도구가 작동하는 방식과 유사하며, 사용 가능한 서비스가 무엇인지 확인하기 위해 포트를 하나씩 검사합니다. 각 포트에 대해 simulate_connection 함수를 호출하고 스캔 패턴이 더욱 자연스럽게 보이도록 작은 랜덤 지연을 추가합니다.

simulate_brute_force 함수는 일반적인 사용자 이름과 비밀번호 목록을 유지하며, FTP 및 SSH와 같은 서비스에 대해 다양한 조합을 시도합니다. 각 시도마다 새로운 연결을 생성하고, 해당 서비스에 맞는 형식으로 로그인 자격 증명을 전송한 후 연결을 종료합니다. 이를 통해 우리는 허니팟이 자격 증명 스터핑 공격을 얼마나 잘 탐지하고 기록하는지 테스트할 수 있습니다.

run_continuous_simulation 함수는 지정된 기간 동안 실행되며, 포트 스캐닝, 무차별 대입 또는 특정 서비스 공격과 같은 다양한 공격 유형 중에서 무작위로 선택합니다. 지정된 강도 수준에 따라 여러 공격을 동시에 실행하기 위해 Python의 ThreadPoolExecutor를 사용합니다.

마지막으로, 우리는 시뮬레이터에 대한 명령줄 인터페이스를 제공하는 main 함수를 가지고 있습니다. 이 함수는 argparse를 사용하여 명령줄 인수를 처리하고, 사용자가 대상 IP, 강도 수준 및 시뮬레이션 기간을 지정할 수 있도록 합니다. HoneypotSimulator 클래스의 인스턴스를 생성하고, 사용자 중단 및 오류를 적절히 처리하는 등 전체 실행을 관리합니다.

시뮬레이터 코드를 별도의 스크립트에 넣은 후, 다음 명령으로 실행하십시오:

# 기본 설정으로 실행 (중간 강도, 로컬호스트, 5분)
python honeypot_simulator.py

# 사용자 지정 설정으로 실행
python honeypot_simulator.py --target 192.168.1.100 --intensity high --duration 600

우리가 동일한 머신에서 허니팟과 시뮬레이터를 실행하고 있기 때문에 대상은 localhost가 될 것입니다. 그러나 실제 시나리오에서 또는 허니팟을 VM이나 다른 머신에서 실행하는 경우에는 다른 것이 될 수 있으므로, 시뮬레이터를 실행하기 전에 IP를 확인하는 것이 중요합니다.

허니팟 데이터 분석 방법

허니팟이 수집한 모든 데이터를 분석할 수 있도록 도와주는 헬퍼 함수를 빠르게 작성해 보겠습니다. 이 데이터를 JSON 로그 파일에 저장했기 때문에 내장된 JSON 패키지를 사용하여 편리하게 파싱할 수 있습니다.

import datetime
import json

def analyze_logs(log_file):
    """Enhanced honeypot log analysis with temporal and behavioral patterns"""
    ip_analysis = {}
    port_analysis = {}
    hourly_attacks = {}
    data_patterns = {}

    # 세션 패턴 추적
    ip_sessions = {}
    attack_timeline = []

    with open(log_file, 'r') as f:
        for line in f:
            try:
                activity = json.loads(line)
                timestamp = datetime.datetime.fromisoformat(activity['timestamp'])
                ip = activity['remote_ip']
                port = activity['port']
                data = activity['data']

                # 새 IP 추적 초기화
                if ip not in ip_analysis:
                    ip_analysis[ip] = {
                        'total_attempts': 0,
                        'first_seen': timestamp,
                        'last_seen': timestamp,
                        'targeted_ports': set(),
                        'unique_payloads': set(),
                        'session_count': 0
                    }

                # IP 통계 업데이트
                ip_analysis[ip]['total_attempts'] += 1
                ip_analysis[ip]['last_seen'] = timestamp
                ip_analysis[ip]['targeted_ports'].add(port)
                ip_analysis[ip]['unique_payloads'].add(data.strip())

                # 시간별 패턴 추적
                hour = timestamp.hour
                hourly_attacks[hour] = hourly_attacks.get(hour, 0) + 1

                # 포트 타겟팅 패턴 분석
                if port not in port_analysis:
                    port_analysis[port] = {
                        'total_attempts': 0,
                        'unique_ips': set(),
                        'unique_payloads': set()
                    }
                port_analysis[port]['total_attempts'] += 1
                port_analysis[port]['unique_ips'].add(ip)
                port_analysis[port]['unique_payloads'].add(data.strip())

                # 페이로드 패턴 추적
                if data.strip():
                    data_patterns[data.strip()] = data_patterns.get(data.strip(), 0) + 1

                # 공격 타임라인 추적
                attack_timeline.append({
                    'timestamp': timestamp,
                    'ip': ip,
                    'port': port
                })

            except (json.JSONDecodeError, KeyError) as e:
                continue

    # 분석 보고서 생성
    print("\n=== Honeypot Analysis Report ===")

    # 1. IP 기반 분석
    print("\nTop 10 Most Active IPs:")
    sorted_ips = sorted(ip_analysis.items(), 
                       key=lambda x: x[1]['total_attempts'], 
                       reverse=True)[:10]
    for ip, stats in sorted_ips:
        duration = stats['last_seen'] - stats['first_seen']
        print(f"\nIP: {ip}")
        print(f"Total Attempts: {stats['total_attempts']}")
        print(f"Active Duration: {duration}")
        print(f"Unique Ports Targeted: {len(stats['targeted_ports'])}")
        print(f"Unique Payloads: {len(stats['unique_payloads'])}")

    # 2. 포트 분석
    print("\nPort Targeting Analysis:")
    sorted_ports = sorted(port_analysis.items(),
                         key=lambda x: x[1]['total_attempts'],
                         reverse=True)
    for port, stats in sorted_ports:
        print(f"\nPort {port}:")
        print(f"Total Attempts: {stats['total_attempts']}")
        print(f"Unique Attackers: {len(stats['unique_ips'])}")
        print(f"Unique Payloads: {len(stats['unique_payloads'])}")

    # 3. 시간적 분석
    print("\nHourly Attack Distribution:")
    for hour in sorted(hourly_attacks.keys()):
        print(f"Hour {hour:02d}: {hourly_attacks[hour]} attempts")

    # 4. 공격 정교화 분석
    print("\nAttacker Sophistication Analysis:")
    for ip, stats in sorted_ips:
        sophistication_score = (
            len(stats['targeted_ports']) * 0.4 +  # 포트 다양성
            len(stats['unique_payloads']) * 0.6   # 페이로드 다양성
        )
        print(f"IP {ip}: Sophistication Score {sophistication_score:.2f}")

    # 5. 일반 페이로드 패턴
    print("\nTop 10 Most Common Payloads:")
    sorted_payloads = sorted(data_patterns.items(),
                            key=lambda x: x[1],
                            reverse=True)[:10]
    for payload, count in sorted_payloads:
        if len(payload) > 50:  # 긴 페이로드 잘라내기
            payload = payload[:50] + "..."
        print(f"Count {count}: {payload}")

이것을 별도의 스크립트 파일에 넣고 JSON 로그에서 함수를 호출할 수 있습니다. 이 함수는 수집된 데이터를 기반으로 JSON 파일에서 포괄적인 통찰력을 제공할 것입니다.

우리의 분석은 IP 기반 통계, 포트 타겟팅 패턴, 시간대별 공격 분포 및 페이로드 특성과 같은 여러 범주로 데이터를 그룹화하는 것으로 시작됩니다. 각 IP에 대해 총 시도 횟수, 처음 및 마지막으로 확인된 시간, 타겟 포트 및 고유 페이로드를 추적하고 있습니다. 이를 통해 공격자에 대한 고유한 프로파일을 구축하는 데 도움이 될 것입니다.

우리는 또한 가장 빈번하게 타겟팅된 포트를 모니터링하고 고유한 공격자가 몇 명인지 확인하는 포트 기반 공격 패턴을 분석합니다. 우리는 또한 타겟 공격자를 식별하는 데 도움이 되는 공격 정교화 분석을 수행하며, 여기에는 타겟 포트 및 사용된 고유 페이로드와 같은 요소를 고려합니다. 이 분석은 단순 스캐닝 활동과 정교한 공격을 구분하는 데 사용됩니다.

시간 분석은 시간대별 공격 시도의 패턴을 식별하는 데 도움이 되며, 공격 타이밍 및 잠재적인 자동 타겟팅 캠페인에서의 패턴을 드러냅니다. 마지막으로, 일반적으로 관찰되는 페이로드를 게시하여 일반적으로 발견되는 공격 문자열이나 명령을 식별합니다.

보안 고려사항

이 허니팟을 배포할 때 다음 보안 조치를 고려해야 합니다:

  1. 허니팟을 격리된 환경에서 실행하십시오. 일반적으로 VM 내에서 또는 NAT와 방화벽 뒤에 있는 로컬 머신에서 실행합니다.

  2. 허니팟을 최소한의 시스템 권한으로 실행하십시오(일반적으로 root가 아님). 이는 침해 시 위험을 줄이는 데 도움이 됩니다.

  3. 생산 수준 또는 연구용 허니팟으로 배포할 계획이 있다면 수집한 데이터에 주의하십시오. 이 데이터에는 맬웨어나 민감한 정보가 포함될 수 있습니다.

  4. 허니팟 환경에서 탈출 시도를 탐지하기 위한 강력한 모니터링 메커니즘을 구현하십시오.

결론

이를 통해 우리는 허니팟을 구축하고, 허니팟에 대한 공격을 시뮬레이션하는 시뮬레이터를 작성하였으며, 허니팟 로그에서 데이터를 분석하여 몇 가지 간단한 추론을 하였습니다. 이는 공격 및 방어 보안 개념을 이해하는 훌륭한 방법입니다. 이를 기반으로 더 복잡한 탐지 시스템을 구축하고 다음과 같은 기능을 추가하는 것을 고려할 수 있습니다:

  1. 공격 행동에 기반한 동적 서비스 에뮬레이션

  2. 수집된 허니팟 로그에 대한 보다 나은 추론 분석을 수행하는 위협 인텔리전스 시스템과의 통합

  3. 고급 로깅 메커니즘을 통해 IP, 포트 및 네트워크 데이터를 넘어 보다 포괄적인 로그 수집

  4. 공격 패턴을 감지하기 위해 머신 러닝 기능 추가

허니팟이 강력한 보안 도구이긴 하지만, 단독 방어선이 아닌 포괄적인 방어 보안 전략의 일부여야 한다는 점을 기억하세요.

허니팟의 작동 방식, 목적 및 약간의 파이썬 프로그래밍에 대해 배웠기를 바랍니다!