Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

Legends 

Low Level Win 11 socket POC // AFD.sys method // No Winsock

Low Level AFD.sys
Socket Creation
for Windows 11


I found this write-up about some undocumented functions in Windows.
This method uses AFD.sys on Win11, and does not use Winsock to open a socket.

Further research with IOCTL can be done to identify how the socket can be used.

This guide can help blue teams & cybersecurity researchers defend their machines by teaching them more about the lesser known & undocumented AFD.sys interface!

Software developers can write more efficient code, low level, and without relying on a boring library like Winsock. I'll be interested in hearing what people can discover or learn from this.

Read the Paper:

https://github.com/LNodesL/files/blob/ma...rfaces.pdf

Mirror:

https://mega.nz/file/AvUESQLS#6dUV8TN-cO...yw0Pdl36ak


Similar articles:
https://leftarcode.com/posts/afd-reverse...ing-part1/
https://leftarcode.com/posts/afd-reverse...ing-part2/


My Golang example:
https://github.com/LNodesL/Golang-AFD.sy...t-Creation


Here is the example code below that they gave. Keep in mind though that your machine's values may be different, and you shouldn't run this without reading the attached PDF first...


Spoiler (Click to View)

Read and learn,
Be a legend.

Oh this is very interesting! PDF Downloaded for sure.
(Oct 21, 2025 08:45 PM)PhillyStyle Wrote:  Oh this is very interesting! PDF Downloaded for sure.

:D happy researching!

You will need to do a good amount of work for real connections, but it's possible.
Please be very careful... low level work can be messy if you don't undo certain changes, or if you mess with your machine too much!
(Oct 21, 2025 08:25 PM)Hackers Wrote:  
Low Level AFD.sys
Socket Creation
for Windows 11


I found this write-up about some undocumented functions in Windows.
This method uses AFD.sys on Win11, and does not use Winsock to open a socket.

Further research with IOCTL can be done to identify how the socket can be used.

This guide can help blue teams & cybersecurity researchers defend their machines by teaching them more about the lesser known & undocumented AFD.sys interface!

Software developers can write more efficient code, low level, and without relying on a boring library like Winsock. I'll be interested in hearing what people can discover or learn from this.

Read the Paper:

https://github.com/LNodesL/blue-team-def...rfaces.pdf


Mirror:

https://mega.nz/file/AvUESQLS#6dUV8TN-cO...yw0Pdl36ak


Here is the example code below that they gave. Keep in mind though that your machine's values may be different, and you shouldn't run this without reading the attached PDF first...


Spoiler (Click to View)

Read and learn,
Be a legend.


Thanks for the share. I book marked it. I will look into it later but very interesting.

I learned ASM 86-64bit and right now want to make stuff at the lower level.
I made my own apps but using the API. I did just just to learn what is commonly done.
I am right now slowly trying to learn how to not use the API and try to do my own thing directly with the kernel.

I seen this file being used with process monitoring app.

Don't you need kernel level assess to use this file?
Got any tips for people just starting out new monkeying with low level stuff.

(Oct 21, 2025 09:16 PM)Hackers Wrote:  :D happy researching!

You will need to do a good amount of work for real connections, but it's possible.
Please be very careful... low level work can be messy if you don't undo certain changes, or if you mess with your machine too much!

It's actually good to do this. However, I think there's a lot of ways to BOS the socket stack.
It requires driver level kernel access. I think you would have to use an VM if you want to test things because it can damage your computer.

However, once you do this you can make your own lib and then use that instead. It's more secure meaning you won't have to rely heavily on Microsoft code.
I don't know if this is practical thought. They said online that it's best to use a kernel level version of winsock.
The reason they said the AFD.sys depends on the machine you run it on and the windows version it will have different values which could easily brick the system if it's wrong.

I will look more into it later in a couple of days.
[Image: bannerman2-0.png]
nice post mate. that code can be extended to be more sophisticated
#c/c++# & #asm#  

The way to patch bad code is to remove the bad code, not to add new bad code that hides the old bad code 
(Oct 27, 2025 06:46 PM)HiddenEyE Wrote:  nice post mate. that code can be extended to be more sophisticated

Definitely, I would like to see some people give it a go

ttbr0 CL1B are either of you up to the task? You could push this forward for the entire internet, there isn't much public past this starting POC.
Sick, I'll check this out and hopefully follow up.

itcorp , check this out.
(Nov 5, 2025 07:29 AM)CL1B Wrote:  Sick, I'll check this out and hopefully follow up.

itcorp , check this out.

Perfect, I figured you'd be interested in this :)
Quite nice and interesting post. I will take a look for sure.
(Nov 7, 2025 06:24 AM)arsium Wrote:  Quite nice and interesting post. I will take a look for sure.

let us know what you find
(Nov 7, 2025 06:26 AM)Hackers Wrote:  let us know what you find

Go to mswsock.dll. Inspect WSP*Proc. WSPListen, WSPAccept...

And here is :

Code
180001e38                        Status = NtDeviceIoControlFile(*(uint64_t*)(rax_3 + 8),
180001e38                            *(uint64_t*)((char*)rdi_1 + 0x10), nullptr, nullptr,
180001e38                            &IoStatusBlock, 0x1200b, &var_50, 0xc, 0, 0);

WSPListen :

Code
180001ddd                    struct IO_STATUS_BLOCK IoStatusBlock;
180001ddd                    *(uint32_t*)((char*)IoStatusBlock + 0x14) = (uint32_t)r14;
180001deb                    uint8_t var_48_1 = *(uint8_t*)(rax_3 + 0x45) >> 2 & 1;
1800130d5                    NTSTATUS Status;
1800130d5                    
1800130d5                    do
1800130d5                    {
180001dfb                        IoStatusBlock.Information = SockSanEnabled;
180001e38                        var_50;
180001e38                        Status = NtDeviceIoControlFile(*(uint64_t*)(rax_3 + 8),
180001e38                            *(uint64_t*)((char*)rdi_1 + 0x10), nullptr, nullptr,
180001e38                            &IoStatusBlock, 0x1200b, &var_50, 0xc, 0, 0);
180001e38                        
180001e49                        if (Status == STATUS_PENDING)
180001e49                        {
180001e4e                            LeaveCriticalSection(rax_3 + 0xe0);
180001e6b                            SockWaitForSingleObject(*(uint64_t*)((char*)rdi_1 + 0x10),
180001e6b                                arg1, 3, 4);
180001e73                            EnterCriticalSection(rax_3 + 0xe0);
180001e7f                            Status = IoStatusBlock..Status;
180001e49                        }
180001e49                        
180001e85                        if (Status >= STATUS_SUCCESS)
180001e85                        {
180001e93                            int32_t rax_5 = SockNotifyHelperDll(rax_3, 2);
180001e98                            rdi_2 = rax_5;
180001e98                            
180001e9c                            if (rax_5)
180001e9c                                goto label_18001307b;
180001e9c                            
180001ea2                            *(uint8_t*)(rax_3 + 0x44) |= 1;
180001ea2                            
1800130ed                            if (Ws2SqmInitStatus == 1 && *(uint32_t*)(rax_3 + 0x20) == 1)
1800130ed                            {
1800130f6                                int32_t rax_10 = data_180063b4c;
1800130f6                                data_180063b4c += 1;
1800130f6                                
180013103                                if (rax_10 + 1 > 0)
180013103                                {
180013109                                    void* Ws2SqmInfo_1 = Ws2SqmInfo;
180013109                                    
180013113                                    if (rax_10 + 1
180013113                                            > *(uint32_t*)((char*)Ws2SqmInfo_1 + 0x50))
180013119                                        *(uint32_t*)((char*)Ws2SqmInfo_1 + 0x50) =
180013119                                            rax_10 + 1;
180013103                                }
1800130ed                            }
1800130ed                            
180001eb7                            if (*(uint8_t*)(rax_3 + 0x45) & 0x10)
180001eb9                                SockTLNPIListenerCount += 1;
180001eb9                            
180001ec4                            int32_t rax_6 = SockSetHandleContext(rax_3);
180001ec9                            rdi_2 = rax_6;
180001ec9                            
180001ecd                            if (rax_6)
180001ecd                                goto label_18001307b;
180001ecd                            
180001ed9                            if (SockSanEnabled == rax_6)
180013121                                goto label_180001edf;
180013121                            
180013121                            int32_t rax_12 = *(uint32_t*)(rax_3 + 0x4c);
180013121                            
180013132                            if (rax_12 != data_1800626f4 && rax_12 != data_180062474)
180013132                                goto label_180001edf;
180013132                            
18001313e                            int32_t rax_13 = SockSanListen(rax_3, (uint32_t)r14);
18001313e                            
180013145                            if (!rax_13)
180013145                                goto label_180001edf;
180013145                            
180013152                            if (!(data_180063ae0 & 1))
180013152                                goto label_180001eec;
180013152                            
180013167                            WPP_SF_D(0xb,
180013167                                &WPP_95f507230b843ef815faab08b2fb8dc7_Traceguids, rax_13);
180013167                            goto label_18001316c;
180001e85                        }
180001e85                        
1800130cc                        if (Status != STATUS_INVALID_PARAMETER_12)
1800130cc                            break;
1800130cc                        
1800130ce                        Status = SockSanActivate();
1800130d5                    } while (Status >= STATUS_SUCCESS);

