1、LDAP 注入
ldap (light Directory Access portocol) 是基于x.500標(biāo)準(zhǔn)的輕量級(jí)目錄訪問協(xié)議,提供訪問目錄數(shù)據(jù)庫(kù)方法的服務(wù)和協(xié)議,常用于與目錄數(shù)據(jù)庫(kù)組成目錄服務(wù)。其中目錄是一個(gè)為查詢、瀏覽和搜索而優(yōu)化的專業(yè)分布式數(shù)據(jù)庫(kù),它呈樹狀結(jié)構(gòu)組織數(shù)據(jù),類似于linux/unix系統(tǒng)中的文件目錄。適合將公用證書、安全密鑰以及公司物理設(shè)備信息等不經(jīng)常變更的數(shù)據(jù)存儲(chǔ)于目錄中。類似于sql,ldap是一種搜索協(xié)議,具有查詢語(yǔ)法,并存在潛在的注入攻擊風(fēng)險(xiǎn)。ldap注入是指客戶端發(fā)送查詢請(qǐng)求時(shí),輸入的字符串中含有一些特殊字符,導(dǎo)致修改了ldap本來的查詢結(jié)構(gòu),從而使得可以訪問更多的未授權(quán)數(shù)據(jù)的一種攻擊方式。
本篇文章以 Java 語(yǔ)言源代碼為例,分析CWE ID 90:Improper Neutralization of Special Elementsused in an LDAP Query (‘LDAP Injection’)樣本中LDAP注入漏洞產(chǎn)生的原因以及修復(fù)方法。詳細(xì)請(qǐng)參見:
CWE ID 90: Improper Neutralization of Special Elements used in an LDAP Query (‘LDAP Injection’)http://cwe.mitre.org/data/definitions/90.htmlCWE ID 639:Authorization Bypass ThroughUser-Controlled Keyhttp://cwe.mitre.org/data/definitions/639.html
2. LDAP 注入的危害
LDAP 注入是利用用戶引入的參數(shù)生成惡意 LDAP 查詢,通過構(gòu)造 LDAP 過濾器來繞過訪問控制、用戶權(quán)限提升。通過針對(duì)正常過濾器的構(gòu)造,實(shí)現(xiàn) AND、OR 操作注入,以獲取敏感信息。
從2018年1月至2019年1月,CVE中共有4條漏洞信息與其相關(guān)。部分漏洞如下:
CVE 編號(hào) | 概述 |
---|---|
CVE-2018-12689 | phpLDAPadmin 1.2.2 允許通過 cmd.php?cmd = loginform 請(qǐng)求中精心設(shè)計(jì)的 serverid 參數(shù)或登錄面板中精心設(shè)計(jì)的用戶名和密碼進(jìn)行 LDAP 注入。 |
CVE-2018-5730 | MIT krb5 1.6 或更高版本允許經(jīng)過身份驗(yàn)證的 kadmin 將主體添加到 LDAP Kerberos 數(shù)據(jù)庫(kù),以通過提供 “l(fā)inkdn” 和 “containerdn” 數(shù)據(jù)庫(kù)參數(shù)來繞過DN容器檢查,或者通過提供作為擴(kuò)展的DN字符串來繞過 DN 容器檢查。 |
CVE-2016-8750 | 4.0.8 之前的 apache Karaf 使用 LDAPLoginModule 通過 LDAP 對(duì)用戶進(jìn)行身份驗(yàn)證。但是沒有正確編碼用戶名,因此容易受到 LDAP 注入攻擊,導(dǎo)致拒絕服務(wù)。 |
CVE-2011-4069 | PacketFence 3.0.2 之前的 html / admin / login.php 允許遠(yuǎn)程攻擊者進(jìn)行 LDAP 注入攻擊,從而通過精心設(shè)計(jì)的用戶名繞過身份驗(yàn)證。 |
3、示例代碼
示例源于 Samate Juliet Test Suite for Java v1.3 (https://samate.nist.gov/SARD/testsuite.php),源文件名:CWE90_LDAP_Injection__connect_tcp_01.java。
3.1缺陷代碼
上述示例代碼 39-61 行,程序進(jìn)行 TCP 連接并讀取Socket的數(shù)據(jù)并賦值給變量 data,在118 行動(dòng)態(tài)構(gòu)造一個(gè) LDAP 查詢語(yǔ)句,119 行對(duì)其加以執(zhí)行。LDAP 為人員組織機(jī)構(gòu)封裝了常見的對(duì)象類,比如人員(person)含有姓(sn)、名(cn)、電話(telephoneNumber)、密碼 (userPassword) 等屬性。該查詢?yōu)榱蓑?yàn)證是否存在名為變量 data 的員工,但并未對(duì)變量 data 的內(nèi)容做任何過濾。使用最簡(jiǎn)單的注入方式,令傳入?yún)?shù)的值為“*”,則構(gòu)造的動(dòng)態(tài)查詢條件為 “(cn=*)”,這樣可以查詢到所有員工的信息,導(dǎo)致信息泄露。
對(duì)上文中的樣例代碼進(jìn)行360代碼衛(wèi)士檢測(cè)后,發(fā)現(xiàn)存在“LDAP注入”漏洞,安全等級(jí)評(píng)定為高。數(shù)據(jù)污染源以及數(shù)據(jù)流向可以通過跟蹤路徑分析得出并在代碼的第120行報(bào)告缺陷,圖1亦如是
圖1:LDAP 注入的檢測(cè)示例
3.2 修復(fù)代碼
在上述修復(fù)代碼中,第119行使用 javax.naming.ldap 包下擴(kuò)展類 BaseControl 接收需要被處理的參數(shù),第120行 control 對(duì)象調(diào)用 getEncodedValue() 方法將接收的參數(shù) data 進(jìn)行編碼,編碼后的值為字符對(duì)應(yīng)的 ASN.1BER 編碼值。編碼后的字節(jié)數(shù)組不存在參與命令解析的特殊字符,可以構(gòu)造結(jié)構(gòu)、內(nèi)容正常的 LDAP 查詢語(yǔ)句,這樣就避免了 LDAP 注入的發(fā)生。
使用360代碼衛(wèi)士對(duì)修復(fù)后的代碼進(jìn)行檢測(cè),可以看到已不存在“LDAP注入”缺陷。如圖2:
圖2:修復(fù)后檢測(cè)結(jié)果
4?、如何避免 LDAP 注入
LDAP注入的根本原因是攻擊者利用LDAP元字符來修改LDAP查詢的含義。在構(gòu)造LDAP篩選器時(shí),程序員需明確哪些字符該被視作命令解析,哪些字符應(yīng)被視作數(shù)據(jù)解析。為了防止攻擊者侵犯程序員的各種預(yù)設(shè)情況,應(yīng)使用白名單的方法,確保LDAP查詢中由用戶控制的數(shù)值完全來自于預(yù)定的字符集合,應(yīng)不包含任何LDAP元字符。如果由用戶控制的數(shù)值范圍要求必須包含?LDAP元字符,則應(yīng)使用相應(yīng)的編碼機(jī)制轉(zhuǎn)義這些元字符在LDAP查詢中的意義。
如&、!、|、=、、,、+、-、”、’、;這些字符正常情況下不會(huì)用到,如果用戶的輸入中出現(xiàn)了,需要用反斜杠轉(zhuǎn)義處理。
還有些字符如(、)、、*、/、NUL這些字符不僅需要用反斜杠處理,還要將字符變成相應(yīng)的ASCII碼值。