{
	"id": "bfd35bc2-2aa4-452b-89ab-fa13a30cc755",
	"created_at": "2026-04-06T00:13:35.108292Z",
	"updated_at": "2026-04-10T03:21:48.597879Z",
	"deleted_at": null,
	"sha1_hash": "fe111dd464ac00be403317bafe8d5ac1d224ce0e",
	"title": "Analyzing COMmunication in Malware | 0ffset Training Solutions",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 549334,
	"plain_text": "Analyzing COMmunication in Malware | 0ffset Training Solutions\r\nBy 0verfl0w_\r\nPublished: 2019-01-15 · Archived: 2026-04-05 14:44:59 UTC\r\nIf you follow me on Twitter (@0verfl0w_), you may have noticed a while back that I was analyzing a sample of\r\nUrsnif/Gozi/ISFB (which I will refer to as ISFB) and was confused as to how it was able to communicate with its\r\nC2 servers through a separate process, without injected DLL’s or process hollowing. I managed to locate a great\r\narticle by Mandiant (here) from 2010 about how COM can be used to control a process, such as Internet Explorer,\r\ninto performing certain actions.\r\nIn this post, I will be exploring the COM mechanisms that the latest versions of ISFB utilize in order to contact\r\nthe command and control servers stealthily. I do have quite a long post going up (hopefully) in the next couple of\r\nweeks that goes into detail about this specific strain of ISFB, and the multiple unpacking stages it goes through\r\nbefore the final stage, so stay tuned for that!\r\nWhat is exactly is COM?\r\nAccording to Microsoft, “The Microsoft Component Object Model (COM) is a platform-independent, distributed,\r\nobject-orientated system for creating binary software components.” To sum it up, COM allows programs to\r\ninteract with each other through COM objects. This interaction can occur\r\n“within a single process, in other processes, and can even be on remote computers“, and the language that the\r\nprogram was written in does not matter – as long as it is able to create structures of pointers and call functions\r\nthrough those pointers, it is COM Compatible – meaning languages like Visual Basic and Java can use COM. If\r\nyou want to learn more about COM, you can check out Microsoft’s own description and tutorials on it here.\r\nAs a result of the progression of technology, COM isn’t used as frequently anymore, and therefore when an\r\nanalyst comes across a piece of malware utilizing this unfamiliar communication method, it may be difficult to\r\npinpoint what is happening, and how. Static analysis is even more complex, unless you know what you are\r\nlooking for – which is what this article is about.\r\nCOM Mechanisms and its use in the ISFB Loader\r\nSecond Stage Loader MD5: 5019f31005dba2b410b21c4743ef4e98\r\nI have uploaded the first stage and dumped second stage loader to VirusBay, so that you can follow the steps if\r\nyou want to. I will be focusing on the second stage loader, as that is where the communication with the C2 occurs.\r\nI will be analyzing it statically using IDA, although you can do it dynamically as well.\r\nThe first giveaway that malware could be using COM functionality for communicating with it’s C2 server is a call\r\nto CoInitializeEx. Calling this function will initialize the COM library so that the calling thread can utilize it’s\r\nfunctionality. Taking a look at the flow of this sample, it is clear that if initializing the library fails, it will exit –\r\nhinting that it heavily relies on the COM library being loaded successfully.\r\nhttps://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nPage 1 of 5\n\nOnce we have discovered it is initializing the COM library, we can search for calls to CoCreateInstance, as this\r\nspawns an uninitialized object of the class associated with a specific CLSID, meaning you will notice a new\r\nprocess being spawned after you step over this call. Whilst there are many cross references to CoCreateInstance in\r\nthis sample, we are able to determine which one calls Internet Explorer based on the CLSID pushed before the\r\nfunction call. IDA will show you the CLSID based on how it looks in memory, and as a result, we can find the\r\ncorresponding object that is called. But how?\r\nThe CLSIDs of different objects are stored in the registry, and so whenever CoCreateInstance is called, the system\r\nchecks the registry for the passed CLSID. From the image above, we can tell that the CLSID being utilized is\r\n{0002DF01-0000-0000-C000-000000000046}, which we can lookup in the registry. You can find a list of all the\r\navailable CSLIDs at HKEY_CLASSES_ROOT\\CLSID. Once the CLSID has been located, it should reveal\r\nwhat process is being created, and in this case it is Internet Explorer (Ver 1). Moreover, the IE_riid that is being\r\npassed to the function informs us of the interface being used – in this case the riid being used is {EAB22AC1-\r\n30C1-11CF-A7EB-0000C05BAE0BE}, which when looked up in the registry reveals that it is the\r\nMicrosoft Web Browser Version 1. When we google this riid, it comes up with results for the IWebBrowser\r\ninterface.\r\nhttps://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nPage 2 of 5\n\nNow that we know for sure what instance is being created, we can look at what functions are being called. IDA\r\nPro has a plugin called COM helper which will detect CLSIDs and alter the names to resemble what they point to,\r\nhowever this isn’t possible in the free version, so you would have to look it up in the registry. When looking at\r\ncalls to COM functions in IDA, all you would see is call dword ptr [ecx+2Ch], which doesn’t tell you much\r\nunless you know the functions inside out. That is why we have to create a structure in IDA that allows us to assign\r\nunderstandable functions to these pointers. Simply click on the Structures tab and press the INSERT Key to add a\r\nnew structure. Then click Add Standard Structure. In this case, we know Internet Explorer is being called, and a\r\nquick google search for “Controlling Internet Explorer using COM C” will show code on several pages referring\r\nto IWebBrowser2, and so the Standard Structure we want to create is called IWebBrowser2Vtbl, which is\r\npossible to create using the free version of IDA Pro. Furthermore, we know that IWebBrowser was being used as\r\nwell, so we should also create a Standard Struct for that as well.\r\nOne way you can determine other interfaces that are being utilized is to simply look for calls to QueryInterface,\r\nas this retrieves pointers to all calls available in that Interface. This will allow you to create the correct standard\r\nstructures, and resolve the calls to these functions.\r\nhttps://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nPage 3 of 5\n\nThis standard structure will contain a list of functions exported by IWebBrowser2, and so we can simply resolve\r\nany pointers to those functions, such as dword ptr [ecx+2Ch], which can be resolved to\r\nIWebBrowser2Vtbl.Navigate(). Dynamic analysis becomes quite important here, as you can then start matching\r\nup functions correctly, rather than assuming a pointer is pointing to a function in that struct.\r\nIf you were debugging this program, these functions would show up as ObjectStublessClient, and sometimes you\r\nwill have to rely on the pushed values to determine what the function was doing. Once we have fully resolved\r\nmost of the calls, we can get an idea of what is happening:\r\nInstance of Internet Explorer is created using CoCreateInstance\r\nIWebBrowser2-\u003eNavigate() is called, passing the C2 URL and gathered data as arguments. This will cause\r\nIE to navigate to that URL\r\nIWebBrowser2-\u003eget_ReadyState() is called, comparing the return value with 4\r\n(READYSTATE_COMPLETE) – if it is 4, the function will continue, otherwise it will sleep for 500\r\nmilliseconds and retry the call.\r\nIWebBrowser2-\u003eget_Document() is called, which physically loads in the page that has been navigated to.\r\nIUnknown-\u003eQueryInterface() is called, passing the CLSID for IHTMLDocument2 to it.\r\nIUnknown-\u003eQueryInterface() is called, passing the CLSID for IHTMLElement to it.\r\nIHTMLDocument2-\u003eget_Body() is called, which returns a pointer to the website body.\r\nIHTMLElement-\u003eget_OuterText() is called, which returns the raw data from the C2 server\r\nThe data is then decrypted and parsed by the malware\r\nCOM usage currently seems quite popular among malware authors, possibly due to the fact that it is often\r\nundetected by several anti malware programs, as well as being able to remain under the radar from unsuspecting\r\nresearchers, such as myself – such as this post by Nocturnus Research Team, which details how the banking trojan\r\nRamnit utilizes COM API to create scheduled tasks, in an attempt to remain persistent.\r\nhttps://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nPage 4 of 5\n\nSo that brings an end to this brief post – but make sure to stay tuned for a much longer post on reversing ISFB,\r\nsometime this month!\r\nSource: https://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nhttps://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA",
		"Malpedia"
	],
	"references": [
		"https://0ffset.net/reverse-engineering/analyzing-com-mechanisms-in-malware/"
	],
	"report_names": [
		"analyzing-com-mechanisms-in-malware"
	],
	"threat_actors": [],
	"ts_created_at": 1775434415,
	"ts_updated_at": 1775791308,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fe111dd464ac00be403317bafe8d5ac1d224ce0e.pdf",
		"text": "https://archive.orkl.eu/fe111dd464ac00be403317bafe8d5ac1d224ce0e.txt",
		"img": "https://archive.orkl.eu/fe111dd464ac00be403317bafe8d5ac1d224ce0e.jpg"
	}
}