LDAP注入


概述

LDAP(Lightweight Directory Access Protocol):即輕量級目錄訪問協議。是一種運行於TCP/IP之上的在線目錄訪問協議,主要用於目錄中資源的搜索和查詢。使用最廣泛的LDAP服務如微軟的ADAM(Active Directory Application Mode)和OpenLDAP。

 

而LDAP 注入是利用用戶引入的參數生成惡意 LDAP 查詢,通過構造 LDAP 過濾器來繞過訪問控制、用戶權限提升。在維持正常過濾器的情況下構造出 AND、OR 操作注入來獲得敏感信息。

 

目錄數據庫結構

LDAP數據庫,是樹結構的,數據存儲在葉子節點上。

  • dn:一條記錄的位置
  • dc:一條記錄所屬的區域
  • ou:一條記錄所屬的組織
  • cn/uid:一條記錄的名字/ID

首先要說明是哪一棵樹(dc),然后是從樹根到目標所經過的所有分叉(ou),最后就是目標的名字(cn/uid),借用一張圖來表明結構如下:

 

 

條目&對象類&屬性

  • 條目(entry):是目錄中存儲的基本信息單元,上圖每一個方框代表一個entry。一個entry有若干個屬性和若干個值,有些entry還能包含子entry
  • 對象類(obejectclass):對象類封裝了可選/必選屬性,同時對象類也是支持繼承的。一個entry必須包含一個objectClass,且需要賦予至少一個值。而且objectClass有着嚴格的等級之分,最頂層是top和alias。例如,organizationalPerson這個objectClass就隸屬於person,而person又隸屬於top
  • 屬性(atrribute):顧名思義,用來存儲字段值。被封裝在objectclass里的,每個屬性(attribute)也會分配唯一的OID號碼

 

 

基本的LDAP語法

  • = 等於
  • & 邏輯和
  •  | 邏輯或
  •  ! 邏輯不 
  • * 通配符

邏輯操作符(AND、OR、NOT)和關系操作符(=、>=、<=、~=)

除使用邏輯操作符外,RFC4256還允許使用下面的單獨符號作為兩個特殊常量:

(&)     ->Absolute TRUE
(|)     ->Absolute FALSE

  

對象定義:

objectclass: top
objectclass: person

  

對象類定義:

objectclass: person
objectclasses=( 2.5.6.6 NAME 'person' DESC 'Defines entries that generically represent people.' SUP 'top' STRUCTURAL MUST ( cn $ sn ) MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) 

  

屬性定義:

attributetypes=( 2.5.4.4 NAME ( 'sn' 'surName' ) DESC 'This is the X.500 surname attribute, which contains the family name of a person.' SUP 2.5.4.41 EQUALITY 2.5.13.2 ORDERING 2.5.13.3 SUBSTR 2.5.13.4 USAGE userApplications )

  

搜索語法:

主要根據屬性和值進行搜索

attribute operator value

  

LDAP查詢語句

一個圓括號內的判斷語句又稱為一個過濾器filter。

默認情況下,LDAP的DN和所有屬性都不區分大小寫。

( "&" or "|" (filter1) (filter2) (filter3) ...) ("!" (filter))

  

LDAP注入

無邏輯操作符的注入

后端代碼如果是這樣寫的:

(attribute=$input)

  

我們構造輸入語句:

$input=value)(injected_filter

  

完整的語句就成下面這樣了:

(attribute=value)(injected_filter)

  

由於一個括號內代表一個過濾器,在OpenLDAP實施中,第二個過濾器會被忽略,只有第一個會被執行。而在ADAM中,有兩個過濾器的查詢是不被允許的。因而這類情況僅對於OpenLDAP有一定的影響。

例如我們要想查詢一個字段是否存在某值時,可以用$input=x*進行推移,利用頁面響應不同判斷x*是否查詢成功。

 

帶有邏輯操作符的注入

(|(attribute=$input)(second_filter))
(&(attribute=$input)(second_filter))

  

此時帶有邏輯操作符的括號相當於一個過濾器。此時形如value)(injected_filter)的注入會變成如下過濾器結構

(&(attribute=value)(injected_filter))(second_filter)

  

雖然過濾器語法上並不正確,OpenLDAP還是會從左到右進行處理,忽略第一個過濾器閉合后的任何字符。一些LDAP客戶端Web組成會忽略第二個過濾器,將ADAM和OpenLDAP發送給第一個完成的過濾器,因而存在注入。

案例分享

萬能用戶名案例

驗證登陸的查詢語句是這樣:

(&(USER=$username)(PASSWORD=$pwd))

  

輸入$username = admin)(&)(使查詢語句變為:

(&(USER=admin)(&))((PASSWORD=$pwd))

  

即可讓后面的password過濾器失效,執行第一個過濾器而返回true,達到萬能密碼的效果。

 

權限提升案例

現假設下面的查詢會向用戶列舉出所有可見的低安全等級文檔:

(&(directory=document)(security_level=low))

  

這里第一個參數”document”是用戶入口,low是第二個參數的值。如果攻擊者想列舉出所有可見的高安全等級的文檔,他可以利用如下的注入:

document)(security_level=*))(&(directory=documents

  

生成的過濾器為:

(&(directory=documents)(security_level=*))(&(direcroty=documents)(security_level=low))
###
LDAP服務器僅會處理第一個過濾器而忽略第二個,因而只有下面的查詢會被處理:(&(directory=documents)(security_level=*)),而(&(direcroty=documents)(security_level=low))則會被忽略。結果就是,所有安全等級的可用文檔都會列舉給攻擊者,盡管他沒有權限看它們。

  

總結

LDAP注入本質就是在OpenLDAP實施中,由於一個括號內代表一個過濾器,第二個過濾器會被忽略,只有第一個會被執行。當查詢語句帶有邏輯操作符時,可以通過注入惡意的LDAP語句去達到不同的目的。

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM