{
	"id": "01114e88-8bc7-4705-b394-ee47054503f2",
	"created_at": "2026-04-06T00:06:07.397065Z",
	"updated_at": "2026-04-10T13:12:48.95002Z",
	"deleted_at": null,
	"sha1_hash": "502f1a938b985209e0924dc950928ec1ed00b953",
	"title": "How to analyze Linux malware – A case study of Symbiote – CYBER GEEKS",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 7129604,
	"plain_text": "How to analyze Linux malware – A case study of Symbiote –\r\nCYBER GEEKS\r\nPublished: 2022-07-26 · Archived: 2026-04-05 18:24:18 UTC\r\nSummary\r\nSymbiote is a Linux threat that hooks libc and libpcap functions to hide the malicious activity. The malware hides\r\nprocesses and files that are used during the activity by implementing two functions called hidden_proc and\r\nhidden_file. It can also hide network connections based on a list of ports and by hijacking any injected packet\r\nfiltering bytecode. The malware’s purpose is to steal credentials from the SSH and SCP processes by hooking the\r\nlibc read function. The extracted credentials are encrypted using RC4, stored in a file on the system, and then\r\nexfiltrated to the C2 server via DNS requests.\r\nAnalyst: @GeeksCyber\r\nTechnical analysis\r\nSHA256: 121157e0fcb728eb8a23b55457e89d45d76aa3b7d01d3d49105890a00662c924\r\nThis is a 64-bit ELF shared object that appears to be an early development build for Symbiote malware. Newer\r\nversions of this malware have even more functionalities which are described in BlackBerry’s analysis. The file is\r\nnot stripped.\r\nThe malware hooks the following functions: fopen, fopen64, pam_authenticate, pam_set_item, read, readdir,\r\nreaddir64, and recvmsg. We will give details about the hooks implementation.\r\nThe dlsym function is utilized to obtain the address of fopen, and then the process calls the original function\r\n(0xFFFFFFFFFFFFFFFF = RTLD_DEFAULT):\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 1 of 38\n\nFigure 1\r\nWhen an application tries to open the “/proc/net/tcp” file, which contains all TCP connections, the execution flow\r\nof the hooked function is different:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 2 of 38\n\nFigure 2\r\nThe ELF file creates a temporary file by calling the tmpfile method, reads the first line from the above file, and\r\nwrites it to the newly created file:\r\nFigure 3\r\nThe file is read line-by-line using the getline function. In the case of returning -1 because of a failure (including\r\nend-of-file condition), the process closes the file and frees the memory area allocated to the line:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 3 of 38\n\nFigure 4\r\nThere is a function called gen_proc_net_port implemented by the malware. The purpose of this function is to\r\nretrieve a list of ports that should be hidden. Whether a line read above contains any of the ports, the line is not\r\nwritten to the temporary file, and the process moves to the next line:\r\nFigure 5\r\nThe function implementation is displayed in the figure below:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 4 of 38\n\nFigure 6\r\nThe hooked function returns the file descriptor corresponding to the temporary file. The fopen64 function is\r\nhooked in a similar way.\r\nThe dlsym function is utilized to obtain the address of pam_authenticate, and then the process calls the original\r\nfunction:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 5 of 38\n\nFigure 7\r\nThe malware calls the pam_get_item method in order to obtain the following information: 0x1 =\r\nPAM_SERVICE – the service name, 0x4 = PAM_RHOST – the requesting hostname, 0x2 = PAM_USER – the\r\nusername. There is also a function call to getaddrlist, which will be explained in the upcoming paragraphs:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 6 of 38\n\nFigure 8\r\nBased on the information extracted above, the process constructs the following string “pam|\u003cgetaddrlist result\u003e|\r\n\u003cPAM_SERVICE\u003e|\u003cPAM_RHOST\u003e|\u003cPAM_USER\u003e|\u003ccs:pampassword\u003e”. There is a call to a function named\r\nsaveline with the “/usr/include/linux/usb/usb.h” parameter (see figure 9). This particular function will be dissected\r\nin the upcoming paragraphs.\r\nFigure 9\r\nThe ELF binary implements an erase function called erasefree. It overwrites an area with zeros, and then the\r\npointer which points to this area will be freed:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 7 of 38\n\nFigure 10\r\nFigure 11\r\nThe dlsym function is utilized to obtain the address of pam_set_item, and then the process calls the original\r\nfunction:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 8 of 38\n\nFigure 12\r\nThe process expects that the item_type value is equal to 0x6 (PAM_AUTHTOK), which is the authentication\r\ntoken (usually it’s a password):\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 9 of 38\n\nFigure 13\r\nThe dlsym function is utilized to obtain the address of readdir, as highlighted below:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 10 of 38\n\nFigure 14\r\nThe malware implements a function called check_proc, which will be explained in a bit. Depending on the\r\nboolean value returned by this function, the process calls the original readdir method and then hidden_file or\r\nhidden_proc:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 11 of 38\n\nFigure 15\r\nThe readdir64 function is hooked in a similar way.\r\nThe dlsym function is utilized to obtain the address of recvmsg, and then the process calls the original function:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 12 of 38\n\nFigure 16\r\nThe malicious process expects a specific message structure i.e. message[8] = 0xc, message[16] != 0, as displayed\r\nin the figure below:\r\nFigure 17\r\nThe ELF binary converts unsigned short integers from host byte order to network byte order using htons. The\r\nmessage is copied to another memory area using the memcpy method:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 13 of 38\n\nFigure 18\r\nIn the check_proc function, the malware gets the directory stream file descriptor and computes the following path\r\n“/proc/self/fd/\u003cFile descriptor\u003e”:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 14 of 38\n\nFigure 19\r\nThe path constructed above points to a symbolic link that is read using the readlink method. The function returns 1\r\nwhether the symbolic link contains “/proc” and 0 otherwise:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 15 of 38\n\nFigure 20\r\nThe malware implements a function called check_ssh_scp. It obtains the location of an executable by calling the\r\nreadlink function with the “/proc/self/exe” parameter:\r\nFigure 21\r\nThe purpose of this function is to detect the presence of the SCP/SSH executable and returns 0 if that’s the case:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 16 of 38\n\nFigure 22\r\nSymbiote implements the CRC32b algorithm in a function called crc32b. The algorithm can be identified using\r\nthe 0xEDB88320 constant:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 17 of 38\n\nFigure 23\r\nThere is a function called create_file that can be used to create files. It calls the open method (0x441 =\r\nO_WRONLY | O_CREAT | O_APPEND):\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 18 of 38\n\nFigure 24\r\nThe process changes the permissions of a file to 0x1B6 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |\r\nS_IROTH | S_IWOTH, which means that all users can read and write but cannot execute the file:\r\nFigure 25\r\nIn the function called dns, the ELF binary retrieves the current process ID that is converted  from host byte order\r\nto network byte order using htons:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 19 of 38\n\nFigure 26\r\nThe malware calls a function named ChangetoDnsNameFormat that will be explained below:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 20 of 38\n\nFigure 27\r\nThe malicious process creates a socket that will be used to communicate with the C2 server (0x2 = AF_INET,\r\n0x2 = SOCK_DGRAM, 0x11 = IPPROTO_UDP). The C2 server address is converted from dotted decimal\r\nnotation to an integer using the inet_addr method:\r\nFigure 28\r\nThe sendto function is utilized to send data to the C2 server:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 21 of 38\n\nFigure 29\r\nThe function called ChangetoDnsNameFormat prepares the structure of the request for DNS data exfiltration:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 22 of 38\n\nFigure 30\r\nIn the function named getaddrlist, the ELF binary extracts a linked list of structures containing the network\r\ninterfaces of the local machine using the getifaddrs method:\r\nFigure 31\r\nBased on the structures extracted above, the process extracts the IP addresses by calling the getnameinfo function:\r\nFigure 32\r\nThe interfaces IP addresses are concatenated together using the strcat method:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 23 of 38\n\nFigure 33\r\nIn the getserver function, the malicious binary tries to open a file called “/tmp/resolv.conf”:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 24 of 38\n\nFigure 34\r\nThe malware is looking for a nameserver in the above file. If there is no nameserver, then the process will use the\r\nGoogle DNS server (8.8.8.8) to send the DNS request as a UDP broadcast:\r\nFigure 35\r\nThe process compares two strings (file names) in the hidden_file function and returns 0 if they match:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 25 of 38\n\nFigure 36\r\nThe hidden_proc function expects a process ID as an argument. It calls the strspn and strlen functions in order to\r\nensure that the process ID consists of digits only:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 26 of 38\n\nFigure 37\r\nThe ELF binary retrieves information about a process from the “/proc/\u003cpid\u003e/status” file, as shown in figure 38.\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 27 of 38\n\nFigure 38\r\nThe purpose of this function is to compare two process names and to return 0 if they match (see figure 39).\r\nSymbiote’s objective is to hide some processes that are related to the malware such as: certbotx64, certbotx86,\r\njavautils, javaserverx64, javaclientex64, javanodex86 (BlackBerry’s article).\r\nFigure 39\r\nThe dlsym function is utilized to obtain the address of the read method. If an SSH or SCP process is calling the\r\nlibc read function, then hook_read is set to keylogger, which is explained below:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 28 of 38\n\nFigure 40\r\nIn the keylogger function, the process calls the original read function with a file descriptor corresponding to SSH\r\nor SCP. It also performs a call to the isatty method in order to ensure that the file descriptor is referring to a\r\nterminal:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 29 of 38\n\nFigure 41\r\nThe executable calls a function named log_cmd_line and then getaddrlist. The first function will be detailed in the\r\nfollowing paragraphs:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 30 of 38\n\nFigure 42\r\nThe malware constructs a string with the following structure “\u003cgetaddrlist result\u003e|\u003clog_cmd_line\r\nresult\u003e|pw_5673”. It calls the saveline function with the “/usr/include/linux/usb/usb.h” parameter:\r\nFigure 43\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 31 of 38\n\nThe log_cmd_line method is called only for the SSH or SCP process. The command line of one of these processes\r\nis read from “/proc/self/cmdline”:\r\nFigure 44\r\nThe realloc method is utilized to deallocate the old object and to return a pointer to a new object:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 32 of 38\n\nFigure 45\r\nThe credentials extracted from the SSH or SCP process are encrypted using the RC4 algorithm (key =\r\n“suporte42atendimento53log”). The encrypted content will be used to construct DNS requests in the sendlinedns\r\nfunction:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 33 of 38\n\nFigure 46\r\nThe malicious process creates a file called “/usr/include/linux/usb/usb.h” by calling create_file:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 34 of 38\n\nFigure 47\r\nThe encrypted credentials are written to the file created above:\r\nFigure 48\r\nIn the sendlinedns function, the malware obtains information about the current kernel using the uname method.\r\nBased on the resulting buffer, the process computes a machine ID which consists of 4 bytes generated using\r\ncrc32b (stored in id_6274):\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 35 of 38\n\nFigure 49\r\nThe encrypted credentials are hex-encoded and splitted to be exfiltrated via DNS requests to a domain owned by\r\nthe threat actor. The A DNS request has the following format:\r\n\u003cPacket number – starts from 0x2B67 = 11111\u003e.\u003cMachine ID – Crc32b hash\u003e.\u003cHex-encoded\r\ndata\u003e.px32.nss.atendimento-estilo[.]com\r\nFinally, the executable calls the dns function that will exfiltrate data:\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 36 of 38\n\nFigure 50\r\nThe implementation of the RC4 algorithm can be identified below:\r\nFigure 51\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 37 of 38\n\nFigure 52\r\nINDICATORS OF COMPROMISE\r\nC2 domain: px32.nss.atendimento-estilo[.]com\r\nSHA256: 121157e0fcb728eb8a23b55457e89d45d76aa3b7d01d3d49105890a00662c924\r\nFiles created: /usr/include/linux/usb/usb.h\r\nSource: https://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nhttps://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/\r\nPage 38 of 38",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://cybergeeks.tech/how-to-analyze-linux-malware-a-case-study-of-symbiote/"
	],
	"report_names": [
		"how-to-analyze-linux-malware-a-case-study-of-symbiote"
	],
	"threat_actors": [],
	"ts_created_at": 1775433967,
	"ts_updated_at": 1775826768,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/502f1a938b985209e0924dc950928ec1ed00b953.pdf",
		"text": "https://archive.orkl.eu/502f1a938b985209e0924dc950928ec1ed00b953.txt",
		"img": "https://archive.orkl.eu/502f1a938b985209e0924dc950928ec1ed00b953.jpg"
	}
}