mskssrv.sys - CVE-2023–29360 | Researchs (2024)

Bug CVE : CVE-2023–29360

Bug type : Logical bug leading to LPE

Integrity needed : Medium for kernel address leak

Tested on : Windows 10

Vulnerable Driver : mskssrv.sys

Bug Details

This is a logical bug arising in function FsAllocAndLockMdl inside mskssrv.sys driver in windows.

NTSTATUS __fastcall FsAllocAndLockMdl(void *AddressPtr, ULONG Length, struct _MDL **OutputMdl){ NTSTATUS v4; // edi struct _MDL *Mdl; // rax struct _MDL *v6; // rbx v4 = 0; if ( !AddressPtr || !Length || !OutputMdl ) return STATUS_INVALID_PARAMETER; Mdl = IoAllocateMdl(AddressPtr, Length, 0, 0, 0i64); v6 = Mdl; if ( !Mdl ) return STATUS_INSUFFICIENT_RESOURCES; MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess); *OutputMdl = v6; return v4;}

This is the vulnerable code snippet that is responsible for the bug. As visible, the function is responsible for creating a MDL from the AddressPtr which is later passed to MmProbeAndLockPages. This probing is done on KernelMode rather than being done via UserMode. This implies that that we can create a MDL based on arbitrary address and there would be no validation done since KernelMode is specified.

Looking at the implementation of MmProbeAndLockPages,we can confirm this

If AccessMode is 0, then no check is done since the condition is evaluated to be false. AccessMode is 0 for kernel and 1 for Usermode.

Understanding MDL

MDL or Memory Descriptor List in windows is used by kernel to describe the physical page layout for a Virtual address. MDL is a opaque structure where StartVa member points to the Virtual Address associated with the MDL. More details on MDL can be found here and here.

Looking at IoAllocateMdl, it simply creates a MDL structure on the basis of values passed to it

There is no check for StartVa member and hence arbitrary virtual address can be passed to it. Next, after the obtaining the MDL structure, the function passes it into MmProbeAndLockPages which will lock the MDL's StartVa and make sure its not paged out while driver is still operating on the data. Notice that IoWriteAccess is supplied to it which means that it allows write operation on the mapped MDL's StartVa member.

Now we know can we can create a arbitrary MDL. Lets see what more can be done with the MDL. Looking at xrefs of the MDL, we can see that its only being used inside FSFrameMdl::MapPages function.

Looking at FsMapLockedPages, we can see that it allows us to map the MDL into the process calling the driver.

NTSTATUS __fastcall FsMapLockedPages(struct _MDL *Mdl, ULONG Priority, PVOID *a3){ NTSTATUS v3; // ebx v3 = 0; if ( !Mdl || !a3 ) return STATUS_INVALID_PARAMETER; *a3 = 0i64; *a3 = MmMapLockedPagesSpecifyCache(Mdl, UserMode, MmCached, 0i64, 0, Priority); return v3;}

Looking at MmMapLockedPagesSpecifyCache, we see that the last argument to this function is a ULONG that denotes the Priority. If the priority is MdlMappingNoWrite i.e 0x80000000 , the the Virtual Address pointed by the MDL is mapped as Read Only. This means, that we need to select the right code branch that can allow us a control over Priority as well.

There are 2 code branches possible here.

For the second branch, the Priority is hardcoded 0xC0000010 which means a Priority flag of MdlMappingNoWrite | NormalPagePriority | MdlMappingNoExecute . This implies that we need to select the first branch since the second one is mapped as Read Only.

Exploitation

Now that we have everything figured, out lets break the exploitation steps into multiple steps :-

Step 1 : Connecting to the vulnerable driver

We know that the vulnerable driver is here mskssrv.sys but, lets figure out how to connect to the driver.

I was out of idea on this as to how to connect to the driver since it was not working via default connection strings like \\\\.\\Device\\mskssrv. Eventually I created a breakpoint on FSStreamReg::PublishTx and various other functions. Upon starting the camera, we see that the requests are coming from a DLL called frameServer.dll . Lets reverse the DLL to figure out how is it creating the driver handle.

Reversing the frameServer.dll , we see a function called FSGetMSKSSrvHandle which creates a call to CreateFileW and uses the handle returned by it for further driver communication. Lets create a breakpoint on the same functionality to dump the file parameter passed to CreateFile.

We switch to WindowsCamera.exe process and wait for the breakpoint to be reached.

Now, that we have the file name, we can now talk to the driver.

bool Driver::SendDataToDriver(int ioctl_code, PVOID buffer, size_t buffer_len, PVOID OutBuffer, size_t out_buffer_len) {  LPCWSTR lpFileName = L"\\\\?\\ROOT#SYSTEM#0000#{3c0d501a-140b-11d1-b40f-00a0c9223196}\\{96E080C7-143C-11D1-B40F-" L"00A0C9223196}&{3C0D501A-140B-11D1-B40F-00A0C9223196}";  HANDLE hDevice = CreateFileW(lpFileName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); NTSTATUS status = -1; status = DeviceIoControl(hDevice, ioctl_code, buffer, buffer_len, OutBuffer, out_buffer_len, nullptr, nullptr)}

Step 2 : Create GlobalRendezvous

To create a MDL, we need to use PublishTx function in mskssrv. While reversing the driver, we found that there is a global variable called FSInitializeContextRendezvous that needs to be initialized before anything is executed.

While reversing, we see that there is a global Rendezvous object that is being checked before any operation. So in order to perform any operation, we need to initialize the GlobalRendezvous object.

The below code would initialize the GlobalRendezvous object.

bool Bug::InitializeGlobalRendezvous() { auto* stream_data = static_cast<_FSStreamRegInfo*>(malloc(sizeof(_FSStreamRegInfo))); memset(stream_data, 0x0, sizeof(_FSStreamRegInfo)); HANDLE hEvent = CreateEvent(nullptr, NULL, NULL, nullptr); stream_data->ObjectHandle = hEvent; stream_data->q2 = GetCurrentProcessId(); stream_data->q1 = 0x5; stream_data->f2 = 0x50; stream_data->q5 = 0x20000; stream_data->q3 = 1; SendDataToDriver(0x2f0400, stream_data, sizeof(_FSStreamRegInfo);}

Step 3 : Read Primitive

The below execution flow is used to create a read primitive.

uint64_t ReadPrimitive(uint64_t where) { // Initialize Stream bool status = false; if (poc::once) { poc_.InitializeStream(); } // PublishTx status = poc_.PublishTx(where); // Register Stream if (poc::once) { poc_.RegisterStream(); poc::once = false; } // ConsumeTx poc_.ConsumeTx(); // DrainTx poc_.DrainTx(); return *reinterpret_cast<uint64_t*>(poc_.GetMappedAddr());}

We first initialize a stream. There would be a single stream binded to a device handle. This implies that we need to execute InitializeStream and RegisterStream once per device handle. Refer to the exploit code on how to create such requests.

PublishTx function is responsible for creating a MDL with arbitrary virtual address while ConsumeTx function is responsible for mapping the virtual address stored in the MDL in the user process creating the driver call. Note that we need both VirtualAddress1 and VirtualAddress2 for the IOCTL code to work.

Another thing to note here is that we pass 0xffffffff00000008 as the value for the switch_case variable. This variable is used to direct the flow to right switch branch along with a controlled value over Priority field for mapping.

The switch_case value passed to PublishTx is accessed in ConsumeTx when the MDL is about to be mapped inside the user address space.

For a value of 0xffffffff00000008, the switch_case branches out on the 32 bit LSB which in our case is 8. The priority on other hand is decided by full 64 bit value which after computation becomes 0x40000010 which is OR operation of MdlMappingNoExecute | NormalPagePriority which implies that the page is mapped for write operations as well.

Refer to the exploit code on how to create requests for ConsumeTx, PublishTx and DrainTx.

Step 4 : Write Primitive

The below execution flow allows for write primitive :-

void WritePrimitive(uint64_t What, uint64_t Where) { // PublishTx poc_.PublishTx(Where); // ConsumeTx poc_.ConsumeTx(); // DrainTx poc_.DrainTx(); *reinterpret_cast<uint64_t*>(poc_.GetMappedAddr()) = What;}

We don't execute InitializeStream and RegisterStream since by the time it reaches the Write Primitive, read primitive would be executed first and the mentioned functions would already be executed.

We use the same technique that we used for Read Primitive since the address is mapped with read and write.

_TOKEN structure

The token structure contains fields from 0x40 that indicate the privileges associated with the token.

+0x40 Present : Uint8B+0x48 Enabled : Uint8B+0x50 EnabledByDefault : Uint8B

To escalate privileges via write primitive, we can simply overwrite the fields at offset 0x40, 0x48 and 0x50 with the values that are present in the _TOKEN of system process.

Note : The _TOKEN address obtained via any means should have the last bit set to 0. So simply AND the address with 0xfffffffffffffff0

Time wasted on :-

The below are the pointers where I wasted lot of time on silly mistakes.

  • While reversing, I figured out that we need to execute both InitializeStream and RegisterStream functions but I was not able to execute both the functions on a single driver handle. This lead me to realize that we need 2 driver handles. One driver handle would be responsible for creating InitializeStream and another one would be responsible for creating RegisterStream. If our main driver handle is say driver1_ , then InitializeStream needs to be done on handle1_ while RegisterStream needs to be done on driver2_.

The reason for this is because of a check in ConsumeTx shown below :

The variable g4 is initialized to 1 only in RegisterStream function in mskssrv driver. As shown below, the driver fetches the stream pointer from a list and sets g4 structure member to 1

The reason we were not able to use the same driver handle is because of this check in RegisterStream operation

 ... if ( CurrentStackLocation->Parameters.DeviceIoControl.IoControlCode != 0x2F0420 || CurrentStackLocation->FileObject->FsContext2 ) { return STATUS_INVALID_DEVICE_REQUEST; } ...

The FsContext2 is set for a IRP that corresponds to a single driver handle. This means that if we create a new driver handle, then FsContext2 by default will be null and this check would be passed and hence the need to create a new driver handle.

  • Given the read write primitives, I wanted to use less number of read and writes. This means that traversing the eprocess linked list in kernel is not a feasible approach since this would be multiple reads. Reading about few techniques, I found this blackhat paper.

I decided to use the OpenProcessToken approach. OpenProcessToken returns a token handle that can be used along with NtQuerySystemInformation to obtain the kernel address of the _TOKEN object. I wasted lot of time trying to understand why the Token address returned via above method was not same to the token address obtained via _EPROCESS structure from debugger.

Eventually I realized that I was looking at wrong process. The exploit process would be a child process of cmd.exe and as such we need to find the _EPROCESS of the exploit process rather than cmd.exe and then calculate the value. The Token address returned via _EPROCESS would be same as the one obtained via previous method. A stupid mistake 😄

Full exploit can be found at Github.

References :-

  • BlackHat paper on methods for token based privilge escalation : here

  • A awesome blog on the bug by yar-eb here

  • Theori blog for a detailed analysis here.

mskssrv.sys - CVE-2023–29360 | Researchs (2024)

FAQs

What is CVE 2023 29360 Microsoft streaming service elevation of privilege vulnerability? ›

What is CVE-2023-29360? CVE-2023-29360 is a high-severity elevation of privilege vulnerability affecting Microsoft Streaming Service on various configurations of Microsoft Windows operating systems, including Windows 10, Windows 11, and Windows Server versions.

What is the vulnerability of KS SYS? ›

The specific flaw exists within the UnserializePropertySet function in the ks. sys driver. The issue results from the lack of proper locking when performing operations on an object. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of SYSTEM.

Is CISA warns of Microsoft streaming bug exploited in malware attacks? ›

CISA ordered U.S. Federal Civilian Executive Branch agencies to secure their Windows systems against a high-severity vulnerability in the Microsoft Streaming Service that's actively exploited in attacks.

What is the proof of concept of CVE 2023 21839? ›

Proof-of-Concept (PoC) – CVE-2023-21839

The vulnerability is caused by the ability to set the remote JNDI name and bind it to an object on the WebLogic server. This can be done using the weblogic. deployment. jms.

What does CVE stand for Microsoft? ›

The Weaknesses page in Microsoft Defender Vulnerability Management lists known Common Vulnerabilities and Exposures (CVE) by their CVE ID. CVE IDs are unique IDs assigned to publicly disclosed cybersecurity vulnerabilities that affect software, hardware and firmware.

What is Windows Remote Access elevation of privilege vulnerability? ›

An elevation of privilege vulnerability exists when Windows Remote Access improperly handles memory. To exploit this vulnerability, an attacker would first have to gain execution on the victim system. An attacker could then run a specially crafted application to elevate privileges.

How to fix KS sys? ›

How to get rid of the SYSTEM_SERVICE_EXCEPTION (ks. sys) BSOD
  1. Method 1.
  2. Method 2.
  3. Check Connected Hardware.
  4. Disable, Uninstall, Update, or Change Your Antivirus Tool.
  5. Disable the Antivirus Tool.
  6. Update, Uninstall or Change the Antivirus Tool.
  7. Uninstall Conflicting Applications.
  8. Go Back to the Previous Skype Version.
May 25, 2021

What is the common vulnerability score? ›

The Common Vulnerability Scoring System (CVSS) is a standardized framework for measuring information systems' severity of security flaws. It assigns each vulnerability a score between 0 and 10, with higher scores meaning more severe issues.

What is the Kerberos checksum vulnerability? ›

A critical vulnerability that was recently found in Kerberos might allow an attacker with domain user credentials to elevate to domain administrator privileges. This is also known as the "Kerberos Checksum Vulnerability".

What is the MSKSsrv sys process? ›

The Microsoft Kernel Streaming Server (mskssrv. sys) is a component of a Windows Multimedia Framework service, Frame Server. The service virtualizes the camera device and allows the device to be shared between multiple applications.

What are 3 of the most common signs that your computer has been compromised by malware? ›

If your computer is hacked, you might notice some of the following symptoms:
  • Frequent pop-up windows, especially the ones that encourage you to visit unusual sites, or download antivirus or other software.
  • Changes to your home page.
  • Mass emails being sent from your email account.

How do you know if your system is infected by malware? ›

How To Know if You Have Malware
  1. suddenly slows down, crashes, or displays repeated error messages.
  2. won't shut down or restart.
  3. won't let you remove software.
  4. serves up lots of pop-ups, inappropriate ads, or ads that interfere with page content.
  5. shows ads in places you typically wouldn't see them, like government websites.

Does every vulnerability have a CVE? ›

Each vulnerability must have one record in the CVE list. There are certain criteria to be satisfied to assign a CVE ID to a vulnerability: The vulnerability should have a negative impact on security. The vulnerability can be fixed independently.

How is a CVE created? ›

The CNA assigns the information a CVE ID, and writes a brief description and includes references. Then the new CVE is posted on the CVE website. Often, a CVE ID is assigned before a security advisory is made public. It's common for vendors to keep security flaws secret until a fix has been developed and tested.

What is CVE 2023 26360? ›

At its core, CVE-2023-26360 is an improper access control vulnerability caused by deserializing untrusted data without proper validation.

What is Microsoft Exchange Server elevation of privilege vulnerability? ›

What does this mean for this vulnerability? In this case, an attacker with elevated privileges on the Exchange server could gain the rights of a Domain Administrator. This could allow access and controls outside of the expected scope of the targeted functionality.

What is elevation of privilege vulnerability in Microsoft edge? ›

This metric reflects the context by which vulnerability exploitation is possible. The Base Score increases the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable component.

What is elevation of privilege vulnerability in framework? ›

An elevation of privilege vulnerability exists in the way that the . NET Framework validates the number of objects in memory before copying those objects into an array. An attacker who successfully exploited this vulnerability could take control of an affected system.

What is Windows graphics component elevation of privilege vulnerability? ›

Microsoft Windows Graphics Component Elevation of Privilege (CVE-2024-38085) Who is Vulnerable? A privilege escalation vulnerability exists in Microsoft Graphics Component. Successful exploitation of this vulnerability would allow a remote attacker to gain unauthorized access to the affected system.

References

Top Articles
Soft and Chewy Amish Gingersnap Cookies Recipe - Amish Heritage
46 Quick and Easy Dinner Recipe Ideas That Literally Anyone Can Make
Supermotocross Points Standings
'That's Hilarious': Ahsoka's Ezra Bridger Actor Reveals Surprising True-To-Life Detail Behind Sabine Reunion Scene
Words With Friends Cheat Board Layout 11X11
Dana Point: Your Ultimate Guide to Coastal Adventures
Tripadvisor London Forum
Tiffany's Breakfast Portage
Morgandavis_24
Gateway Login Georgia Client Id
Terry Gebhardt Obituary
Sir Mo Farah says 'sport saved me' after finishing final race of illustrious career at Great North Run
Nyc Peep Show 2022
Wdel News Today
Courierpress Obit
Bones And All Showtimes Near Tucson Spectrum 18
Vegamovies 2023 » Career Flyes
Patriot Ledger Obits Today
Bootyandthebeast69 Swap
Busted Newspaper Hampton County VA Mugshots
Red Lobster cleared to exit bankruptcy under new owner Fortress
Otis Inmate Search Michigan
Naydenov Gymnastics Reviews
Python Regex Space
636-730-9503
Zen Leaf New Kensington Menu
Lee Lucas Jaliyah Dad
Carlitos Caribbean Bar & Grill Photos
Haktuts.in Coin Master 50 Spin Link
Katmoie
Southern Food Buffet Near Me
Funny Shooter Unblocked
San Diego Cars And Trucks Craigslist
Koinonikos Tourismos
Mcdonald's Near Me Dine In
Https Eresponse Tarrantcounty Com
The Flash 2023 1080P Cam X264-Will1869
Jami Lafay Gofundme
Kare11.Com Contests
We Tested and Found The Best Weed Killers to Banish Weeds for Good
Chihuahua Adoption in Las Vegas, NV: Chihuahua Puppies for Sale in Las Vegas, NV - Adoptapet.com
Dr Ayad Alsaadi
Understanding Turbidity, TDS, and TSS
iPhone reconditionné
2005 Lund Boat For Sale in Ham Lake, MN Lot #67597***
Mychart Mountainstarhealth
A1.35.3 Spanish short story: Tending the Garden
Craigslist Farm And Garden Reading Pa
Unblocked Games Shooters
Fetid Emesis
Olive Onyx Amora
Love & Basketball streaming: where to watch online?
Latest Posts
Article information

Author: Rev. Leonie Wyman

Last Updated:

Views: 5692

Rating: 4.9 / 5 (79 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Rev. Leonie Wyman

Birthday: 1993-07-01

Address: Suite 763 6272 Lang Bypass, New Xochitlport, VT 72704-3308

Phone: +22014484519944

Job: Banking Officer

Hobby: Sailing, Gaming, Basketball, Calligraphy, Mycology, Astronomy, Juggling

Introduction: My name is Rev. Leonie Wyman, I am a colorful, tasty, splendid, fair, witty, gorgeous, splendid person who loves writing and wants to share my knowledge and understanding with you.