Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement mitigation for Driver Verifier #4

Merged
merged 9 commits into from
Jun 10, 2021

Conversation

kkent030315
Copy link
Contributor

@kkent030315 kkent030315 commented Jun 6, 2021

This is a mitigation for issue #3 .

Added optional augment of --mitigatedv which allows execution of this exploit to be work while DV (Driver Verifier) is enabled.
This mitigation only supports Windows 10+.

Tested on:

  • x64 Windows 10 2004 19041.985
    • success_2004_19041
  • x64 Windows 10 20H2 19042.631
    • success_20H2_19042
  • x64 Windows 10 21H1 19043.985
    success_21H1_19043

What

As discussed on the issue, this is due to bad implementation of capcom.

image

Both of CpCreateClose and CpDeviceIoControl reference Irp->IoStatus.Status after the IRP is freed by IofCompleteRequest.

image

This causes page fault bugcheck on DV enabled environment. (bugcheck 0x50)

Mitigation

As the author says, we could directly patch the mapped image to avoid page faults.
We need to patch two functions, CpCreateClose and CpDeviceIoControl.

; Original disassembly of CpDeviceIoControl
fffff805`784b062b ff15dffcffff    call    qword ptr [Capcom+0x310 (fffff805`784b0310)]
fffff805`784b0631 8b4330          mov     eax,dword ptr [rbx+30h] ; rva is 0x631
fffff805`784b0634 4883c420        add     rsp,20h
fffff805`784b0638 5f              pop     rdi
fffff805`784b0639 5e              pop     rsi
fffff805`784b063a 5b              pop     rbx
fffff805`784b063b c3              ret
; Original disassembly of CpCreateClose
fffff805`784b0512 ff15f8fdffff    call    qword ptr [Capcom+0x310 (fffff805`784b0310)]
fffff805`784b0518 8b4330          mov     eax,dword ptr [rbx+30h] ; rva is 0x518
fffff805`784b051b 4883c420        add     rsp,20h
fffff805`784b051f 5b              pop     rbx
fffff805`784b0520 c3              ret

Simply patch with following shellcode:

BYTE PatchShellcode[] = { 
    0x33, 0xC0, // xor edx, edx 
    0x90        // nop
};

Problem

This mitigation will not work on either Windows 7 nor Windows 8, 8.1.
I do not see any reason to compatible with these versions so I don't care.

If you have any problems or better idea, feel like to discuss here.
Thank you.

@kkent030315 kkent030315 marked this pull request as draft June 6, 2021 11:49
@kkent030315 kkent030315 marked this pull request as ready for review June 6, 2021 11:52
@tandasat
Copy link
Owner

tandasat commented Jun 7, 2021

Excellent work. Also, thank you for the clean write up and testing on multiple platforms. Left few minor style related requests and a request to update of README.md. Otherwise, looks great.

EDIT: I also do not care Windows 7 and 8, as well as supporting a different version of capcom.sys that might have those functions at different offsets if such versions exist. I tested with the version noted in README.md and that's all this project needs to support.

@kkent030315
Copy link
Contributor Author

kkent030315 commented Jun 7, 2021

I forgot to implement mutex for PsLoadedModuleList the code must acquire PsLoadedModuleResource in order to reference it.
I'll commit some additional implementation for it and README.md later.

@kkent030315 kkent030315 changed the title implement mitigation for Driver Verifier Implement mitigation for Driver Verifier Jun 7, 2021
@kkent030315
Copy link
Contributor Author

Retested on all listed platforms and this PR is ready to go.
Please review changes.
Thank you.

@tandasat
Copy link
Owner

tandasat commented Jun 7, 2021

Thanks for the update. Please address review comments

@kkent030315
Copy link
Contributor Author

I don't see any review comments on the commits regarding your style-related requests.
Where especially should I change?
Thank you.

ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Outdated Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Outdated Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Outdated Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Outdated Show resolved Hide resolved
ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp Outdated Show resolved Hide resolved
@tandasat
Copy link
Owner

tandasat commented Jun 9, 2021

Apologies, I thought I submitted my comments (because you addressed some of them :) ) but it was not the case. Those comments should be visible to you now.

@kkent030315
Copy link
Contributor Author

Code refactored.

Here is the changes:

  • Fixes for the change requests.
  • Remove KeEnterCriticalRegion, KeLeaveCriticalRegion, ExAcquireResourceExclusiveLite, ExReleaseResourceList
    • Add ExEnterCriticalRegionAndAcquireResourceExclusive, ExReleaseResourceAndLeaveCriticalRegion for simpler codebase
  • Use memcpy instead of NtosRtlCopyMemory
  • Implement temporal CR0.WP disabling in order to safer execution of patching .text section

Please re-review changes.
Thank you for taking time for this PR. :)

@kkent030315
Copy link
Contributor Author

kkent030315 commented Jun 9, 2021

This is a bit unrelated but I'd like to share information here.

From my investigation, it looks like the whole image that mapped to the KVA is writable. (Even IAT or PE, whatever)
On other normal driver, it is no way this thing happens.

During my reverse engineering of this driver I thought that the Capcom image size is very small (0xE00). something is special with this driver.

image

Example Output
0: kd> !address -v -map Capcom+518
===================================================================================================
PXE:    fffff379bcde6f80 [contains 0000000000f89063]

        Page Frame Number:  f89, at address: ffff81000002e9b0
        Page Location:      6 (Active)
        Virtual address:    fffff379bcdf0000
        PTE Address:        fffff379bcde6f80
        Containing frame:   00000000000001ad
        Attributes:         M:Modified,Cached
        Usage:              PPEs; Process ffff9e81024b4040 [System], Entries:0

PPE:    fffff379bcdf0020 [contains 0000000000f8a063]

        Page Frame Number:  f8a, at address: ffff81000002e9e0
        Page Location:      6 (Active)
        Virtual address:    fffff379be004000
        PTE Address:        fffff379bcdf0020
        Containing frame:   0000000000000f89
        Attributes:         M:Modified,Cached
        Usage:              PDEs; Process ffff9e81024b4040 [System], Entries:0

PDE:    fffff379be004140 [contains 0a0000003f721863]

        Page Frame Number:  3f721, at address: ffff810000be5630
        Page Location:      6 (Active)
        Virtual address:    fffff37c00828000
        PTE Address:        fffff379be004140
        Containing frame:   0000000000000f8a
        Attributes:         M:Modified,Cached
        Usage:              PTEs; Process ffff9e81024b4040 [System], Entries:0

===================================================================================================
PTE:    fffff37c00828b80 [contains 0900000006a1f963]

        Page Frame Number:  6a1f, at address: ffff81000013e5d0
        Page Location:      6 (Active)
        Virtual address:    fffff80105170000
        PTE Address:        fffff37c00828b80
        Containing frame:   000000000003f721
        Attributes:         M:Modified,Cached
        Usage:              Private; Process ffff9e81024b4040 [System]

Type:   Valid
Attrs:  Global,NormalPage,Dirty,Dirty1,Accessed,Kernel,Writable,NotWriteThrough,Cached
PFN:    6a1f

===================================================================================================

EDIT 19th Aug 2021:

I assume capcom.sys intentionally changes /ALIGN linker option to make binary minimum. which will result in the entire driver image is on the single page. It makes sense now.

Such linker option would make HLK to be failure for specific versions of Windows 10.

@tandasat
Copy link
Owner

tandasat commented Jun 9, 2021

That's interesting. Thanks for additional notes. I noticed the entire driver image is within in 0x1000 on memory and some of sections are writable. That would make the entire page, including the .text section, writable.

Love into Capcom.sys. It was vulnerable by design, had an UAF bug and the whole image was writable. Amazing quality of engineering.

Given that, I prefer not to change WP. I am pretty sure that fact that the driver is writable would be consistent across platforms, so no value to add complexity of bit flipping.

@kkent030315
Copy link
Contributor Author

I agreed with that and removed no-need CR0.WP modification.
Let me know if it there are another change requests. :)

@tandasat tandasat merged commit c2e2f1a into tandasat:master Jun 10, 2021
@tandasat
Copy link
Owner

Merged the PR. Thank you for analyzing the issue and working for the fix with me!

I am glad to find out I can still use this garbage as an example of.. garbage :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants