ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • what is Keylogging?
    What is 2025. 8. 9. 19:45

    “키보드에 입력하는 모든 걸 몰래 기록하는 기술”이 있다면, 그게 바로 키로깅입니다.
    오늘은 이 키로깅이 어떻게 생겼고, 어떻게 움직이며, 어떻게 막을 수 있는지 이야기해 드릴게요.

     

    키로깅이 뭐냐면요

    자, 여러분이 키보드로 글자를 치고 있다고 상상해 보세요.
    ‘a’, ‘b’, ‘c’… 그리고 스페이스바, 엔터 키, 심지어 백스페이스로 지운 것도 다 기록이 된다면 어떨까요?
    이걸 키로깅(Keylogging)이라고 부릅니다.

    원래는 키보드 테스트나 사용자 습관 분석 같은 합법적인 목적에도 쓰일 수 있습니다.
    하지만 악용되면 비밀번호, 주민번호, 카드번호 같은 민감한 정보를 그대로 훔쳐갈 수 있죠.


    종류는 두 가지입니다

    키로거(Keylogger)는 크게 소프트웨어형하드웨어형이 있어요.

    • 소프트웨어 키로거
      컴퓨터 안에서 프로그램처럼 돌아가며, 운영체제가 “이 키가 눌렸다”라고 알려주는 순간을 슬쩍 가로채서 기록합니다.
    • 하드웨어 키로거
      키보드와 컴퓨터 사이 케이블에 작은 USB/PS2 인라인 장치를 끼워두면, 거기에 입력 내용이 저장됩니다.
      물리적인 장치라서 설치 흔적이 거의 없어 눈치채기 어렵죠.

    이 글에서는 소프트웨어 키로거에 초점을 맞춥니다.


    어떻게 움직일까요?

    대부분의 키로거는 아래 순서를 밟습니다.

    1. 환경 준비
      “어디에 기록할까?” “어떤 내용을 기록할까?” 정하고 시작합니다.
    2. 키 입력 캡처
      키보드에서 눌린 글자, 특수키까지 하나하나 받아옵니다.
    3. 저장
      모은 내용을 파일이나 폴더에 기록해 둡니다.
    4. 외부 전송
      악성 키로거라면, 이 파일을 공격자의 서버로 보냅니다.
    5. 지속성 유지
      컴퓨터를 껐다 켜도 자동으로 다시 실행되도록 등록합니다.

    Python으로 키로깅 원리 체험하기

    아래 Python 예제는 실제 키보드 후킹이나 악성 행위를 전혀 하지 않고,
    단순히 ‘키로깅이 이런 흐름으로 동작할 수 있다’는 개념만 안전하게 체험할 수 있도록 만든 시뮬레이터입니다.

    흐름
    준비 → 입력 → 묶기 → 저장 → 전송 요약 → 지속성 등록

    0) 전체 흐름

    def main():
        ctx = initialize_context()          # 기본 설정/상태 준비
        events = capture_input_events(ctx)  # (개념) 키 입력 이벤트 스트림 확보
        chunk = chunk(events)    # 묶기
        path = persist_locally(chunk, ctx)  # 로컬 임시 저장
        summary_outbound(ctx)               # (개념) 외부 전송 요약/점검
        register_persistence(ctx)           # (개념) 재부팅 후 지속 실행 등록 개념
    
    if __name__ == "__main__":
        main()

     

    1) 초기화

    “무엇을 모으고, 어디에 둘지”
    def initialize_context():
        """
        목적:
          - 이후 단계에서 사용할 공통 설정과 저장 위치를 만든다.
        설명:
          - buffer_limit: 몇 개의 키 입력 이벤트를 묶을지 정하는 값
          - log_dir: 입력 데이터를 저장할 임시 폴더 경로
          - outbound_enabled: 외부 전송을 실제로 할지 여부 (여기서는 False로 설정)
          - target_host, beacon_secs: '전송한다면'의 가상 대상/주기 정보
        """
        temp_base = Path(tempfile.gettempdir()) / "concept_keylog_demo"
        temp_base.mkdir(parents=True, exist_ok=True)  # 임시 폴더 만들기
        return {
            "buffer_limit": 50,
            "log_dir": str(temp_base),
            "outbound_enabled": False,
            "target_host": "example.org",
            "beacon_secs": 60,
        }

    2) 입력 이벤트 캡처

    “키 입력이 이렇게 들어온다고 가정”

    def capture_input_events(context):
        """
        목적:
          - 실제 키로거처럼 운영체제에서 키 입력을 잡아오는 대신,
            사용자가 콘솔에 입력한 내용을 키 이벤트 리스트로 변환
        반환:
          - ["H", "e", "l", "l", "o", "Space", "1", ...] 형태의 리스트
        """
        print("입력할 텍스트를 한 줄 써주세요. (엔터를 누르면 수집 종료)")
        line = sys.stdin.readline()
        if not line:
            return []
        line = line.rstrip("\n")  # 마지막 줄바꿈 제거
        events = []
        for ch in line:
            if ch == " ":
                events.append("Space")  # 공백은 'Space'로 기록
            elif ch == "\t":
                events.append("Tab")    # 탭은 'Tab'으로 기록
            else:
                events.append(ch)       # 나머지는 그대로 기록
        events.append("Enter")          # 마지막에 엔터 표시 추가
        return events

    3) 청크(묶기)

    “덩어리로 묶는다”

    def chunk_events(events):
        """
        목적:
          - 개별 키 이벤트를 하나의 문자열로 합친다.
          - 예: ["H", "i", "Space", "T", "e", "s", "t", "Enter"]
            → "H i Space T e s t Enter"
        """
        return " ".join(events)

    4) 로컬 임시 저장

    “임시로 파일에 둔다고 치면 이런 경로가 된다”

     
    def persist_locally(chunk, context):
        """
        목적:
          - 만든 청크를 임시 폴더에 로그 파일로 저장
          - 저장된 경로를 반환
        """
        ts = datetime.now().strftime("%Y%m%d_%H%M%S")  # 현재 시각으로 파일명 만들기
        path = Path(context["log_dir"]) / f"chunk_{ts}.log"
        path.write_text(chunk, encoding="utf-8")       # 내용 저장
        return str(path)

    5) 외부 전송 요약

    “외부로 보낸다면 이런 방법이 필요하다”
    def summary_outbound(context):
        """
        목적:
          - 외부 서버로 보낼 때 어떤 설정이 필요한지 '요약'만 출력
          - 실제 전송은 하지 않는다.
        """
        size = len(chunk.encode("utf-8"))
        print(f"[요약] outbound 준비: 대상={context['target_host']}, 주기={context['beacon_secs']}s, 크기≈{size}B (전송 안 함)")

    6) 지속성 등록(개념)

    “다음 부팅에도 돌아가게 등록할 수 있다”

    def register_persistence(context):
        """
        목적:
          - '다음 부팅 시 자동 실행' 개념을 설명하기 위한 메모 파일 작성
          - 실제로 OS 설정을 바꾸진 않는다.
        """
        note = Path(context["log_dir"]) / "persistence_simulated.txt"
        note.write_text(
            "이 파일은 '지속성' 개념을 설명하기 위한 메모입니다.\n"
            "실제 자동 실행 등록은 수행하지 않았습니다.\n"
            f"기록 시각: {datetime.now().isoformat()}\n",
            encoding="utf-8",
        )
        return str(note)

     

     


    폼 그래빙(Form Grabbing)과의 차이

    가끔 키로깅과 폼 그래빙을 헷갈리는데요,

    • 키로깅은 “키를 누른 순간”을 기록
    • 폼그랩은 “입력칸 내용을 전송하기 직전”, 브라우저 메모리에서 입력칸 내용을 낚아채는 방식입니다.
      두 기술이 함께 쓰이면, 입력 과정과 완성된 내용을 모두 훔칠 수 있습니다.

    진짜 사례를 보면…

    • FormBook / XLoader: 이메일 첨부파일로 퍼져서 키 입력과 폼 데이터를 훔쳤습니다.
    • Agent Tesla: 키로깅은 물론, 브라우저와 메일 비밀번호까지 탈취했습니다.
    • Hawkeye Keylogger: 키와 마우스 클릭을 기록하고 이메일로 전송했습니다.

    공통점은 입력 → 저장 → 전송 → 자동 실행 등록으로 오래 숨어있다는 겁니다.


    어떻게 눈치챌까요?

    • 컴퓨터 켤 때 자동 실행되는 목록에 모르는 프로그램이 있다면 의심
    • 작업 관리자에서 이상한 프로세스가 계속 실행 중이라면 주목
    • 알 수 없는 프로그램이 특정 서버와 주기적으로 통신하고 있다면 경계
    • 폴더 안에서 이상한 로그 파일이 주기적으로 생겼다 사라진다면 확인 필요

    막는 방법은 의외로 기본적입니다

    • 운영체제와 프로그램 업데이트를 항상 최신으로
    • 출처 불명의 파일, 특히 메일 첨부는 열지 않기
    • 백신과 실시간 보호를 켜 두기
    • 중요한 계정에는 2단계 인증을 걸어두기

    'What is' 카테고리의 다른 글

    What is Hooking?  (4) 2025.08.13
    what is Rooting?  (2) 2025.08.11
    what is HSTS(HTTP Strict Transport Security)?  (2) 2025.08.09
Designed by Tistory.