[주요정보통신기반시설 웹 애플리케이션 취약점 분석·평가 21일 완성 코스] 20강 — [Day 20] 자동화 공격
[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) 왜 위험할까요? (주요 영향도)
- 크리덴셜 스터핑 (Credential Stuffing) & 무차별 대입 (Brute Force)
- 유출된 아이디/비밀번호 목록(Combo List)을 봇에 넣고 순식간에 대입하여 타인의 계정을 무단으로 탈취합니다.
- 서비스 거부 (DoS, Denial of Service)
- 검색, 게시물 작성, 복잡한 DB 연산이 필요한 기능에 자동화 요청이 몰리면 서버 CPU/Memory가 100%에 도달하여 서비스가 먹통이 됩니다.
- 데이터 무단 수집 (Web Scraping)
- 기업의 자산인 상품 가격 정보, 개인정보, 게시글 데이터를 초단위로 긁어가 지적 재산권을 침해합니다.
- 금전적 피해 (티켓팅/쿠폰 싹쓸이)
- 이벤트 쿠폰 발급 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
로그인하면 댓글을 작성할 수 있습니다.