Tuesday, May 17, 2022

Micropatches for Remote Procedure Call Runtime Integer Overflows (CVE-2022-26809 and CVE-2022-22019)



by Mitja Kolsek, the 0patch Team

 

April 2022 Windows Updates included a fix for a critical remotely exploitable vulnerability in Windows Remote Procedure Call Runtime (CVE-2022-26809). The vulnerability was found and reported by company Cyber-Kunlun founded by security researcher mj0011, but no proof-of-concept was published at the time.

As is often the case, the research community "diffed" Microsoft's patch (see Ben Barnea and Ophir Harpaz of Akamai and MalwareTech) and quickly found that the vulnerability must have been an integer overflow: if a special kind of RPC packets were sent to the RPC server, and very many of them, a buffer size on the server side would grow and grow until it would have to exceed 4 GB (the highest number one can represent with 32 bits), at which point said buffer size would "overflow" and become very small again. Should the buffer then get allocated, it would be too small, incoming packets overwriting data and possibly code beyond it. By carefully selecting the size and content of packets, at least in theory, a remote attacker could cause arbitrary code to get executed in the process of the targeted RPC serve.

In practice, it would not be that easy. First of all, packets have a maximum size of about 5,000 bytes and sending enough of them over the network to cause the overflow takes hours. Moreover, several researchers have mentioned - and we can confirm - that attempting to send so much data to an RPC server often results in a timeout in communication, which means going back to square one. In addition, it became apparent that not all RPC servers would be vulnerable, as the affected code was only reachable on certain types of servers (see here). Finally, what exactly would be overwritten by malicious data, and how/if that could lead to execution of attacker's code, remains unexplored. Nevertheless, the history teaches us to assume that possible.

For a few weeks attackers and defenders alike were looking for more data and either searching for, or trying to create a POC. On May 1st, a GitHub repository from user yuanLink appeared with what looked like a POC for this issue, along with a detailed analysis of the vulnerability seemingly from the same user. We took the POC and after some modifications we were able to reach the vulnerable code and see the buffer size growing with each received packet.

While analyzing the vulnerability and comparing fixed and vulnerable code, our team noticed another integer overflow issue nearby that wasn't addressed by the April Windows Updates. Before we could report it to Microsoft it turned out Akamai researchers had already done that, and May updates brought a fix for this additional vulnerability, assigned CVE-2022-22019.

 


 

This allowed us to fix two birds with one stone, so to speak, and we created a single micropatch to address both CVE-2022-26809 and CVE-2022-22019.

Source code of the micropatch:



MODULE_PATH "..\Affected_Modules\rpcrt4.dll_6.1.7600.24545_Win7_64-bit_NoESU\rpcrt4.dll"
PATCH_ID 862
PATCH_FORMAT_VER 2
VULN_ID 7335
PLATFORM win64

patchlet_start
    PATCHLET_ID 1
    PATCHLET_TYPE 2
    PATCHLET_OFFSET 0xb4633
    N_ORIGINALBYTES 5
    JUMPOVERBYTES 0
    PIT rpcrt4!0xb4661,rpcrt4!0xb4647
    ; 0xb4661 -> on error exit block
    ; 0xb4647 -> TransGetBuffer block
    
    code_start
       
        mov r13d, [rsi+24Ch]
        cmp r13d, edi         ; check if r13 > 0
        jz PIT_0xb4661        ; jmp to exit block
       
        cmp ebx, edi          ; is flag RPC_BUFFER_EXTRA set?
        jz PIT_0xb4647        ; jmp to TransGetBuffer block
    
                              ; overflow check
        mov edx, [rbp+18h]    ; acc buffer length
        lea eax, [r13d+edx]   ; sum of len(new_data) + len(acc_buffer)
        cmp eax, r13d         ; check for overflow (if the result is smaller
                              ; than r13)
        jb SET_ERROR          ; if so, jump to error
       
        mov edx, eax          ; take the above sum
        add edx, 18h          ; because of instruction: lea r8, [r13+18h]
        cmp edx, 18h          ; check for overflow (if the result is smaller
                              ; than 18h)
        jb SET_ERROR          ; if so, jump to error
       
        mov r13d, eax         ; save len(new_data) + len(acc_buffer) to r13
        jmp PIT_0xb4647       ; jmp to TransGetBuffer block, continuing original code
       
    SET_ERROR:
        mov edi, 6C6h         ; error code
        jmp PIT_0xb4661       ; jmp to exit block
       
    code_end
    
patchlet_end

 

Our micropatch was written for the following Windows versions that don't receive official patches from Microsoft:


  1. Windows 10 v1803 updated to May 2021
  2. Windows 10 v1809 updated to May 2021
  3. Windows 10 v1903 updated to December 2020
  4. Windows 10 v2004 updated to December 2021
  5. Windows 7 updated with ESU year 2, ESU year 1 or updated to January 2020
  6. Windows Server 2008 R2 updated with ESU year 2, ESU year 1 or updated to January 2020


This micropatch has already been distributed to all online 0patch Agents with a PRO or Enterprise license. To obtain the micropatch and have it applied on your computers along with our other micropatches, create an account in 0patch Central, install 0patch Agent and register it to your account with a PRO or Enterprise subscription. Note that no computer restart is needed for installing the agent or applying/un-applying any 0patch micropatch. 

To learn more about 0patch, please visit our Help Center

We'd like to thank yuanLink for publishing their analysis and providing a proof-of-concept that allowed us to reproduce the vulnerability and create a micropatch, and Antonio Cocomazzi for providing valuable assistance in reproducing the issue. We also encourage security researchers to privately share their analyses with us for micropatching.

No comments:

Post a Comment