Skip to content

Conversation

@Still34
Copy link
Contributor

@Still34 Still34 commented Nov 29, 2025

Summary

The communication/socket/tcp/create-tcp-socket-via-raw-afd-driver.yml rule currently does not match many of the in-the-wild samples that utilize the same technique; this is primarily due to the required CreateEvent, as many of the examples hold the lock outside of the function or do not have one in the first place.

This PR moves the CreateEvent to the optional scope, therefore should make more of the samples that utilize this technique to be matched.

References

https://www.unknowncheats.me/forum/c-and-c-/500413-native-tcp-client-socket.html
418d37c488b5fc534e0ee34d3c4eab5a02ba3c3c42ca3fcc5df3ef1c6673ef62:0x0040D374

2025-11-29_10-05-35-(vmconnect)-

@mr-tz
Copy link
Collaborator

mr-tz commented Dec 1, 2025

Thanks!

@mike-hunhoff
Copy link
Collaborator

Nice catch @Still34 !

We're failing lints here, see:

 create TCP socket via raw AFD driver
  FAIL: rule format incorrect: use scripts/capafmt.py or adjust as follows
  rule:
    meta:
      name: create TCP socket via raw AFD driver
      namespace: communication/socket/tcp
      authors:
        - [email protected]
      scopes:
        static: function
        dynamic: unsupported
      mbc:
        - Communication::Socket Communication::Create TCP Socket [C0001.011]
      references:
        - https://www.x86matthew.com/view_post?id=ntsockets
      examples:
        - 0fd8330e00aa48676d6d0c4f36e9a80b:0x1400132B0
        # FLIRT FP: ?DERReencode@CryptoPP@@YAXAEAVBufferedTransformation@1@0@Z
        # - 59a6c5036241a2f604e755bf523eb084:0x1400010D0
    features:
      - and:
        # wanted, but the routine is resolved via GetProcAddress into a global
        # - api: ntdll.NtCreateFile
  
        - string: "\\Device\\Afd\\Endpoint"
        - or:
          - description: a hardcoded byte array that provides the socket details
to the AFD driver via "extended attributes".
  
          # the raw byte sequence
          - bytes: 00 00 00 00 00 0F 1E 00 41 66 64 4F 70 65 6E 50 61 63 6B 65 
74 58 58 00 00 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 06 00 00 00 00 00 00
00 00 00 00 00 60 EF 3D 47 FE = bExtendedAttributes for IPv4 TCP
  
          # in the example code, in debug mode, the array is constructed 
bytewise on the stack
          - basic block:
            - and:
              - description: bExtendedAttributes for IPv4 TCP on stack, bytewise
              # i've kept the values approximately in order while removing some 
duplicates for clarity
              - number: 0x00
              - number: 0x0F
              - number: 0x1E
              - number: 0x41 = A
              - number: 0x66 = f
              - number: 0x64 = d
              - number: 0x4F = O
              - number: 0x70 = p
              # - number: 0x65 = e
              - number: 0x6E = n
              - number: 0x50 = P
              - number: 0x61 = a
              - number: 0x63 = c
              - number: 0x6B = k
              - number: 0x65 = e
              - number: 0x74 = t
              - number: 0x58 = X
              - number: 0x02
              - number: 0x01
              - number: 0x06
              # - number: 0x00
              - number: 0x60
              - number: 0xEF
              - number: 0x3D
              - number: 0x47
              - number: 0xFE
  
          # in the example code, in release mode, the array is constructed 
word-wise on the stack
          - basic block:
            - and:
              - description: bExtendedAttributes for IPv4 TCP on stack, wordwise
              - number: 0x1E0F00 = bExtendedAttributes+0x4
              - number: 0x4F646641 = AfdO
              - number: 0x506E6570 = penP
              - number: 0x656B6361 = acke
              - number: 0x585874 = tXx
              - number: 6 = IPPROTO_TCP
              - number: 1 = SOCK_STREAM
              - number: 2 = AF_INET
              - number: 0x473DEF60 = bExtendedAttributes+0x34
              - number: 0x0FE = bExtendedAttributes+0x38
        - optional:
          - api: NtCreateFile
          - api: NtDeviceIoControlFile
-         - api: kernel32.CreateEvent 
?                                    -
+         - api: kernel32.CreateEvent
          - api: kernel32.WaitForSingleObject
          - number: 0x12003 = IOCTL_AFD_BIND
          - number: 0x12007 = IOCTL_AFD_CONNECT
          - number: 0x12017 = IOCTL_AFD_RECV
          - number: 0x1201F = IOCTL_AFD_SEND

You can run our lints locally to double check before your next commit.

Signed-off-by: Still Hsu <[email protected]>
@Still34
Copy link
Contributor Author

Still34 commented Dec 3, 2025

Should work now - I did not expect the linting to fail since it doesn't seem to automatically trigger the linting check workflow now

@mr-tz mr-tz merged commit fb3737b into mandiant:master Dec 4, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants