Lucene search

K
attackerkbAttackerKBAKB:5297439F-EFF0-4C64-90EF-DB07917497E3
HistoryJan 10, 2023 - 12:00 a.m.

CVE-2023-21768

2023-01-1000:00:00
attackerkb.com
16

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

4.3 Medium

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:S/C:P/I:P/A:P

0.008 Low

EPSS

Percentile

79.6%

Windows Ancillary Function Driver for WinSock Elevation of Privilege Vulnerability

Recent assessments:

gwillcox-r7 at March 08, 2023 7:11pm UTC reported:

Interesting bug that was announced on Twitter at <https://twitter.com/chompie1337/status/1633498392125997056&gt; and later posted on GitHub at <https://github.com/xforcered/Windows_LPE_AFD_CVE-2023-21768&gt;. Bug occurs in afd.sys which is the Windows Ancillary Function Driver for WinSock, and allows privilege escalation from a local user to NT AUTHORITY\SYSTEM.

Whats interesting about this bug though is that unlike other EoP bugs, this only seems to affect Windows 11 and Windows Server 2022 according to <https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2023-21768&gt;. Additionally the exploit at <https://github.com/chompie1337/Windows_LPE_AFD_CVE-2023-21768&gt; is noted to only work on vulnerable Windows 11 22H2 systems, which raises the question of if there were some specific items that needed to be hardcoded for a specific version of Windows, such as offsets or similar.

The current exploit that is available, from my brief look at things, appears to use the I/O Ring R/W primitive that Yarden Shafir talked about at <https://windows-internals.com/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/&gt; and later released a PoC on at <https://github.com/yardenshafir/IoRingReadWritePrimitive&gt;. I’m somewhat surprised that Microsoft still hasn’t patched this several months later given how strict they have been at trying to fix such items in the past, but these things typically require complicated change to the OS so perhaps I shouldn’t be all too surprised, particularly given its dealing with I/O buffers which are heavily utilized.

After leaking some addresses it appears to do the standard SYSTEM token replacement using the leaked EPROCESS address of the SYSTEM process and then takes that security token and replaces the chosen processes’s security token with the SYSTEM security token. Note I say chosen here as the exploit takes a PID as an argument and uses that PID to find out which process’s token it should replace with the SYSTEM security token.

Looking closer at the exploit to perform some of the leaks there seems to be a reference to NtQuerySystemInformation which is commonly used for leaking information, however I don’t actually see that being used anywhere, so it looks like it is potentially left over code.

The main vulnerability exploit code appears to be centralized into ArbitraryKernelWrite0x1 in <https://github.com/xforcered/Windows_LPE_AFD_CVE-2023-21768/blob/master/Windows_AFD_LPE_CVE-2023-21768/exploit.c&gt;, which is then used to overwrite some entries in the IO ring buffer to transform it from arbitrary kernel write to arbitrary kernel read and write.

Looking into ArbitrarykernelWrite0x1 it seems it takes in a pointer to the address to overwrite, then creates an IPv4 extended TCP socket attribute structure, creates an IoCompletion object using NtCreateIoCompletion that allows for both querying and modifying the state, and allows one thread of concurrent access to the object.

We then call NtSetIoCompletion (documented to some degree at <http://undocumented.ntinternals.net/UserMode/Undocumented Functions/NT Objects/IoCompletion/NtSetIoCompletion.html&gt;) on the same object with a completion key of 0x1337 and pass it the empty IO_STATUS_BLOCK object IoStatusBlock so we can keep track of the IO status of this IoCompletion object. We set the completion status to 0, aka not completed, and set the number of bytes transferred in a manually finished I/O operation to 0x100. Not sure why this value was chosen but eh.

If this completes successfully, then we go ahead and make a UNICODE_STRING called ObjectFilePath that holds the string \\Device\\Afd\\Endpoint, which according “Reverse Engineering Windows AFD.sys” by Steven Vittitoe which was presented at Recon 2015 at <https://recon.cx/2015/slides/recon2015-20-steven-vittitoe-Reverse-Engineering-Windows-AFD-sys.pdf&gt;, is an endpoint that allows access to 70+ IOCTLs that are defined within the afd.sys driver.

Looking more at this paper we can also see that AFD.sys handles everything from TCP/IP to SAN and that its listed as the “Ring 0 entrypoint for WinSock”, aka all WinSock calls will end up going through this driver which executes at the kernel level. This is backed up by their point that it handles all socket() calls.

Anyway getting back to this we can see we also set an OBJECT_ATTRIBUTES object to the name of this string as the ObjectName parameter, and then set its attributes to 0x40, aka OBJ_CASE_INSENSITIVE as noted at http://www.jasinskionline.com/technicalwiki/Print.aspx?Page=Constants-Windows-API&AspxAutoDetectCookieSupport=1, as I guess we need case insensitive operations for this? Idk though without further info.

Finally we call NtCreateFile to create this file and save the handle into hSocket. We ask for the maximium permissions possible on this object, pass in the ObjectAttributes object attributes object we created earlier so that we use the \\Device\\Afd\\Endpoint and use case insensitive naming, pass in the IoStatusBlock for the I/O completion object, allow read and write sharing, pass in nothing for the creation options since this device should already be created, and pass in 1 aka FILE_OPEN so we open the existing file. Finally we pass in bExtendedAttributes which will hold the hardcoded extended attributes for a IPv4 TCP socket.

If all goes well then we should now have an file handle in hSocket however the AFD driver still isn’t fully aware of this socket. To complete this we then create a new Data object of type AFD_NOTIFYSOCK_DATA. This object type is not publicly documented anywhere as far as I can tell, and appears to have been guessed at via reverse engineering. In this structure we can see that we have a few pointers, a handle to hCompletion which explains our earlier completion object creation call, and some DWORDs.

The next few lines of the code will set the hCompletion parameter of this structure to the hCompletion object we created earlier, and after this we set pData1 and pData2 to 0x2000 byte long heap buffers that are readable and writeable and which have been reserved and committed in memory.

We then set dwCounter to 1 to indicate one entry, and set dwLen to 1. Not sure what dwLen controls though but we’ll have to wait for the blog for more details. We interestingly set dwTimeout to an insanely large value of 100000000. Its possible this may be related to an overflow which leads to the out of bound write, or it could be set this way to hold the connection open whilst the exploit happens and prevent timeouts. Finally we see that the address we wish to overwrite is placed into Data.pPwnPtr suggesting that this structure is responsible for the arbitrary overwrite and perhaps doesn’t validate that the address is actually a kernel address and not a user address like it should be.

Finally we create an event using CreateEvent and then call IOCTL 0x12127 on AFD, which the exploit notes as AFD_NOTIFYSOCK_IOCTL. My guess is that this processes the malicious Data structure of type AFD_NOTIFYSOCK_DATA and then fails to notice that the Data.pPwnPtr is out of the expected address range, allowing for an arbitrary write vulnerability.

Assessed Attacker Value: 4
Assessed Attacker Value: 4Assessed Attacker Value: 3

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

4.3 Medium

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:L/AC:L/Au:S/C:P/I:P/A:P

0.008 Low

EPSS

Percentile

79.6%