[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스] 20강 — [Day 20] 자동화 공격

⚡ 정다은 · 2026-10-10 14:00 · 조회 36

[Day 20] 자동화 공격 (Automated Attack) - 봇(Bot)과 무차별 요청을 막는 보안 설계

안녕하세요! Hackerstory 공부방의 IT/보안 튜터 정다은입니다. 👋

어느덧 **‘주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스’**의 20번째 시간입니다! 완주까지 단 하루만을 남겨두고 있네요. 끝까지 열정적으로 따라와 주신 여러분, 정말 대단합니다. 👍

오늘 우리가 학습할 주제는 [Day 20] 자동화 공격입니다.

웹 서비스가 아무리 유효성 검증을 잘하고 권한 분리를 잘해두었더라도, **"컴퓨터의 엄청난 처리 속도"**를 이용한 반복적인 요청을 제어하지 못한다면 서비스가 마비되거나 금전적·데이터적 큰 손실을 입을 수 있습니다.

오늘 강의를 통해 자동화 공격의 원리부터 실무 진단법, 그리고 효과적인 방어 기법(CAPTCHA, Rate Limiting)까지 완벽하게 파헤쳐 보겠습니다!


1. 개념 설명: 자동화 공격(Automated Attack)이란?

1) 자동화 공격의 정의

자동화 공격은 공격자가 매크로(Macro), 크롤러(Crawler), 파이썬 스크립트, Burp Suite Intruder와 같은 전문 도구를 활용하여 매우 짧은 시간 동안 수백~수만 번의 HTTP 요청을 자동·반복적으로 전송하는 공격 기법입니다.

서버가 정상적인 사용자의 요청과 자동화된 도구(Bot)의 요청을 구분하지 못하고, 단위 시간당 요청 횟수(Rate Limit)를 제한하지 않을 때 발생합니다.

[공격자 (Bot Script)] --(초당 1,000회의 로그인/조회 요청)--> [웹 서버 (제한 없음)]
                                                                  │
                                                        ┌─────────┴─────────┐
                                                        ▼                   ▼
                                                  [DB 과부하 / DoS]   [계정 탈취 / 데이터 유출]

2) 왜 위험할까요? (주요 영향도)

  1. 크리덴셜 스터핑 (Credential Stuffing) & 무차별 대입 (Brute Force)
    • 유출된 아이디/비밀번호 목록(Combo List)을 봇에 넣고 순식간에 대입하여 타인의 계정을 무단으로 탈취합니다.
  2. 서비스 거부 (DoS, Denial of Service)
    • 검색, 게시물 작성, 복잡한 DB 연산이 필요한 기능에 자동화 요청이 몰리면 서버 CPU/Memory가 100%에 도달하여 서비스가 먹통이 됩니다.
  3. 데이터 무단 수집 (Web Scraping)
    • 기업의 자산인 상품 가격 정보, 개인정보, 게시글 데이터를 초단위로 긁어가 지적 재산권을 침해합니다.
  4. 금전적 피해 (티켓팅/쿠폰 싹쓸이)
    • 이벤트 쿠폰 발급 API나 예매 시스템에 매크로를 돌려 정당한 이용자의 기회를 박탈하고 불법 전매(암표)로 이어집니다.

2. 취약점 진단 및 예시 코드로 이해하기

실무 진단에서는 주로 로그인, 회원가입, 비밀번호 찾기, 게시판 글쓰기, 검색, 쿠폰 입력 기능에 자동화 방지 메커니즘이 존재하는지 점검합니다.

vuln-scenario: 방어 메커니즘이 없는 로그인 API

다음은 자동화 공격에 무방비로 노출된 Node.js 기반의 로그인 처리 백엔드 예시 코드입니다.

// [취약한 코드 예시] - Rate Limiting이나 CAPTCHA가 없는 로그인 엔드포인트
app.post('/api/login', async (req, res) => {
    const { username, password } = req.body;

    // DB에서 사용자 조회
    const user = await db.findUser(username);
    
    if (user && await bcrypt.compare(password, user.password_hash)) {
        req.session.userId = user.id;
        return res.json({ status: "success", message: "로그인 성공" });
    } else {
        // 실패하더라도 아무런 횟수 제한이나 지연(Delay) 없이 에러 반환
        return res.status(401).json({ status: "fail", message: "아이디 또는 비밀번호가 일치하지 않습니다." });
    }
});

🤖 공격 예시: 파이썬(Python)을 이용한 무차별 대입 공격

공격자는 위와 같이 제한이 없는 API를 상대로 아래와 같이 간단한 스크립트를 작성해 1초 만에 수백 개의 비밀번호를 대입할 수 있습니다.

import requests

url = "http://example.com/api/login"
target_user = "admin"

# 비밀번호 사전 파일(dictionary)을 읽어서 자동화 공격 수행
with open("passwords.txt", "r") as f:
    for password in f:
        password = password.strip()
        data = {"username": target_user, "password": password}
        
        # 초당 수십~수백 번의 POST 요청 전송
        response = requests.post(url, json=data)
        
        if "성공" in response.text:
            print(f"[★] 비밀번호 발견! -> {password}")
            break

