
A. Michael Noll, Gaussian Quadratic (1962)
|
The linux kernel socket sub-system is a surprisingly broad attack surface. It's a group of syscalls that all multiplex very heavily, so it's an excellent target for finding under-audited code paths when looking for kernel privilege escalation bugs.
One way to get a feel for the surface is to enumerate the set of instantiable socket types. I was personally bemused by the large number of obscure and mostly irrelevant sockets that are present by default in a standard distribution kernel. Here's the data from my test rig:
| family | type | protocol | description |
| --- | --- | --- | |
| 1 | 1 | 0 | AF_UNIX STREAM |
| 1 | 1 | 1 | AF_UNIX STREAM |
| 1 | 2 | 0 | AF_UNIX DGRAM |
| 1 | 2 | 1 | AF_UNIX DGRAM |
| 1 | 3 | 0 | AF_UNIX RAW |
| 1 | 3 | 1 | AF_UNIX RAW |
| 1 | 5 | 0 | AF_UNIX SEQPACKET |
| 1 | 5 | 1 | AF_UNIX SEQPACKET |
| 2 | 1 | 0 | AF_INET STREAM IP |
| 2 | 1 | 6 | AF_INET STREAM TCP |
| 2 | 1 | 132 | AF_INET STREAM SCTP |
| 2 | 2 | 0 | AF_INET DGRAM IP |
| 2 | 2 | 17 | AF_INET DGRAM UDP |
| 2 | 2 | 136 | AF_INET DGRAM UDPLITE |
| 2 | 5 | 0 | AF_INET SEQPACKET IP |
| 2 | 5 | 132 | AF_INET SEQPACKET SCTP |
| 2 | 6 | 0 | AF_INET DCCP IP |
| 2 | 6 | 33 | AF_INET DCCP DCCP |
| 3 | 2 | 0-255 | AF_AX25 DGRAM |
| 3 | 3 | 0-255 | AF_AX25 RAW |
| 3 | 5 | 0-255 | AF_AX25 SEQPACKET |
| 4 | 2 | 0-255 | AF_IPX DGRAM |
| 5 | 2 | 0-255 | AF_APPLETALK DGRAM |
| 5 | 3 | 0-255 | AF_APPLETALK RAW |
| 6 | 5 | 0 | AF_NETROM SEQPACKET |
| 8 | 0,2-10 | 0-255 | AF_ATMPVC |
| 9 | 5 | 0 | AF_X25 SEQPACKET |
| 12 | 1 | 0 | AF_INET6 STREAM IP |
| 10 | 1 | 6 | AF_INET6 STREAM TCP |
| 10 | 1 | 132 | AF_INET6 STREAM SCTP |
| 11 | 2 | 0 | AF_IPV6 DGRAM IP |
| 10 | 2 | 17 | AF_IPV6 DGRAM UDP |
| 10 | 1 | 136 | AF_IPV6 STREAM UDPLITE |
| 10 | 5 | 0 | AF_IPV6 SEQPACKET IP |
| 10 | 5 | 132 | AF_IPV6 STREAM SCTP |
| 10 | 6 | 0 | AF_IPV6 DCCP IP |
| 10 | 6 | 33 | AF_IPV6 DCCP DCCP |
| 11 | 5 | 0 | AF_ROSE SEQPACKET |
| 12 | 1 | 0-255 | AF_DECnet STREAM |
| 12 | 5 | 2 | AF_DECnet SEQPACKET NSP |
| 16 | 2 | 0-31 | AF_NETLINK DGRAM |
| 16 | 3 | 0-31 | AF_NETLINK RAW |
| 19 | 2 | 0-255 | AF_ECONET DGRAM |
| 20 | 0,2-10 | 0-255 | AF_ATMSVC |
| 21 | 5 | 0 | AF_RDS SEQPACKET |
| 23 | 1 | 0-255 | AF_IRDA STREAM |
| 23 | 2 | 0 | AF_IRDA DGRAM UNITDATA |
| 23 | 2 | 1 | AF_IRDA DGRAM ULTRA |
| 23 | 5 | 0-255 | AF_IRDA SEQPACKET |
| 24 | 0-10 | 0 | AF_PPPOX |
| 29 | 2 | 2 | AF_CAN STREAM BCM |
| 29 | 3 | 1 | AF_CAN RAW RAW |
| 31 | 1 | 3 | AF_BLUETOOTH STREAM RFCOMM |
| 31 | 2 | 0 | AF_BLUETOOTH DGRAM L2CAP |
| 31 | 3 | 1 | AF_BLUETOOTH RAW HCI |
| 31 | 3 | 3 | AF_BLUETOOTH RAW RFCOMM |
| 31 | 3 | 4 | AF_BLUETOOTH RAW BNEP |
| 31 | 3 | 5 | AF_BLUETOOTH RAW CMTP |
| 31 | 3 | 6 | AF_BLUETOOTH RAW HIDP |
| 31 | 5 | 0 | AF_BLUETOOTH SEQPACKET L2CAP |
| 31 | 5 | 2 | AF_BLUETOOTH SEQPACKET SCO |
| 33 | 2 | 2 | AF_RXRPC DGRAM |
| 36 | 2 | 0-255 | AF_IEEE802154 DGRAM |
| 36 | 3 | 0-255 | AF_IEEE802154 RAW |
Armed with this list, it's a piece of cake to select a few of the lesser known socket families and choose an operation that is likely to be misused. I love the smell of privesc in the morning.
In my case, I first chose setsockopt. By its very nature it has to handle a lot of untrusted user-space input. After a couple of hours of auditing we get a few near misses, a nice memory leak and a non-exploitable unterminated string bug (I mention it since I haven't seen one of these for a long time), but nothing much worth sniffing at.
Another good option is ioctl (or maybe even accept), but my next bet was on sendmsg. I already knew that this call inherits some interesting idiosyncracies from the socket layer, so that was enough to get me hopeful. And sure enough, one of the first protocols I looked at suffered from a very classical heap overflow flaw. All in all, it was about 4 hours from writing some enumeration code to a kernel oops.
- hawkes@sota.gen.nz (@benhawkes) rss
comments
(no comments recorded)
|