QRcode Generator를 잘못 구현 시 큐싱(Qshing)의 매개체로 활용될 수 있는 점을 알아봅시다.
QRcode & Qshing(큐싱)
QRCODE에 의하면 QR코드는 일본에서 처음 개발되었고, 2차원 매트릭스 형태로 이루어진 정보 표시 방법입니다.
QR코드에는 URL, 텍스트, 숫자, 결제 정보등을 담을 수 있으며 카메라로 스캔 시 특정 데이터를 실행/표시 할 수 있습니다.
Qshing(큐싱)은 QR코드와 피싱의 합성어로 QR코드를 통해 사용자의 정보를 탈취하는 해킹 수법입니다.
가짜 QR코드를 제작해 피해자가 스캔하면 악성 사이트로 연결시켜 주의가 필요합니다.
QR코드 Generator
웹사이트 <-> 모바일에 빠른 데이터 전달을 위해 QR코드를 이용하는 사이트가 있는데 아래의 취약한 코드를 예시로 들어보겠습니다.
아래 코드는 p 라는 파라미터를 받아 해당 값을 기반으로 QR 코드를 제작하는 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask, request, send_file
import qrcode
from io import BytesIO
app = Flask(__name__)
@app.route("/")
def qr():
p = request.args.get("p", "")
img = qrcode.make(p)
b = BytesIO()
img.save(b, "PNG")
b.seek(0)
return send_file(b, mimetype="image/png")
app.run()
QR코드를 스캔하게 되면 123456 이라는 값이 모바일로 전달되게 합니다.
하지만 만약 텍스트/숫자 데이터가 아닌 링크를 전달하면 어떻게 될까요?
아래 두 QR코드 모두 google.com으로 이동시키는 버튼을 출력하게 됩니다.
- ?p=https://google.com
- ?p=google.com
google.com 이라는 버튼이 출력되고 해당 버튼을 누르면 google.com로 이동하게 됩니다.
QR코드를 받는 입장에서 요즘은 https://{URL}은 조심을 하게 되지만 실제 QRcode를 만들 수 있는 사이트가 신뢰할 수 있는 사이트라면 https://{신뢰사이트}?~~~~~~?p={악성사이트}의 형식이기 떄문에 사용자는 신뢰사이트에서 전달한 QR코드라고 인식하기 쉽습니다.
대응 방안
대응 방안은 QR코드로 텍스트/숫자 같은 패턴을 제공한다면 QRcode를 생성하는 변수를 사용자에게 입력받지 말아야하며, 입력을 받는 경우라면 형식(길이, 특수문자 사용 금지등)의 검증 로직이 있어야합니다.
