본문 바로가기
IT보안

[IT보안] Python으로 윈도우 서버 점검 및 멀웨어 탐지 자동화 스크립트 만들기

by 시스코킹 2025. 5. 15.
반응형

윈도우 서버 점검할 일이 많다 보니, 매번 수동으로 상태 체크하는 게 번거롭습니다.
그래서 자주 확인하는 항목들을 파이썬으로 자동화해봤습니다.

결과는 텍스트 파일로 바탕화면에 저장됩니다. 다음과 같은 주요 항목에 대해 점검이 가능합니다.

- 주요 점검 항목

1. CPU 및 메모리 사용량 확인

  • psutil 모듈을 활용하여 현재 CPU 사용률과 메모리 점유율을 실시간으로 측정합니다.
  • 과부하나 이상 징후 확인 시 활용 가능합니다.

2. 시스템 업타임 확인

  • 서버의 부팅 시간과 현재까지의 가동 시간을 계산하여 출력합니다.
  • 불안정한 서버 재시작 여부, 긴 가동시간 확인 등에 활용됩니다.

3. 로그인 실패 이벤트 확인

  • Windows Event Log의 보안 이벤트 ID 4625를 기준으로 최근 로그인 실패 내역을 최대 10건까지 조회합니다.
  • 비정상적인 접근 시도나 내부 계정 오남용에 대한 단서를 확보할 수 있습니다.

4. 서버 운영체제 및 버전 정보 출력

  • platform 모듈을 이용하여 OS 이름, 버전, 커널, CPU 정보 등을 출력합니다.
  • 시스템 사양 확인 및 취약점 점검 시 참고 자료로 활용할 수 있습니다.

5. 서버 IP 및 호스트 정보 확인

  • 현재 서버의 호스트명 및 연결된 IP 정보를 조회합니다.
  • 네트워크 진단, 접근 제어 정책 확인 시 유용합니다.

6. 악성코드 실행 여부 탐지

  • 현재 실행 중인 프로세스 목록을 기반으로, 미리 정의된 악성코드(랜섬웨어, 트로이 목마, 웜, 백도어 등)와의 이름 일치 여부를 판별합니다. 탐지 시 관련 항목을 메모장 에 표시하며, 탐지 매칭 여부를 알려줍니다.



- 자동화 방식 및 출력 결과

실행 예시 화면


출력 예시는 다음과 같습니다:
해당 스크립트는 Python 환경에서 실행되며, 점검 항목들을 순차적으로 수집한 뒤
결과를 텍스트 파일(서버점검결과.txt) 형식으로 바탕화면에 저장합니다.

-> 해당 코드로 실제 멀웨어 이름이 작업관리자에서 매칭되면 확인이 가능하나 실제 멀웨어가 알려진 이름이 아닌 다른 이름으로 동작한다면 탐지가 어려울 수도 있습니다.
해당 코드를 참고하셔서 멀웨어 리스트를 추가하시거나 수정하셔서 사용하시면 될 것 같습니다.

- 적용 효과는?

  • 점검 시간 단축: 클릭해서 하나하나 보는 대신 한 번에 자동으로 체크
  • 보안 이상 징후 빠르게 확인: 로그인 실패나 멀웨어 프로세스 탐지
  • 로그 남기기: 나중에 증빙용으로도 활용 가능
  • IT팀 내 공통 툴로 활용 가능: 다른 팀원에게 배포해서 다 같이 쓰기 좋음

 

- 개발 코드 및 주석

import os
import psutil  # 시스템 자원 정보 확인용
import platform  # OS 및 시스템 정보 확인용
import socket  # IP 및 호스트 정보 확인용
from datetime import datetime  # 시간 계산용
import win32evtlog  # 윈도우 이벤트 로그 접근용 (로그인 실패 확인)

# 바탕화면 경로 가져오기
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")

def save_to_desktop(filename, content):
    """입력된 문자열을 바탕화면에 파일로 저장하는 함수"""
    file_path = os.path.join(desktop_path, filename)
    try:
        with open(file_path, "w", encoding="utf-8") as file:
            file.write(content)
        print(f"\n[알림] 결과가 저장되었습니다: {file_path}")
    except Exception as e:
        print(f"파일 저장 오류: {e}")

# 1. CPU 및 메모리 사용량 확인
def check_cpu_memory_usage():
    """CPU 사용률과 메모리 점유율을 수집하여 문자열로 반환"""
    try:
        cpu_usage = psutil.cpu_percent(interval=1)  # 1초 간격으로 CPU 사용률 측정
        memory_info = psutil.virtual_memory()  # 전체 메모리 정보 획득
        result = "\n[CPU 및 메모리 사용량]\n"
        result += f"- CPU 사용량: {cpu_usage}%\n"
        result += f"- 메모리 사용량: {memory_info.percent}%\n"
        return result
    except Exception as e:
        return f"CPU/메모리 확인 오류: {e}"

