본 글은 blackhat.com에서 공개한 LDAP Injection & Blind LDAP Injection을 번역&정리한 것입니다.
생략된 부분이 많기 때문에, 자세히 알기 위하신 분들은 아래 pdf 파일을 참고하시기 바랍니다.
1. LDAP 개요
LDAP 필터들은 RFC 4515에 다음과 같이 정의되어 있다. 이러한 필터들의 구조는 다음과 같이 요약될 수 있다 :
Filter = ( filtercomp )
Filtercomp = and / or / not / item
And = & filterlist
Or = | filterlist
Not = ! filter
Filterlist = 1*filter
Item = simple / present / substring
Simple = attr filtertype assertionvalue
Filtertype = "=" / "~=" / ">=" / "<="
Present = attr = *
Substring attr "=" [initial] * [final]
Initial = assertionvalue
Final = assertionvalue
모든 필터는 항상 괄호 안에 있어야하며, 오직 논리와 관계와 관련된 연산자들만 그것들을 구성할 수 있다.
특수한 문자인 "*"은 필터들의 구성에서 하나 혹은 많은 문자들을 대신하여 사용될 수 있다.
논리연산자를 제외하고, RFC 4256에서 독립적으로 사용할 수 있도록 허용된 두 특수 상수들이 있다 :
- (&) : 절대 참
- (|) : 절대 거짓
2. 공통적인 LDAP 환경들
거의 모든 환경에서, LDAP 서비스를 기반으로 한 어플리케이션들은 다음의 목적들 중 하나의 디렉토리를 사용한다.
- 접근제어(user/password 기반 검증, 사용자 인증거 관리)
- 권한 관리
- 자원 관리
3. Web Applications 에서의 LDAP Injection
가장 널리 사용되는 LDAP인 ADAM과 OpenLDAP에서 [1. LDAP 개요] 에서 설명한 LDAP 필터 구조의 구현에 대해 알아보자.
※ (attribute=value)
: 만약 쿼리 구조에 논리연산자(OR 또는 AND)가 존재하지 않다면, "value)(injected_filter"와 같은 injection은 두 필터에서 다음과 같은 결과일 것이다 : (attribute=value)(injected_filter)
: OpenLDAP에서는 두번째 필터가 무시되어 오직 첫번째 것만 실행될 것이다.
: ADAM에서는 두 필터를 가진 쿼리가 허용되지 않는다. 그러므로 injection은 불가능하다.
※ (|(attribute=value)(second_filter)) or (&(attribute=value)(second_filter))
: 만약 쿼리 구조에 논리연산자(OR 또는 AND)가 존재한다면, "value)(injected_filter)"와 같은 injection은 다음과 같은 결과일 것이다 : (&(attribute=value)(injected_filter))(second_filter))
: 비록 필터가 심지어 구문적으로 올바르지 않더라도, OpenLDAP은 첫번째 필터가 끝난 이후의 어떠한 문자든 무시를하며 왼쪽에서부터 오른쪽으로 처리를 시작할 것이다.
: 일부 LDAP Client web components는 두번째 필터를 무시하고 ADAM과 OpenLDAP에 오직 첫번째 완성된 것만 보내어 injection이 허용될 것이다.
몇몇의 어플리케이션 프레임워크들은 그것을 LDAP 서버로 보내기 전에 필터가 올바른지 체크할 것이다. 이러한 경우, 필터들은 구조적으로 올바르게 되어있어야 하므로 injection은 다음과 같이 만들 수 있다 : "value)(injected_filter))(&(1=0"
이것은 결과적으로 두개의 다른 필터를 만들고, 두번째는 무시될 것이다 : (&(attribute=value)(injected_filter))(&(1=0)(second_filter))
두번째 필터가 LDAP Server에서 무시되게 될 경우, 일부 구성요소들은 두 필터를 가진 LDAP query를 허용하지 않을 수 있다. 이러한 경우 단일필터 LDAP query를 얻기 위해서는 특별한 injection이 만들어져야 한다.
injection이 "value)(injected_filter"와 같으면 결과는 다음과 같을 것이다 : (&(attribute=value)(injected_filter)(second_filter)).
이후 상세한 쿼리 및 예제들은 그림과 함께 보는 것이 이해가 빠르므로 출처 PDF를 참고해주시기 바랍니다.
'Hacking > Web' 카테고리의 다른 글
[root-me] NoSQL injection - Blind (0) | 2020.03.05 |
---|---|
[root-me] Local File Inclusion - Wrappers (0) | 2020.03.05 |
Study of XXE (0) | 2020.03.03 |
PHP wrapper (0) | 2020.03.02 |
JWT Signature - RS256 to HS256 (3) | 2020.02.27 |