Currently, I did not dynamic analysis while debugging.

Remember the article for bind (WSPBind) for example the IOCTL Code (Part2):
0x12003 = #define IOCTL_AFD_BIND _AFD_CONTROL_CODE(AFD_BIND, METHOD_NEITHER) // 0x12003
Code
180004cbc                    (uint32_t)var_110 = 0x12003;
180004cdf                    NTSTATUS Status_1 = NtDeviceIoControlFile(*(uint64_t*)(rax_4 + 8),
180004cdf                        *(uint64_t*)((char*)r15_1 + 0x10), nullptr, nullptr,
180004cdf                        &IoStatusBlock, (uint32_t)var_110, rsi, InputBufferLength, rsi,
180004cdf                        OutputBufferLength);
(Nov 5, 2025 07:23 AM)Hackers Wrote:  ttbr0 CL1B are either of you up to the task? You could push this forward for the entire internet, there isn't much public past this starting POC.

ive already seen this make its way around my space before and its first mention was a while back dating back to 2020 with just whispers and then a poc back to 2022. it isnt particularly interesting enough for me to do anything about it but i would follow any development on it.
(Nov 8, 2025 07:38 PM)ttbr0 Wrote:  ive already seen this make its way around my space before and its first mention was a while back dating back to 2020 with just whispers and then a poc back to 2022. it isnt particularly interesting enough for me to do anything about it but i would follow any development on it.

Fair enough, do you know if they hit a wall or had any technical reasons to not continue? Was surprised to not find much on this topic
(Nov 9, 2025 05:51 AM)Hackers Wrote:  Fair enough, do you know if they hit a wall or had any technical reasons to not continue? Was surprised to not find much on this topic

i dont know. personally i dont really see why evasion on socket operations is useful when you can observe and track network data outside of the operating system. it might also be suspicious that a program is directly interacting with the driver. if i saw this in the wild, i would be immediately suspicious than if i saw something just using winsock functions.
(Nov 9, 2025 10:11 PM)ttbr0 Wrote:  i dont know. personally i dont really see why evasion on socket operations is useful when you can observe and track network data outside of the operating system. it might also be suspicious that a program is directly interacting with the driver. if i saw this in the wild, i would be immediately suspicious than if i saw something just using winsock functions.

Agreed, it would be instantly suspect

My thought is maybe red teams could use it with other methods and stay undetected if the blue team is not looking for this.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[.NET] by xloaderJul 8, 2025 09:28 AM 9 2,133 Jul 8, 2025 09:28 AM
Last Post: Mumbaiboys
[Source] by KrishnaGangaMay 28, 2025 01:46 AM 2 404 May 28, 2025 01:46 AM
Last Post: KrishnaGanga
[C#] by PaskowskyJan 11, 2020 04:13 AM 16 946 Jan 11, 2020 04:13 AM
Last Post: BadByte