티스토리 뷰

보안/Research

[Research] Unicode Case Mapping Collisions

돔돔이부하 2021. 12. 8. 00:52
728x90
반응형

Unicode Case Mapping Collision란?

서로 다른 문자를 대문자 또는 소문자로 변환했을 때 같은 문자가 되는 특이 케이스를 의미합니다. 주로 도메인이나 이메일 입력을 검증하는 로직에서 많이 발생하곤 합니다. 왜냐하면 이메일이나 도메인의 경우 대소문자가 제각각이면 안되니깐요.

 

예시

파이썬의 경우 아래와 같은 현상이 일어날 수 있습니다.

>>> 'K'.lower() == 'k'
True
>>> 'ı'.upper() == 'I'
True

위 예시에서 한 문자가 한 문자를 대응하는 예시를 들었다고 해서 무조건 1대1로 대응되는 것은 아닙니다.

>>> 'ß'.upper() == 'SS'
True

위와 같이 한 문자가 대문자 S 2개에 해당되는 경우도 있습니다.

 

이외에도 정말 다양한 케이스들이 있는데, 아래 링크를 참고해보면 될 것 같습니다.

https://domdomi22.github.io/unicode-pentester-cheatsheet/

 

Characters that byͥte

 

domdomi22.github.io

참고

그리고 위 링크를 보셨으면 알겠지만, Unicode Case Mapping Collisions 은 프로그래밍 언어마다 결과가 달라지기도 합니다. 예를 들어 Go 언어와 Python을 비교해보겠습니다.

 

Go 언어는 아래 결과가 true 가 나옵니다.

package main

import (
	"fmt"
	"strings"
)

func main() {
	fmt.Println(strings.ToLower("admİn") == "admin")
}

Python 언어의 경우에는 false 가 나옵니다.

>>> 'admİn'.lower() == 'admin'
False

 

언어별로 유니코드 처리 방식이나 lower, upper 함수들의 원리가 어떻게 되는지는 알 수 없지만, 확실히 흥미로운 주제인 것 같습니다.

 

사례

그럼 이번에는 실제 사용 예시로는 어떤 경우가 있는 지 살펴보도록 하겠습니다.

 

대상 : Github

Github에서 예전에 비밀번호 재설정 할 때 이메일로 인증 코드를 보내는 로직에서 해당 취약점이 발생했다고 합니다. 자세한 건 생략하고 중요한 부분만 설명하자면 이렇습니다.

 

어떤 한 사용자의 Github 계정 사용자명이 이메일로 되어 있었는데, 예를 들어 그 이메일이 domdomi@example.com 이라고 했을 때, example.com 이메일 서버에 domdomı@example.com 계정을 만들어 놓습니다. (참고로 여기서는 유니코드 문자인 ı 를 사용했습니다) 그리고 이메일 재설정 시 필요한 이메일에 domdomı@example.com 을 입력했고, Github 서버에서는 이를 lowercase 로 바꾸어 domdomı 가 아닌 domdomi 로 인식해서 데이터베이스에 실제로 존재한 이메일인지 확인합니다. 그리고 Github에서는 이를 정상 사용자의 이메일이라 판단하고 domdomı@example.com 에 인증코드를 보내줬다고 합니다. 이를 통해서 타 사용자 계정을 탈취할 수 있었다고 합니다.

 

(실제로는 어떤 언어와 어떤 로직과 어떤 input을 넣어서 취약점에 이용됐는지는 확인할 수 없었습니다.)

 

대상 : Django

Django 웹 프레임워크에서도 비밀번호 재설정 할 때 해당 케이스가 발생했다고 합니다. 자세한 건 CVE-2019-19844 와 관련해서 찾아보면 좋을 것 같습니다.

Django 공식 사이트에도 해당 취약점에 대해서 언급하고 있습니다. 취약한 버전으로는 3.0.1, 2.2.9, 그리고 1.11.27 이라고 합니다.

https://www.djangoproject.com/weblog/2019/dec/18/security-releases/

 

Django security releases issued: 3.0.1, 2.2.9, and 1.11.27 | Weblog | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

www.djangoproject.com

취약점 관련한 PoC 는 아래 링크를 확인하면 될 것 같습니다.

https://github.com/domdomi22/django_cve_2019_19844_poc

 

GitHub - domdomi22/django_cve_2019_19844_poc: PoC for CVE-2019-19844(https://www.djangoproject.com/weblog/2019/dec/18/security-r

PoC for CVE-2019-19844(https://www.djangoproject.com/weblog/2019/dec/18/security-releases/) - GitHub - domdomi22/django_cve_2019_19844_poc: PoC for CVE-2019-19844(https://www.djangoproject.com/webl...

github.com

 

대상 : 버그바운티 플랫폼에 제보된 사례

어디서 이런 취약점이 발생했는지는 모르겠지만, 터키 문자로 'ı' (일명 점 없는 i라고 함) 가 영문자 i 로 변환되는 버그가 있다고 했습니다. 공격자는 이를 이용해서 admin 계정의 비밀번호를 admın@example.com 으로 전송하게 해서 탈취할 수 있었다고 합니다. 버그바운티에 제보한 제보자가 말하긴 ı 를 toUpperCase() 함수에 거쳐져서 영문자 i 로 변환되었다고 합니다.

 

제 생각에는 Github 에서 발생했던 취약점과 거의 유사한 취약점으로 생각되는데요.

이 외에 또 Unicode Case Mapping Collision 과 관련된 취약점이 발생했다는 얘기는 못들은 걸로 봐서,

정~말 드물게 발생하는 케이스인 것 같습니다.

 

가끔 이와 관련해서 Wargame이나 CTF 문제에서는 본 것 같기도 합니다.

 

- 끝 -

 

추신 : 뭔가 각 환경별로 유니코드 변환 원리에 대해서 더 자세히 연구해보고 싶지만, 다음에 시간 있으면 해보기로...

728x90
반응형
댓글