欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Linux lxd提权漏洞分析利用

来源:本站整理 作者:佚名 时间:2019-05-30 TAG: 我要投稿

核心在于利用的方式,比较新颖,不逐句翻译,保证将核心的点介绍清楚,并复现整个利用过程。
lxc(Linux container),Linux自带的容器;
lxd,简单地说,LXD 就是一个提供了 REST API 的 LXC 容器管理器
其中Ubuntu 19.04 server自带lxd,来扩展lxc的命令;
具体关于lxc和lxd可以参考【1】【2】
概述:
LXD是Linux系统中用于管理LXC容器的API,提供了很多便利的命令来创建容器(container)、启动等等操作。它将为本地lxd用户组的任何用户执行任务,然而并没有在用户的权限与要执行的功能之间是否匹配做过多的判断。
例如:一个低权限的用户能够创建一个用于host和container通信的socket,当将host中已经创建的一个socket和container绑定后,它们之间的连接通信会以LXD服务的凭证(root权限)而不是调用用户的凭证;所以当container中发送socket和host通信时,此时host端的socket则是root权限。所以关键就是怎么在一个得到一个root socket时实现提权,这也是这篇博客注重点。
环境搭建&PoC验证:
因为ubuntu 19.04 server是默认安装了lxd的,所以采用这个环境,基于VMWare搭建。(其中Mac上多个ubuntu Server terminal的切换是,control+command+f1/f2/f3…)。前提就是必须有一个处于lxd用户组的用户,使用exp lxd_rootv2.py将其提升到root权限。
所以环境搭建,首先创建一个处于lxd用户组的低权限用户。按照博客上面的流程,我这里为了方便,创建了一个llxd的用户,在lxd用户组,

权限很低,是无法sudo的。


此时基本环境是ok的,只要能够拿到这么一个llxd用户,就能够提权。
在该用户下创建一个container,是不需要额外的权限的。创建ubuntu18.04容器,名称是fal。
lxc launch ubuntu:18.04 fal
创建成功:

PoC验证:
首先尝试在正常环境下,即llxd用户下开启一个socket监听,然后去nc连接,查看此时socket的权限。
socket的监听代码如下:
##!/usr/bin/env python3 """ Echo peercreds in connections to a UNIX domain socket """ import socket import struct def main(): """Echo UNIX peercreds""" listen_sock = '/tmp/echo.sock' sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.bind(listen_sock) sock.listen() while True: print('waiting for a connection') connection = sock.accept()[0] peercred = connection.getsockopt(socket.SOL_SOCKET, socket.SO_PEERCRED, struct.calcsize("3i")) pid, uid, gid = struct.unpack("3i", peercred) print("PID: {}, UID: {}, GID: {}".format(pid, uid, gid)) continue if __name__ == '__main__': main()
自己在server上省略敲了一遍,测试结果如下,正常的用户权限。


此时尝试从container中去nc来和host通信,这里不是单纯的监听和发送,需要经过lxd server。首先配置通信网络:
lxc config device add fal proxy_sock
proxy connect=unix:/tmp/echo.sock listen=unix:/tmp/proxy.sock
bind=container mode=0777
通过lxd来增加一个代理socket(proxy_sock)来帮助container和host之间的通信,上面的命令大致意思是:给叫fal的容器增加一个proxy_sock,绑定在container上,container上是/tmp/proxy.sock在监听,然后收到数据后连接到host上的/tmp/echo.sock,其实就是相当于一个代理的作用。
所以我们在容器里往/tmp/proxy.sock发送,那么host上监听/tmp/echo.sock就能拿到数据。
然后,创建一个容器用户,登录进去,就能在容器中.
lxc exec falcor -- sudo --user ubuntu --login


上面的结果说明了从container中发出的通信,是能够拿到root socket的。
利用:作者首先查看在host上面都有哪些socket在监听着,然后发现了一个看起来比较有意思的socket,/run/systemd/private
lowpriv@server:~$ ss -xlp
-- snip --
Local Address:Port
/run/systemd/private
然后通过查看文档寻找该socket的功能:
Used internally as communication channel between systemctl(1) and the systemd process. This is an AF_UNIX stream socket. This interface is private to systemd and should not be used in external projects.

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载