진단원 시점의 확인 방법:

  • Burp Suite의 Intruder 기능을 이용하여 동일한 IP/세션에서 짧은 시간 동안 100회 이상의 요청을 보냈을 때, **모든 요청이 차단 없이 정상 응답(200 OK 등)**을 반환한다면 **취약(Vulnerable)**으로 평가합니다.

3. 실무 보안 대책 및 대응 방안

자동화 공격을 막기 위해서는 사람과 프로그램(Bot)을 구분 기법과 요청의 빈도를 제어하는 기법을 병행해야 합니다.

1) Rate Limiting (요청 수 제한) 도입

서버 측에서 IP 주소, 계정 ID, 세션 ID 단위로 일정한 시간 동안 허용되는 최대 요청 수를 설정합니다.

  • Nginx 웹 서버 설정 예시:

    # IP당 초당 5개 요청으로 제한 (Zone 이름: login_limit)
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/s;
    
    server {
        location /api/login {
            # 버퍼 크기(burst)를 10으로 설정하고 초과 시 429 Too Many Requests 반환
            limit_req zone=login_limit burst=10 nodelay;
            proxy_pass http://backend_server;
        }
    }
    
  • Node.js (express-rate-limit) 설정 예시:

    const rateLimit = require('express-rate-limit');
    
    const loginLimiter = rateLimit({
        windowMs: 15 * 60 * 1000, // 15분
        max: 5, // 15분 동안 IP당 최대 5회 시도 가능
        message: { status: 429, message: "너무 많은 로그인 시도가 발생했습니다. 15분 후 다시 시도해주세요." }
    });
    
    // 로그인 라우터에 적용
    app.post('/api/login', loginLimiter, loginHandler);
    

2) CAPTCHA (캡차) 도입

사람은 쉽게 풀 수 있지만, 컴퓨터 스크립트는 해독하기 어려운 문제(문자 맞추기, 이미지 찾기 등)를 제시하여 자동화된 접근을 원천 차단합니다.

  • 최신 트렌드: 기존의 시각적 문자 입력 방식은 사용자 경험(UX)을 해치므로, 사용자 행동 패턴을 분석해 무단 인터렉션 없이 판별하는 Google reCAPTCHA v3나 Cloudflare Turnstile 사용을 권장합니다.
<!-- 프론트엔드: reCAPTCHA v2 예시 -->
<form action="/login" method="POST">
  <input type="text" name="username" />
  <input type="password" name="password" />
  <!-- CAPTCHA 위젯 -->
  <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">로그인</button>
</form>

⚠️ 주의사항: CAPTCHA 검증 로직은 반드시 백엔드 서버에서 Google/Cloudflare API 서버와 통신하여 검증 결과를 최종 확인해야 합니다. 프론트엔드 JavaScript 검증만 수행할 경우 공격자가 검증 로직을 우회할 수 있습니다!


3) 임계치 기반 임시 계정 잠금 (Account Lockout)

비밀번호 입력 5회 연속 실패 시 해당 계정을 30분간 잠그거나, 이메일/SMS 2차 인증을 거치도록 재설정합니다. (Credential Stuffing 방어에 필수)


4. 요약 및 정리

분류 핵심 내용
취약점 명 자동화 공격 (Automated Attack)
원인 반복적 요청에 대한 단위 시간당 횟수 제한(Rate Limit) 및 Bot 검증(CAPTCHA) 미흡
주요 공격 대상 로그인, 회원가입, 비밀번호 찾기, 게시판 작성, 쿠폰/예매, 검색 API
보안 대책 1. Rate Limiting 적용 (IP/계정별 요청 횟수 제한 - 429 Code 반환)<br>2. CAPTCHA 도입 (reCAPTCHA v3, Turnstile 등)<br>3. 계정 임시 잠금 정책 구현 (연속 N회 실패 시 차단)

🎓 튜터 다은의 한 줄 요약

"시스템 자원과 데이터는 무한하지 않습니다! 컴퓨터의 무시무시한 처리 속도에 브레이크를 걸어주는 Rate Limiting과 진짜 사람인지를 확인하는 CAPTCHA는 웹 서비스 문지기의 필수 덕목입니다."


🔮 다음 챕터 예고: [Day 21] 불필요한 Method 악용

드디어 내일, 21일 완성 코스의 대망의 마지막 강의가 기다리고 있습니다!

마지막날 다룰 주제는 [Day 21] 불필요한 Method 악용입니다. GET, POST 외에 웹 서버에 기본적으로 열려 있는 PUT, DELETE, OPTIONS, TRACE 등 불필요한 HTTP 메서드가 활성화되어 있을 때 발생할 수 있는 보안 위협(서버 파일 임의 수정 및 삭제, XST 공격 등)과 이를 깔끔하게 차단하는 웹 서버 설정법을 알아봅니다.

마지막까지 완주해서 멋진 웹 보안 진단 전문가로 거듭나봅시다! 수고 많으셨습니다. 내일 만나요! 하이파이브! 🖐️

댓글 0

로그인하면 댓글을 작성할 수 있습니다.