capa icon indicating copy to clipboard operation
capa copied to clipboard

add com class/interface features

Open williballenthin opened this issue 3 years ago • 1 comments

in https://github.com/fboldewin/COM-Code-Helper/pull/2 @stevemk14ebr adds definitions for around 3k COM class GUIDs and 23k COM interface GUIDs. this is probably one of the most comprehensive databases of COM constants out there. we should consider incorporating it into capa, possibly as a new type of feature, like:

or:
  com/class: WebBrowser       # maps to bytes: emit-guid(8856F961-340A-11D0-A96B-00C04FD705A2)
  com/interface: IWebBrowser  # maps to bytes: emit-guid(EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B)

williballenthin avatar Sep 18 '20 16:09 williballenthin

oh hey look its @fboldewin!

williballenthin avatar Apr 22 '21 16:04 williballenthin

@williballenthin https://github.com/fboldewin/COM-Code-Helper/blob/8d99c61f82541dd17a6232820ace1615fb92248b/code/interfaces.txt contains 5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C IBackgroundCopyManager is used as 0D 4C E3 5C C9 0D 1F 4C 89 7C DA A1 B7 8C EE 7C = IBackgroundCopyManager in https://github.com/mandiant/capa-rules/issues/332.

As u mentioned in https://github.com/mandiant/capa-rules/issues/332#issuecomment-824974853, that the bytes need to be reordered while matching, is it true for all COMs or was above just an exception.

Aayush-Goel-04 avatar Aug 08 '23 15:08 Aayush-Goel-04

to go from bytes to GUID string, example code (by Willi) is:

guid = "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % \
            (h[3], h[2], h[1], h[0],
             h[5], h[4],
             h[7], h[6],
             h[8], h[9],
             h[10], h[11], h[12], h[13], h[14], h[15])
return guid

mr-tz avatar Aug 09 '23 08:08 mr-tz

https://github.com/mandiant/capa/blob/ec93ca5b2176457516edf14735bd98b4b68a34c4/capa/rules/init.py#L594-L602

We can store the com, guid as a map as @williballenthin said.

In above snippet of capa.rules.__init__.build_statements

  • while building in parse_feature if key is com/class or com/interface then feature will be capa.features.common.Bytes
  • in parse_description based on key value we can fetch guid from map and convert it to bytes literal b'\x61....' and key value will become description, for example
or:
  com/class: WebBrowser       # maps to bytes: emit-guid(8856F961-340A-11D0-A96B-00C04FD705A2)
  com/interface: IWebBrowser  # maps to bytes: emit-guid(EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B)

for above features line 598 of code snipped will return feature as feature = Bytes(b'\x61\xF9\x56\x88\x34\x0A\x11\xD0\xA9\x6B\x00\xC0\x4F\xD7\x05\xA2', "WebBrowser")

Also should there be a single map or two separate maps for classes and interfaces? It seems logical for the maps to already exist in "capa" rather than being generated at runtime.

Aayush-Goel-04 avatar Aug 13 '23 20:08 Aayush-Goel-04

Yes, we should store the database in capa. In fact, I have a COM database (one file for class and interface) like this:

...
 '884e2046-217d-11da-b2a4-000e7bbb2b09': 'CX509Enrollment',
 '884e2049-217d-11da-b2a4-000e7bbb2b09': 'CX509EnrollmentWebClassFactory',
 '8854f6a0-4683-4ae7-9191-752fe64612c3': 'InkDivider',
 '8856f961-340a-11d0-a96b-00c04fd705a2': 'WebBrowser',
 '8858ffc3-3ac7-3dda-aec5-e43b3e425a4c': '_NotSerializableException',
 '885b5e08-c26c-4ef9-af83-51580a750be1': 'IFaxInboundRoutingExtension',
 '885c7b80-3fa2-4e5a-be07-cf01e1d6e2cd': 'iaudiomuteapo',
 '885d2e90-3cfd-39bb-b5da-f5bbd6584828': '_PRINTER_DEFAULTS',
...

mr-tz avatar Aug 14 '23 08:08 mr-tz

I agree with the proposals above.

I'd suggest that the GUID be encoded in at least two ways, as bytes and as a string, which we sometimes see. So the statement should be translated to:

- or:
  - description: IBackgroundCopyManager
  - string: "12380421-124-142-42-141141111" = IBackgroundCopyManager
  - bytes: 731478127891287912879124879827912789 = IBackgroundCopyManager

williballenthin avatar Aug 14 '23 08:08 williballenthin

@williballenthin @mr-tz So we have four following possible cases

- or:
   - description: IBackgroundCopyManager
     string: "12380421-124-142-42-141141111" = IBackgroundCopyManager
   - description: IBackgroundCopyManager
      bytes: 731478127891287912879124879827912789 = IBackgroundCopyManager
   - com/class: WebBrowser       # maps to bytes: emit-guid(8856F961-340A-11D0-A96B-00C04FD705A2)
   - com/interface: IWebBrowser  # maps to bytes: emit-guid(EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B)

and all of these will translate to feature = Bytes(b'\x61\xF9\x56\x88\x34\x0A\x11\xD0\xA9\x6B\x00\xC0\x4F\xD7\x05\xA2', "WebBrowser")

Aayush-Goel-04 avatar Aug 18 '23 19:08 Aayush-Goel-04

not exactly. we want to write com/interface: IFoo and have it be replaced by or: bytes: ..., string: ... (sorry on mobile so the formatting isn't great). the values for the bytes and strings should come from the database referenced in the first few comments.

we want to let rule authors refer to the symbolic names for the COM classes and interfaces, and let capa do the translation to the machine representations of the identifiers (GUIDs).

williballenthin avatar Aug 18 '23 21:08 williballenthin

Got it, thanks for explaining. Using symbolic names for COM classes/interfaces and having capa handle the translation to GUIDs sounds great.

Aayush-Goel-04 avatar Aug 19 '23 09:08 Aayush-Goel-04