Features:
Hooks accept() for socket connections Multi-factor authentication Suid Privesc Drop Process hiding File hiding
Strace log | Pcap log C’s accept() function is the function used when a socket connection is received and initiated by the server. This is typically used for all TCP-related server-side functionality written in C, and by overriding it, we can determine if this is regular traffic for the port, or if it’s the rootkit owner attempting to log in. In order to determine whether or not to hijack the socket’s file descriptor, we check against the client-side port (defined by highport and lowport in the pre-compile configuration of the rootkit) attempting to open the connection. If the port is correct, the file descriptor is hijacked and the connection and related processes becomes hidden from a typical administrator. Otherwise, the connection is passed to the service daemon and the service operates normally for the user connecting to the service, as if no rootkit is present. Due to the accept() hook, this rootkit does not require any modification of existing firewalls. This makes it particularly effective when the server is behind a network layer appliance type firewall, as no holes need to be poked. Any existing service may be hooked; so long as the service is restarted it will grant access as the service’s username, and suid shell drop is available. While this feature is similar to ncom’s accept() hook, the use of SSL is a vast improvement over it. Files and processes are hidden by several factors in the pre-compile configuration phase, along with a default password (DEFAULT_PASS). The factors used after authentication for hiding files and processes include a “Magic string” and a “Magic GID”. This means that any files beginning with a particular string (“XxJynx” by default) or owned by a particular group will automatically be hidden from the root user. However, due to the nature of the kit, we can still see this file when we are logged in from the netcat shell (an attacker’s perspective). This was fixed with the file “reality.so” installed to its INSTALL directory on installation of the kit. Like many things on UNIX (and Linux by extension), processes are represented as files. This is done the /proc filesystem in Linux. Every process is has a directory corresponding to its PID in /proc. For example: The files contain various pieces of information about the process, such as memory space, environment variables and current working directory. Since there is no API within Linux for viewing process information, all one must do to hide a process is hide its entry in the /proc file system. Since each the proc entries are owned by the owner of that process, any process started under the magic GID/UID will be hidden just the same as a file would be. Processes spawned by the backdoor or by the jynx user are also hidden from listing in /proc: By setting the LD_PRELOAD environment variable to the reality.so file, we can see hidden files, processes, and folders: Processes owned by the magic GID or spawned by the backdoor are hidden similarly from ps: There is no sleep process from the jynx user. Similarly, using the backdoor: As we can see here, there is no bash process running in ps for www-data. Additionally, by setting the environment variable matching the magic string, we’re able to obtain root privileges with the backdoor using a suid binary: The privilege escelation backdoor uses preloaded setuid bins to produce a root shell. For example, gpasswd, which is used in the above example: LD_PRELOAD will not normally apply to setuid binaries unless certain conditions are met, most notably the shared library must be placed in /lib and /usr/lib. However, this restriction does not apply to shared libraries placed in /etc/ld.so.preload. In each hooked/preloaded function there is a function which checks the environment variable XxJynx (which is set in config.h) for a specific value. If that value is set, it will spawn a root shell if it has the permissions to do so.
Detection:
LDD
Perhaps the simplest method of detection is with ldd, this is a simple ldd of the “ls” coreutil binary. This, of course could be changed to point to /etc/ld.so.preload, however if you try to access the file, it won’t exist. So, one method of detection would be to determine the presence of ld.so.preload etc or any library inside of an `ldd’ listing that cannot be read by your user using bash, claiming that the file does not exist.
strace
We ran “strace nc -l -p 6001”, as even netcat will be hooked, to show an example of the accept() hook. Here, we show netcat binding and listening on the port, then waiting for connection Now we can see the connection being accepted in strace: Once the password is entered, we see the kit hijacking the file descriptor:: Then moving to protect the connection: At this point in the sequence, an attacker has already entered root access level on the infected system, yet the connection does not appear in netstat, nor any additional PID’s appear in /proc or processes in ps/top. So we can easily make a comparison based from the strace with netstat in order to locate an attacker logging into a compromised machine.
Netstat and pcap discrepancies
Another method of detection includes the comparison of pcap data with netstat data; however it is also difficult to determine what the attacker was doing due to the shell being SSL encrypted. Our PCAP file contains a recording of the infected host’s traffic logs. Though this rootkit may hide from netstat, it does not yet hide from pcap. The SSL hook does not require the support of SSL within the service, only that SSL be installed on the system being infected.
Removal
The older method of removing jynx will no longer work: For any ld_preload rootkit, the best method of removal is by mounting the drive from a livecd and deleting it that way, due to the number of potential function hooks that could be embedded within the kit. This particular kit does not protect itself from symbolic links, and therefore can be easily removed. For ease of removal, you can run the following commands to remove Jynx2
References
LD_PRELOAD Jynx Rootkit strace log PCAP session