QR Code Pentesting
What Is a QR Code?
A QR (Quick Response) code is a 2D matrix barcode originally developed by Denso Wave in 1994. It can encode URLs, text, contact information, Wi-Fi credentials, and more. With the explosion of QR code usage during and after COVID-19 (contact tracing, contactless menus, payments), QR codes have become a significant attack surface.
Why QR Codes Are a Security Concern
QR codes are inherently opaque to humans—unlike a typed URL, a user cannot easily verify what a QR code will do before scanning it. This creates multiple attack opportunities:
- The user cannot see the destination before acting on it.
- QR codes are easily replaced on physical surfaces (stickers over legitimate codes).
- Mobile apps often process QR data automatically (deeplinks, Wi-Fi connections, Bluetooth pairing).
- QR codes can trigger privileged actions on mobile devices without user confirmation.
QR Code Attack Scenarios
1. QR Code Phishing (QRishing)
An attacker replaces a legitimate QR code (e.g., on a restaurant menu, parking meter, or public transit sign) with a malicious one pointing to a phishing site. The victim scans it and lands on a convincing fake login page.
- In the wild: Parking meter QR code fraud has been widely reported in the US and Europe.
- Defense: Verify the URL shown by the scanner before opening; use URL scanners.
2. URL Manipulation Attacks
When a QR code encodes a URL, that URL may be vulnerable to standard web attacks:
- Open Redirect:
https://trusted.com/redirect?url=https://evil.com - Parameter Injection: Hidden parameters that change app behavior
- SQL Injection / XSS via URL parameters if the destination app is vulnerable
1
2
# Attacker crafts a QR code encoding:
https://victim-app.com/login?redirect=https://evil.com&debug=1
3. Deeplink Hijacking
Mobile apps register URL schemes (e.g., myapp://action) and universal links (e.g., https://app.com/open). QR codes can trigger these:
1
myapp://transfer?to=attacker&amount=1000
If the app doesn’t validate the action or requires no further authentication, this can result in unauthorized operations.
4. Wi-Fi QR Code Attacks
QR codes for Wi-Fi networks encode credentials in a known format:
1
WIFI:T:WPA;S:NetworkName;P:Password;;
Attackers can:
- Create malicious Wi-Fi QR codes pointing to rogue APs (Evil Twin attacks).
- Generate QR codes that connect victims to networks enabling MITM.
5. vCard / Contact Injection
QR codes can encode vCard contact data. Malicious vCards may contain fields that exploit parsing vulnerabilities in contact apps.
6. SSRF via QR Code
If a server-side component scans QR codes (e.g., QR-based check-in systems), a QR code containing an internal URL can trigger SSRF:
1
http://169.254.169.254/latest/meta-data/ # AWS metadata endpoint
7. Dynamic QR Code Endpoint Takeover
Many “dynamic QR code” services use a short redirect URL. If the service allows updating the destination, an attacker who compromises the account can redirect all existing QR codes to malicious URLs.
Penetration Testing Methodology
Phase 1: Reconnaissance
- Identify how QR codes are generated and what they encode.
- Determine if they use static or dynamic QR code services.
- Map what happens after scanning: deeplink, web URL, action trigger?
Phase 2: URL/Deeplink Testing
1
2
3
4
5
6
7
8
9
10
# Decode QR code content (if you have the image)
zbarimg --raw qrcode.png
# Test the URL for standard web vulnerabilities:
# - Open redirect
curl -v "https://target.com/scan?url=https://evil.com"
# - XSS in redirect
curl -v "https://target.com/scan?url=javascript:alert(1)"
# - SSRF
curl -v "https://target.com/scan?url=http://169.254.169.254/latest"
Phase 3: Mobile App Deeplink Testing
1
2
3
4
5
# On iOS (using Frida or direct deeplink)
xcrun simctl openurl booted "myapp://transfer?to=attacker&amount=9999"
# On Android
adb shell am start -a android.intent.action.VIEW -d "myapp://transfer?to=attacker"
Phase 4: Server-Side QR Scanning Testing (SSRF)
If the application scans QR codes server-side:
1
2
3
# Generate a QR code containing SSRF payload
qrencode -o ssrf.png "http://169.254.169.254/latest/meta-data/"
# Upload or present this QR code to the application
Tools
| Tool | Purpose |
|---|---|
| zbarimg | Decode QR codes from images |
| qrencode | Generate QR codes from CLI |
| Burp Suite | Intercept and modify requests triggered by QR |
| Frida / Objection | Hook deeplink handlers in mobile apps |
| adb | Trigger Android deeplinks for testing |
Mitigations
- Validate and sanitize all data extracted from QR codes before processing.
- Show users the URL/destination before acting on it (scanner preview).
- Implement deeplink parameter validation — require authentication tokens for sensitive actions.
- Rate-limit and monitor server-side QR scanning endpoints.
- Sign dynamic QR codes to prevent tampering.
- Educate users to verify QR code destinations, especially for payment and authentication flows.
QR 코드란?
QR(Quick Response) 코드는 1994년 Denso Wave가 개발한 2D 매트릭스 바코드입니다. URL, 텍스트, 연락처 정보, Wi-Fi 자격 증명 등을 인코딩할 수 있습니다. COVID-19 이후 QR 코드 사용이 폭발적으로 증가하면서(방역 체크인, 비접촉 메뉴, 결제 등) QR 코드는 중요한 공격 표면이 되었습니다.
QR 코드가 보안 위협이 되는 이유
QR 코드는 본질적으로 사람이 읽기 어렵습니다 — 입력한 URL과 달리, 사용자는 QR 코드를 스캔하기 전에 무슨 일이 일어날지 쉽게 확인할 수 없습니다. 이는 다음과 같은 공격 기회를 만듭니다:
- 사용자가 행동하기 전에 목적지를 볼 수 없음
- 물리적 표면에서 QR 코드가 쉽게 교체 가능 (합법적인 코드 위에 스티커)
- 모바일 앱이 QR 데이터를 자동으로 처리 하는 경우가 많음 (딥링크, Wi-Fi 연결)
- QR 코드가 사용자 확인 없이 특권 작업을 트리거 할 수 있음
QR 코드 공격 시나리오
1. QR 코드 피싱 (QRishing)
공격자가 합법적인 QR 코드(식당 메뉴, 주차 요금기, 대중교통 안내판 등)를 피싱 사이트를 가리키는 악성 코드로 교체합니다.
2. URL 조작 공격
QR 코드가 URL을 인코딩하면 표준 웹 공격에 취약할 수 있습니다:
- 오픈 리다이렉트, 파라미터 인젝션, URL 파라미터를 통한 SQL 인젝션/XSS
3. 딥링크 하이재킹
모바일 앱은 URL 스킴(예: myapp://action)을 등록합니다. QR 코드가 이를 트리거할 수 있으며, 앱이 작업을 검증하지 않으면 무단 작업으로 이어질 수 있습니다.
4. Wi-Fi QR 코드 공격
공격자는 피해자를 MITM이 가능한 악성 AP에 연결시키는 Wi-Fi QR 코드를 만들 수 있습니다.
5. QR 코드를 통한 SSRF
서버 측에서 QR 코드를 스캔하는 경우(예: QR 기반 체크인 시스템), 내부 URL을 포함한 QR 코드로 SSRF를 트리거할 수 있습니다.
침투 테스트 방법론
1단계: 정찰
- QR 코드 생성 방법과 인코딩 내용 파악
- 정적 또는 동적 QR 코드 서비스 사용 여부 확인
- 스캔 후 발생하는 일 매핑: 딥링크, 웹 URL, 작업 트리거?
2단계: URL/딥링크 테스트
1
2
3
# QR 코드 내용 디코딩
zbarimg --raw qrcode.png
# 오픈 리다이렉트, XSS, SSRF 등 표준 웹 취약점 테스트
3단계: 모바일 앱 딥링크 테스트
1
2
# Android에서 딥링크 트리거
adb shell am start -a android.intent.action.VIEW -d "myapp://transfer?to=attacker"
완화 방법
- QR 코드에서 추출한 모든 데이터를 처리 전에 검증하고 정화
- 사용자에게 행동 전 URL/목적지 표시 (스캐너 미리보기)
- 민감한 작업에 인증 토큰을 요구하는 딥링크 파라미터 검증 구현
- 서버 측 QR 스캔 엔드포인트에 속도 제한 및 모니터링 적용
- 변조 방지를 위한 동적 QR 코드 서명
- 특히 결제 및 인증 흐름에서 QR 코드 목적지 확인을 위한 사용자 교육