COMMENTS (0)
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
User-Agent 조작만으로는 부족하다. JavaScript 환경, Canvas 핑거프린트까지 위조해야 네트워크 탐지를 우회하는 3단계 구조.
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
전 세계 웹 트래픽의 대부분이 브라우저를 통해 발생한다. 각 브라우저는 고유한 "지문"을 남긴다. User-Agent 문자열, 화면 해상도, 시간대, 언어 설정 등 수십 가지 속성이 이 지문을 구성한다. 공격자들은 이 지문을 조작해 정상 사용자로 위장하고 보안 탐지를 우회한다.
초기 웹에서는 IP 주소만으로 사용자를 식별했다. NAT, VPN, 프록시가 일반화되면서 IP만으로는 실제 사용자를 구별하기 어려워졌다. 보안 업계는 브라우저 메타데이터를 조합해 "디지털 지문"을 만드는 기술을 개발했다.
문제는 이 기술이 양날의 검이라는 점이다. 정당한 보안 목적으로 개발된 기술을 공격자들이 역으로 악용하기 시작했다. 자신의 실제 브라우저 환경을 숨기고 정상 사용자의 지문을 모방하는 방법이다.
악성 트래픽 차단에는 주로 IP 블랙리스트를 사용했다. 이 방식에는 근본적 한계가 있었다.
이 한계를 해결하기 위해 브라우저 메타데이터에 주목했다. 하나의 웹 요청에는 IP 외에도 수십 가지 정보가 포함된다. User-Agent, Accept-Language, 화면 해상도, 시간대, 설치된 폰트 목록 등이다. 이들을 조합하면 개별 사용자를 높은 정확도로 식별할 수 있었다.
T1036.012 Browser Fingerprint는 브라우저 및 시스템 속성을 위조해 정상 웹 트래픽으로 위장하는 기법이다. User-Agent, OS 정보, 언어, 플랫폼, 화면 해상도, 시간대 등이 위조 대상이다.
Adversaries may alter their browser fingerprint to avoid detection and evade security controls. Browser fingerprinting is a method of tracking web users by collecting information about their web browser and computing environment. — MITRE ATT&CK T1036.012
공격자는 탐지를 피하기 위해 브라우저 지문을 변조한다. 브라우저 지문채취는 브라우저와 컴퓨팅 환경 정보로 웹 사용자를 추적하는 방법이다.
브라우저 핑거프린트 위조는 다음 5가지 요소로 구성된다.
| 용어 | 설명 |
|---|---|
| Browser Fingerprint | 브라우저 환경의 종합적 특성. HTTP 헤더 + JavaScript로 수집. 위조 난이도 높음 |
| User-Agent | 브라우저와 OS 식별 문자열. HTTP 헤더만으로 수집. 위조 난이도 낮음 |
| Device Fingerprint | 하드웨어 기반 고유 식별자. Canvas, WebGL, 오디오로 수집. 위조 난이도 최고 |
| IP Reputation | IP 주소 기반 신뢰도 평가. 네트워크 계층에서 수집. 위조 난이도 낮음 |
| Behavioral Analysis | 사용자 행동 패턴 분석. 마우스, 키보드, 타이밍으로 수집. 위조 난이도 최고 |
브라우저 핑거프린트 위조는 3단계로 진행된다.
시스템 정보 탐색
공격자는 먼저 대상 환경의 일반적인 브라우저 구성을 파악한다.
공개 통계 활용:
// 대상 조직의 일반적인 브라우저 환경 조사
const targetProfile = {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
language: "ko-KR",
timezone: "Asia/Seoul",
screen: "1920x1080",
platform: "Win32"
};
소셜 엔지니어링을 통한 정보 수집: 대상 사용자를 자신이 제어하는 웹사이트로 유도한다. 실제 브라우저 환경 정보를 수집하는 방법이다.
// 공격자 제어 웹사이트에서 실행되는 정보 수집 스크립트
function collectFingerprint() {
return {
userAgent: navigator.userAgent,
language: navigator.language,
platform: navigator.platform,
screen: `${screen.width}x${screen.height}`,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
fonts: detectInstalledFonts(), // 설치된 폰트 탐지
plugins: Array.from(navigator.plugins).map(p => p.name)
};
}
User-Agent 문자열 조작
User-Agent는 가장 기본적이면서도 중요한 위조 대상이다. RFC 9110의 정의를 보자.
The "User-Agent" header field contains information about the user agent originating the request, which is often used by servers to help identify the scope of reported interoperability problems. — RFC 9110 Section 10.1.5
공격자는 이 정보를 조작해 실제 환경을 숨긴다.
import requests
# 실제 공격자 환경 (Linux + 자동화 도구)
real_headers = {
'User-Agent': 'python-requests/2.28.1'
}
# 위조된 정상 사용자 환경 (Windows + Chrome)
fake_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'ko-KR,ko;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
# 위조된 지문으로 요청 전송
response = requests.get('https://target.com', headers=fake_headers)
HTTP 헤더 일관성 유지
User-Agent만 바꾸는 것으로는 부족하다. 브라우저마다 전송하는 HTTP 헤더의 순서와 값이 다르다. 전체적인 일관성을 유지해야 한다.
GET / HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ko-KR,ko;q=0.9
Accept-Encoding: gzip, deflate, br
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
JavaScript 환경 위조
최신 지문채취 시스템은 JavaScript로 더 정밀한 정보를 수집한다. 공격자는 JavaScript 환경도 조작해야 우회할 수 있다.
// 화면 해상도 위조
Object.defineProperty(screen, 'width', {
get: function() { return 1920; }
});
Object.defineProperty(screen, 'height', {
get: function() { return 1080; }
});
// 시간대 위조
Date.prototype.getTimezoneOffset = function() {
return -540; // UTC+9 (한국 시간)
};
// 언어 설정 위조
Object.defineProperty(navigator, 'language', {
get: function() { return 'ko-KR'; }
});
// Canvas 지문 위조 (더 고급 기법)
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() {
// 미리 계산된 정상 사용자의 Canvas 지문 반환
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAA...';
};
점진적 접근
대량 요청은 즉시 탐지된다. 공격자는 정상 사용자 패턴을 모방해 점진적으로 접근한다.
import time
import random
def gradual_attack():
"""정상 사용자 패턴을 모방한 점진적 공격"""
# 정상 사용자의 요청 간격 시뮬레이션 (2-10초)
for i in range(100):
# 위조된 지문으로 요청
response = make_request_with_fake_fingerprint()
# 인간적인 간격 시뮬레이션
delay = random.uniform(2, 10)
time.sleep(delay)
# 응답 분석 후 다음 단계 결정
if is_blocked(response):
# 탐지되면 지문 변경
switch_fingerprint()
다중 지문 로테이션
하나의 위조 지문만 쓰면 패턴이 드러난다. 여러 개의 서로 다른 지문을 순환 사용하는 방법이다.
fingerprint_pool = [
{ # 프로필 1: Windows + Chrome 사용자
'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'language': 'ko-KR',
'timezone': 'Asia/Seoul'
},
{ # 프로필 2: macOS + Safari 사용자
'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15',
'language': 'en-US',
'timezone': 'America/New_York'
},
{ # 프로필 3: Android + Chrome 사용자
'user_agent': 'Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36',
'language': 'ko-KR',
'timezone': 'Asia/Seoul'
}
]
def rotate_fingerprint():
"""지문을 순환하여 탐지 회피"""
current_profile = random.choice(fingerprint_pool)
return current_profile
카페에서 다른 사람의 신분증을 빌려 쓰는 것과 같다. 진짜 신분증(정상 사용자의 브라우저 지문)이므로 출입 통제 시스템(보안 솔루션)이 의심하지 않는다. 실제로는 전혀 다른 사람(공격자)이 출입하는 것이다.
단일 지표 의존성
대부분의 보안 시스템은 User-Agent나 IP 같은 단일 지표에 의존한다. 공격자는 해당 지표만 조작하면 탐지를 우회할 수 있다.
공격자의 관점: "보안 시스템이 User-Agent만 확인한다면, 이것만 바꾸면 된다"
정적 규칙 기반 탐지의 한계
많은 보안 솔루션이 "python-requests", "curl" 같은 자동화 도구의 User-Agent를 블랙리스트로 관리한다. 공격자는 정상 브라우저의 User-Agent를 복사해 정적 규칙을 우회한다.
신용카드 사기 탐지 우회
온라인 쇼핑몰은 사기 거래 탐지에 브라우저 지문채취를 사용한다. 공격자는 다음과 같이 우회한다.
# 사기 탐지 시스템 우회를 위한 지문 위조
def bypass_fraud_detection():
"""정상 구매자 패턴 모방"""
# 1. 일반적인 쇼핑 패턴 시뮬레이션
browse_products() # 상품 둘러보기
add_to_cart() # 장바구니 담기
time.sleep(random.uniform(30, 120)) # 고민 시간
# 2. 정상 사용자 지문으로 결제 시도
fake_fingerprint = {
'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'screen': '1920x1080',
'timezone': 'Asia/Seoul',
'language': 'ko-KR'
}
purchase_with_fingerprint(fake_fingerprint)
계정 탈취 후 추적 회피
탈취한 계정에 평소와 다른 환경에서 접속하면 의심받는다. 피해자의 브라우저 환경을 모방해 이를 피한다.
// 피해자의 실제 브라우저 환경 정보 (사전 수집)
const victimProfile = {
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
language: "ko-KR",
timezone: "Asia/Seoul",
screen: "1920x1080",
fonts: ["Arial", "Malgun Gothic", "Segoe UI"]
};
// 공격자 환경을 피해자 환경으로 위장
function impersonateVictim() {
// User-Agent 변경
Object.defineProperty(navigator, 'userAgent', {
get: () => victimProfile.userAgent
});
// 기타 환경 정보 위조
Object.defineProperty(navigator, 'language', {
get: () => victimProfile.language
});
// 화면 해상도 위조
Object.defineProperty(screen, 'width', {
get: () => parseInt(victimProfile.screen.split('x')[0])
});
}
FatDuke APT 그룹
MITRE ATT&CK 문서에 따르면, FatDuke 악성코드는 손상된 사용자의 트래픽을 모방하려 시도했다. 정상 사용자의 브라우저 환경을 분석해 악성 트래픽을 위장한 사례다.
대규모 자동화 공격
웹 스크래핑, DDoS, 브루트포스 공격에서 탐지를 피하기 위해 브라우저 지문 위조를 사용한다.
# 대규모 자동화 공격에서의 지문 위조 예시
import random
from concurrent.futures import ThreadPoolExecutor
def automated_attack_with_rotation():
"""지문 로테이션을 통한 대규모 자동화 공격"""
# 수백 개의 서로 다른 브라우저 지문 생성
fingerprints = generate_diverse_fingerprints(500)
def attack_with_fingerprint(fingerprint):
# 각 스레드마다 다른 지문 사용
session = create_session_with_fingerprint(fingerprint)
# 공격 실행 (브루트포스, 스크래핑 등)
execute_attack(session)
# 다중 스레드로 동시 공격
with ThreadPoolExecutor(max_workers=50) as executor:
executor.map(attack_with_fingerprint, fingerprints)
다층 지문채취 시스템
단일 지표에 의존해선 안 된다. 여러 계층의 정보를 종합 분석해야 한다.
이상 징후 탐지
정상 사용자와 다른 패턴을 보이는 요청을 탐지한다.
def detect_fingerprint_anomalies(request):
"""브라우저 지문 이상 징후 탐지"""
anomaly_score = 0
# 1. User-Agent와 다른 헤더 간 불일치
if is_user_agent_header_mismatch(request):
anomaly_score += 30
# 2. JavaScript 지문과 HTTP 헤더 불일치
if is_js_http_mismatch(request):
anomaly_score += 40
# 3. 비정상적인 헤더 순서
if has_unusual_header_order(request):
anomaly_score += 20
# 4. 자동화 도구 특성
if has_automation_signatures(request):
anomaly_score += 50
# 5. 시간대와 언어 설정 불일치
if is_timezone_language_mismatch(request):
anomaly_score += 25
return anomaly_score >= 70 # 임계값 이상이면 의심
Client Hints 활용
W3C는 User-Agent 문자열의 한계를 해결하기 위해 Client Hints 표준을 개발했다.
Client Hints are an optimization that provides an alternative to user-agent string sniffing, allowing servers to request specific information about the user agent environment. — WICG Client Hints Specification
위조하기 어려운 정확한 클라이언트 정보를 얻을 수 있다.
// Client Hints를 통한 정확한 브라우저 정보 수집
navigator.userAgentData.getHighEntropyValues([
'platform',
'platformVersion',
'architecture',
'model',
'uaFullVersion'
]).then(data => {
// 위조하기 어려운 정확한 환경 정보 획득
console.log('Platform:', data.platform);
console.log('Architecture:', data.architecture);
console.log('Full Version:', data.uaFullVersion);
});
행동 기반 분석
브라우저 지문 외에 사용자의 실제 행동 패턴을 분석한다. 자동화된 공격을 탐지하는 방법이다.
// 인간적 행동 패턴 분석
function analyzeBehaviorPattern() {
const behavior = {
mouseMovements: trackMouseMovements(),
clickPatterns: analyzeClickPatterns(),
scrollBehavior: analyzeScrollBehavior(),
typingRhythm: analyzeTypingRhythm()
};
// 자동화 도구는 인간적 불규칙성을 재현하기 어려움
return calculateHumanLikeScore(behavior);
}
탐지 시스템 구축:
모니터링 및 대응:
지속적 개선:
T1036.012 브라우저 핑거프린트 위조는 브라우저 환경 정보를 조작해 정상 사용자로 위장하는 기법이다. User-Agent 변경부터 JavaScript 환경 위조, 행동 패턴 시뮬레이션까지 여러 계층에서 이루어진다. 방어하려면 다층적이고 지능적인 탐지 시스템이 필요하다.
단일 지표에 의존해선 안 된다. HTTP 헤더, JavaScript 지문채취, 네트워크 패턴, 행동 분석을 종합해 위장 시도를 탐지하고 차단해야 한다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.