[BRLY-2021-001]
SMM callout vulnerability on Lenovo ThinkPad laptops firmware (SMM arbitrary code execution)
BINARLY efiXplorer team

Summary

BINARLY efiXplorer team identified SMM callout in ThinkPad 13 2nd Gen, which allows a local privileged user to access the System Management Mode and execute arbitrary code.

Vulnerability Information

  • BINARLY internal vulnerability identifier: BRLY-2021-001
  • Lenovo PSIRT assigned CVE identifier: LEN-65529 (CVE-2021-3452)

Product description

Multiple Lenovo ThinkPad's is affected by this issue. (business-oriented laptops and tablets).

Affected products with confirmed impact by Binarly team

  • Lenovo ThinkPad 13 2nd Gen, firmware version: 1.29 (R0JET44W) / r0juj22w
  • Lenovo ThinkPad 11e 4th Gen, Yoga 11e 4th Gen (for Celeron Processors), firmware version 1.26 (R0KET40W) / r0kuj22w
  • Lenovo ThinkPad 11e 4th Gen, Yoga 11e 4th Gen (for i-based processors such as i3, i5, i7 & etc), firmware version 1.21 (R0LET36W) / r0luj20ww
  • Lenovo ThinkPad 11e Yoga Gen 6, firmware version 1.08 (R18ET24W) / r18uj06w

Potential impact

An attacker with local privileged access can exploit this vulnerability to elevate privileges from ring 0 to ring -2, execute arbitrary code in System Management Mode, and install a firmware backdoor/implant. The malicious code installed at the SMM level could persist across operating system re-installs. Additionally, this vulnerability potentially could be used by malicious actors to bypass UEFI firmware security mechanisms (include Secure Boot and some types of memory isolation for hypervisors) and in some cases would allow an attacker to modify the firmware storage on SPI flash chip to gain persistent infection on the target platform.

Vulnerability description

Vulnerability exists in the software System Management Interrupt (SWSMI) handler located at the address 0x48C of the module LenovoSmapiSmm (code example given from r0juj20w firmware).

SWSMI handler at offset 0x48C (SwSmiHandler_48C) dereferences gRT (EFI_RUNTIME_SERVICES) pointer to call a ResetSystem function, which can result in code execution in SMRAM and escalating privilege from ring 0 to ring -2.

.text:000000000000048C SwSmiHandler_48C proc near              ; DATA XREF: sub_314+FA↑o
...
.text:000000000000048C
.text:000000000000048C                 mov     [rsp-28h+arg_0], rbx
.text:0000000000000491                 mov     [rsp-28h+arg_8], rsi
.text:0000000000000496                 mov     [rsp-28h+arg_10], rdi
.text:000000000000049B                 push    rbp
.text:000000000000049C                 push    r12
.text:000000000000049E                 push    r13
...
...
.text:0000000000000BAC ; ---------------------------------------------------------------------------
.text:0000000000000BAC
.text:0000000000000BAC loc_BAC:                                ; CODE XREF: SwSmiHandler_48C+6C2↑j
.text:0000000000000BAC                 mov     rax, cs:gRT_1B00
.text:0000000000000BB3                 xor     edx, edx        ; ResetStatus
.text:0000000000000BB5                 xor     r9d, r9d        ; ResetData
.text:0000000000000BB8                 lea     ecx, [rdx+2]    ; ResetType
.text:0000000000000BBB                 xor     r8d, r8d        ; DataSize
.text:0000000000000BBE                 call    [rax+EFI_RUNTIME_SERVICES.ResetSystem] ; gRT->ResetSystem()

SwSmiHandler_48C is installed by the sub_314, which is called from ModuleEntryPoint

.text:0000000000000314 sub_314         proc near               ; CODE XREF: _ModuleEntryPoint+7B↑p
...
.text:0000000000000340                 call    [rax+_EFI_SMM_SYSTEM_TABLE2.SmmLocateProtocol] ; gSmst->SmmLocateProtocol
.text:0000000000000346                 mov     rax, cs:gSmst_1AF8
.text:000000000000034D                 lea     r8, [rsp+28h+EFI_SMM_SW_DISPATCH2_PROTOCOL_IF] ; Interface
.text:0000000000000352                 lea     rcx, EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID_19F0 ; Protocol
.text:0000000000000359                 xor     edx, edx        ; Registration
...
.text:00000000000003F5                 lea     r9, [rsp+28h+DispatchHandle] ; DispatchHandle
.text:00000000000003FA                 mov     rcx, [rax]
.text:00000000000003FD                 mov     rax, [rsp+28h+EFI_SMM_SW_DISPATCH2_PROTOCOL_IF]
.text:0000000000000402                 lea     r8, [rsp+28h+RegisterContext] ; RegisterContext
.text:0000000000000407                 mov     cs:qword_1C28, rcx
.text:000000000000040E                 lea     rdx, SwSmiHandler_48C ; DispatchFunction
.text:0000000000000415                 mov     rcx, rax        ; This
.text:0000000000000418                 mov     [rsp+28h+RegisterContext.SwSmiInputValue], 80h ; '€'
.text:0000000000000421                 call    [rax+EFI_SMM_SW_DISPATCH2_PROTOCOL.Register]

Passing RAX = 0x5380, RBX = 0x7003 to SwSmiHandler_48C via CPU save state (ReadSaveState) will trigger the following vulnerable code:

__int64 __fastcall SwSmiHandler_48C():

  case 0x7003u:
    gRT_1B00->ResetSystem(EfiResetShutdown, 0i64, 0i64, 0i64);
    goto LABEL_132;

Disclosure timeline

This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available (whichever is earlier), the bug report will become visible to the public.

Disclosure Activity Date
Lenovo PSIRT is notified 2021-02-08
Lenovo PSIRT confirmed reported issue 2021-03-16
Lenovo PSIRT assigned CVE number 2021-03-19
Lenovo PSIRT provide patch release 2021-07-13
BINARLY public disclosure date 2021-07-14

Acknowledgements

BINARLY efiXplorer team

References