摘录理解LDAP与LDAP注入
0x01 LDAP簡介
? ? ? ? LDAP,輕量目錄訪問協(xié)議
? ? ? ? ? ?| dn: 一條記錄的位置
? ? ? ? ? ?| dc: 一條記錄所屬區(qū)域
? ? ? ? ? ?| ou: 一條記錄所屬組織
? ? ? ? ? ?| cn/uid:一條記錄的名字/ID
? ? ? ? 這里拿LDAP和數(shù)據(jù)庫進行比較。數(shù)據(jù)庫用"表"來存數(shù)據(jù),LDAP用"樹"來村數(shù)據(jù)。數(shù)據(jù)庫主要是三個DB,TABLE,ROW來定位一條記錄,而LDAP首先要說明是那一棵樹dc,然后是從樹根到目的所經(jīng)過的所有"分叉",ou(group),最后就是目標的名字,例如UID等等。
? ? ? ? ?具體到如何定義如下:
dn:cn=honglv,ou=bei,ou=xi,ou=dong,dc=waibo,dc=com 其中樹根是dc=waibo,dc=com,分叉ou=bei,ou=xi,ou=dong,目標cn=honglv 注意:要把"cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org"看成是一個整體,它只是屬性dn的值? ? ? ? 具體的一條記錄如下:
dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org objectClass:organizationalPerson cn:stan cn:小刀 sn:小刀 description:a good boy? (保存成LDIF文件,可以導入到LDAP數(shù)據(jù)庫中)
0x02 LDAP基本語法
? ? ? ?1) =(等于)
? ? ? ? ? ?查找"名"屬性為"John"的所有對象,可以使用:
(givenName=John) 這會返回"名"屬性為"John"的所有對象。圓括號是必需的,以便強調LDAP語句的開始和結束。? ? ? ? 2) &(邏輯與)
? ? ? ? 如果具有多個條件并且希望全部條件都得到滿足,則可使用此語法。例如,如果希望查找居住在Dallas并且"名"為"John"的所有人員,可以使用:
(&(givenName=John)(l=Dallas)) 此語句將查找"名"不為"John"的所有對象。請注意!操作符緊鄰參數(shù)的前面,并且位于參數(shù)的圓括號內。由于本語句只有一個參數(shù),因此使用圓括號將其括起來以示說明? ? ? ? ?3) !(邏輯非)
? ? ? ? ? ? ?此操作符用來排除具有特定屬性的對象。假定您需要查找"名"為"John"的對象以外的所有對象。則應使用如下語句:
(!givenName=John) 此語句將查找"名"不為"John"的所有對象。請注意:!操作符緊鄰參數(shù)的前面,并且位于參數(shù)的圓括號內。由于本語句只有一個參數(shù),因此使用圓括號將其括起來以示說明。? ? ? ? ?4) *(通配符)
? ? ? ? ? ? ? 可使用通配符表示值可以等于任何值。使用它的情況可能是:您希望查找具有職務頭銜的所有對象。為此,可以使用:
(title=*) 這會返回"title"屬性包含內容的所有對象。另一個例子是:您知道某個對象的"名"屬性的開頭兩個字母是"Jo".那么,可以使用如下語句進行查找:(givename=Jo*)這會返回"名"以"Jo"開頭的所有對象? ? ? ? ? 5) 高級用法eg:
? ? ? ? ? ? ?您需要一個篩選條件,用來查找居住在Dallas或Austin,并且名為"John"的所有對象。使用的語法應該是:
(&(givenName=John)(!(l=Dallas)(l=Austin)))0x03 LDAP注入
? ? ?LDAP注入攻擊和SQL注入攻擊相似,接下來的想法是利用用戶引入的參數(shù)生成LDAP查詢。一個安全的Web應用的Web應用在構造和將查詢發(fā)送給服務器前應該凈化用戶傳入的參數(shù)。在有漏洞的環(huán)境中,這些參數(shù)沒有得到合適的過濾,因而攻擊者可以注入任意惡意代碼。使用最廣泛的LDAP:ADAM和OpenLDAP,下面的結論將會導致代碼注入:
? ? ? 3.1 引入
(attribute=value)? ? ? ? ?如果過濾器用于構造查詢單缺少邏輯操作符,如value)(injected_filter,瞬間導致產生了兩個過濾器,
(attribute=value)(injected\_filter)? ? ? ? ?通常,在OpenLDAP實施中,第二個過濾器會被忽略,只有第一個會被執(zhí)行。而在ADAM中,有兩個過濾器的查詢是不被允許的,因而這個注入毫無用處。
(|attribute=value)(second_filter)) or (&(attribute=value)(second_filter))? ? ? ? ? 如果第一個用于構造查詢的過濾器有邏輯操作符,形如value)(injected_filter)的注入會變成如下過濾器:
(&(attribute=value)(injected_filter)) (second_filter)。? ? ? ? ? 雖然過濾器語法上并不正確,OpenLDAP還是會從左到右進行處理,忽略第一個過濾器閉合后的任何字符。
? ? ? ? ? 但是有的瀏覽器會進行檢查,檢查過濾器是否正確,這種情況下value)(injected_filter))(&(1=0,于是就出現(xiàn)了下述payload
(&(attribute=value)(injected_filter))(&(1=0)(second_filter))? ? ? ? ? ?既然第二個過濾器會被LDAP服務器忽略,有些部分便不允許有兩個過濾器的查詢。這種情況下,只能構建一個特殊的注入以獲得單個過濾器的LDAP查詢,如value)(injected_filter得到
(&(attribute=value)(injected_filter)(second_filter))? ? ? ?3.2 AND注入
? ? ? ? ? ? ?這種情況,應用匯構造由"&"操作符和用戶引入的參數(shù)組成的正常查詢在LDAP目錄中搜索,例如:
(&(parameter1=value1) (parameter2=value))? ? ? ? ? ? ?這里value1和value2是在LDAP目錄中搜索的值,攻擊者可以注入代碼,維持正確的過濾器結構但能使用查詢實現(xiàn)他自己的目標。
? ? ? ? ? ?3.2.1 繞過訪問控制
? ? ? ? ? ? ? ? ?一個登陸頁有兩個文本框用于輸入用戶名和密碼,過濾器如下:
(&(USER=Uname)(PASSWORD=Pwd))? ? ? ? ? ? ? ? ?如果攻擊者輸入一個有效地用戶名,如r00tgrok,然后在這個名字后面注入恰當?shù)恼Z句,password檢查就會被繞過。輸入Uname=slisberger)(&)),得到如下
(&(USER=slisberger)(&)(PASSWORD=Pwd))? ? ? ? ? ? ? ? ?LDAP服務器只處理第一個過濾器,即僅查詢(&(USER=slidberger)(&))得到了處理。這個查詢永真,故成功繞過。
? ? ? ? ? ? 3.2.2 權限提升
? ? ? ? ? ? ? ?現(xiàn)假設下面的查詢會向用戶列舉出所有可見的低安全等級文檔:
(&(directory=document)(security_level=low))? ? ? ? ? ? ? ?這里第一個參數(shù)document是用戶入口,low是第二個參數(shù)的值。如果攻擊者想列舉出所有可見的高安全等級的文檔,他可以利用如下的注入: **document)(security_level=*))(&(directory=documents**得到:
(&(directory=documents)(security_level=*))(&(directory=documents)(security_level=low))? ? ? ? ? ? ? ? LDAP服務器僅會處理第一個過濾器而忽略第二個,因而只有下面的查詢會被處理:
(&(directory=documents)(security_level=*))? ? ? ? ? 3.3 OR注入
? ? ? ? ? ? ? ?這種情況,應用會構造由"|"操作符和用戶引入的參數(shù)組成的正常查詢在LDAP目錄中搜索,例如:
(!(parameter1=value1) (parameter2=value2))? ? ? ? ? ? ? ? 這里value1和value2是在LDAP目錄中搜索的值,攻擊者可以注入代碼,維持正確的過濾器結構但能使用查詢實現(xiàn)他自己的目標。
? ? ? ? ? ?3.4 LDAP盲注
? ? ? ? ? ? ? 3.4.1 AND盲注
? ? ? ? ? ? ? ? 假設一個Web應用想從一個LDAP目錄列出所有可用的Epson打印機,錯誤信息不會反悔,應用發(fā)送如下的過濾器:
($(objectClass=printer)(type=Epson*))? ? ? ? ? ? ? ? 正確的過濾器為:
(&(objectClass=printer)(type=Epson*))? ? ? ? ? ? ? ? 而當注入)(objectClass=))(&(objectClass=void時得到
(&(objectClass=*)(objectClass=*))(&(objectClass=void)(type=Epson*))? ? ? ? ? ? ? ? ?執(zhí)行第一個,過濾器objectClass=*總是返回一個對象。當圖標被顯示時響應為真,否則為假。這樣我們就可以猜第二個括號的objectclass字段有些什么內容了。LDAP盲注技術讓攻擊者使用基于TRUE/FALSE的技術訪問所有的信息。
? ? ? ? ? ? ? 3.4.2 OR盲注
? ? ? ? ? ? ? ? 這種情況下,用于推測想要的信息的邏輯與AND是相反的,因為使用的是OR邏輯操作符。
? ? ? ? ? ? ? 3.4.3 盲注深入
? ? ? ? ? ? ? ? ?攻擊者可以使用字母、數(shù)字搜索提取屬性的值,這個想法的關鍵在于將一個復雜的值轉化為TRUE/FALSE列表。這個機制,通常稱為booleanization,大意是二值化。
? ? ? ? ? ? ? ? ? 假設攻擊者想知道department屬性的值,處理如下:
(&(idprinter=HPLaserJet2100)(department=a*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=f*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=fa*)) (object=printer))? ? ? ? ? ? ? ? ? 如此根據(jù)返回的不同結果猜是否正確,和MYSQL盲注類似。
? ? ? ? ? ? ? ? ? 同樣,攻擊者可以使用字符集削減技術減少獲得信息所需的請求數(shù),為完成這一點,他使用通配符測試給定的字符在值中是否為anywhere:
(&(idprinter=HPLaserJet2100)(department=*b*))(object=printer)) (&(idprinter=HPLaserJet2100)(department=*n*))(object=printer))? ? ? ? ? ? ? ? ? 這樣子可以看department中是否有b和n,巧用可以加速猜解過程,當然一般肯定都是寫腳本猜解
0x04 防御LDAP注入
? ? ?總而言之,我們看到圓括號、星號、邏輯操作符、關系運算操作符在應用層都必須過濾。無論什么時候,只要可能,構造LDAP搜索過濾器的值在發(fā)送給LDAP服務器查詢之前都要用應用層有效地值列表來核對。正則表達式替換掉就可以了。
總結
以上是生活随笔為你收集整理的摘录理解LDAP与LDAP注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 参考资料学习APR库
- 下一篇: 学习pcre之摘录