# 2. 윈도우 업타임 확인
def get_uptime():
    """서버의 부팅 시간과 현재까지의 가동 시간(업타임)을 계산하여 반환"""
    boot_time = datetime.fromtimestamp(psutil.boot_time())  # 부팅 시간 (timestamp → datetime)
    uptime = datetime.now() - boot_time  # 현재 시각과의 차이 계산
    result = f"\n[서버 업타임]\n- 부팅 시간: {boot_time.strftime('%Y-%m-%d %H:%M:%S')}\n- 업타임: {str(uptime).split('.')[0]}\n"
    return result

# 3. 최근 로그인 실패 기록 확인
def get_failed_logins(max_records=10):
    """Windows 보안 로그에서 최근 로그인 실패 이벤트(4625)를 최대 max_records 개수만큼 조회"""
    try:
        server = "localhost"
        log_type = "Security"  # 보안 로그 접근
        log_handle = win32evtlog.OpenEventLog(server, log_type)
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        failed_logins = []
        while len(failed_logins) < max_records:
            events = win32evtlog.ReadEventLog(log_handle, flags, 0)
            if not events:
                break
            for event in events:
                if event.EventID == 4625:  # 로그인 실패 이벤트 ID
                    time = event.TimeGenerated.Format()  # 발생 시간
                    failed_logins.append(f"- 시간: {time}, 출처: {event.SourceName}, 카테고리: {event.EventCategory}")
                    if len(failed_logins) >= max_records:
                        break
        result = "\n[최근 로그인 실패 기록 (최대 10개)]\n" + "\n".join(failed_logins) if failed_logins else "\n로그인 실패 기록이 없습니다.\n"
        return result
    except Exception as e:
        return f"로그인 실패 기록 확인 오류: {e}"

# 4. 서버 버전 정보 확인
def get_server_version():
    """운영체제, 호스트 이름, 커널 버전 등 시스템 기본 정보를 반환"""
    os_info = platform.uname()
    result = f"\n[서버 버전 정보]\n- 시스템: {os_info.system}\n- 호스트 이름: {os_info.node}\n- 릴리즈: {os_info.release}\n- 버전: {os_info.version}\n- 머신: {os_info.machine}\n- 프로세서: {os_info.processor}\n"
    return result

# 5. IP 정보 확인
def get_ip_info():
    """호스트명과 함께 현재 서버의 IP 주소 목록 반환"""
    try:
        hostname = socket.gethostname()  # 현재 시스템의 호스트명
        ip_addresses = socket.gethostbyname_ex(hostname)[2]  # 연결된 IP 리스트
        result = f"\n[서버 IP 정보]\n- 호스트 이름: {hostname}\n"
        result += "\n".join([f"- IP: {ip}" for ip in ip_addresses])
        return result
    except Exception as e:
        return f"IP 정보 확인 오류: {e}"

# 6. 멀웨어 프로그램 실행 여부 확인
def check_malware_running():
    """사전 정의된 멀웨어 이름 목록과 현재 실행 중인 프로세스를 비교하여 실행 여부 탐지"""
    
    # 멀웨어 분류별 목록 정의
    malware_categories = {
        "Ransomware (랜섬웨어)": [...],
        "Trojan (트로이 목마)": [...],
        ...
        "Cryptojacking (암호화폐 채굴)": [...]
    }

    # 현재 실행 중인 프로세스 목록을 모두 조회 (소문자 변환)
    running_processes = [proc.name().lower() for proc in psutil.process_iter(['name'])]

    detection_results = []

    # 각 악성코드 카테고리별로 실행 여부 확인
    for category, programs in malware_categories.items():
        detected = [
            malware.lower() + ".exe" for malware in programs
            if (malware.lower() + ".exe") in running_processes
        ]
        if detected:
            # 실행 중인 악성코드가 있을 경우
            detection_results.append(f"\n[{category}] 탐지된 프로그램:")
            detection_results.extend([f"- {malware}" for malware in detected])
        else:
            # 없을 경우 ‘탐지 없음’ 표시 후 전체 목록 나열
            detection_results.append(f"\n[{category}] 탐지여부 없음!")
            detection_results.extend([f"{malware}" for malware in programs])

    return "\n".join(detection_results)

# 메인 실행부
if __name__ == "__main__":
    # 각 점검 항목 실행
    cpu_memory_result = check_cpu_memory_usage()
    uptime_result = get_uptime()
    failed_logins_result = get_failed_logins()
    server_version_result = get_server_version()
    ip_info_result = get_ip_info()
    malware_result = check_malware_running()

    # 전체 결과 문자열로 합침
    full_result = (
        cpu_memory_result + "\n" +
        uptime_result + "\n" +
        failed_logins_result + "\n" +
        server_version_result + "\n" +
        ip_info_result + "\n" +
        malware_result
    )
    
    # 바탕화면에 결과 파일로 저장
    save_to_desktop("서버점검결과.txt", full_result)

반응형

댓글