SSD Advisory – Linux Kernel AF_PACKET Use After Free (packet_sock)

Credit to Author: SSD / Ori Nimron| Date: Wed, 15 Aug 2018 05:26:28 +0000

Vulnerability Summary
UAF vulnerability in Linux Kernel’s implementation of AF_PACKET leads to privilege escalation. AF_PACKET sockets allow users to send or receive packets on the device driver level, which lets them implement their own protocol on top of the physical layer or sniffing packets including Ethernet and higher levels protocol and higher levels of the OSI model.

Credit
An independent security researcher has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.

Affected systems
Ubuntu Desktop versions 14.04, 16.04, 17.10, and other Linux distributions with older kernel versions. The vulnerability has been resolved in the latest Linux Kernel version 4.17.11.

Vulnerability Details
A use-after-free can occur due to a race condition between fanout_add from setsockopt and bind on a AF_PACKET socket.

Although the racing condition has been fixed here: 15fe076edea787807a7cdc168df832544b58eba6#diff-39c49c27f7a70091bcf94cbad241d0eb. They failed to see a UAF could occur from the racing issue. The logic is that a packet_sock can be linked via its prot_hook member to one of the ptype_head linked list in /net/core/dev.c. Each list is a list of function callbacks the Linux stack can call when a network packet is received or sent.

The logic is that a packet_sock can be linked via its prot_hook member to one of the ptype_head linked list in /net/core/dev.c. Each list is a list of function callbacks the Linux stack can call when a network packet is received or sent, as discussed in the first advisory about AF_PACKET (https://blogs.securiteam.com/index.php/archives/3484)

register_prot_hook() and __unregister_prot_hook() in /net/packet/af_packet.c can both be reached via packet_do_bind() and packet_notifier() without any locks held. Which ptype_head list it is added to only depends on po->num. When a thread A unregisters it from packet_do_bind(), a second thread B can rapidly call packet_notifier() to register it again on the same list, before thread A continues with po->num = proto:

which will add it into a new list. When releasing the socket in packet_release, we will release the one from the last linked list but forget that we have another one in the first original list from packet_create(), thus causing a UAF.

We can get PC control by following the same logic as in the previously mentioned SSD article.

Poc

Crash info

Print Friendly, PDF & Email

https://blogs.securiteam.com/index.php/feed