LINUX.ORG.RU

Встроенный бинарник на Linux

 , ,

Встроенный бинарник на Linux

7

1

Это текстовая версия статьи, оригинал с картинками вот тут.

Продолжаю раскрывать интересную тему запуска программ нестандартными способами. В этот раз расскажу про запуск ELF-бинарника из скрипта и без записи в файловую систему.

Что тут происходит

Я уже создавал один универсальный скрипт запуска для четырех разных систем, но там в качестве основного тестового приложения использовалась Java. В этот раз решил раскопать тему упаковки и запуска именно настоящего бинарника Qt-приложения.

По мотивам вот этой статьи. Еще этой и вот этой.

Проект выложен вот тут целиком. Все тесты проводились на 64-битном Linux Manjaro с новым ядром 6.х.

Код скрипта:

#!/usr/bin/env bash

execute_elf_string(){
  local bin_encoded=$1
  perl -e '
    # Create memfd
    my $name = "";
    my $fd = syscall(319, $name, 1);
    if (-1 == $fd) { die "memfd_create: $!"; }
    # Copy binary
    open(my $fh, ">&=".$fd) or die "open: $!";
    my $bin = `echo "'"$bin_encoded"'" | base64 -d | gunzip`;
    print $fh $bin;
    # Execute
    exec {"/proc/$$/fd/$fd"} "memfd";
  '
}
execute_elf_string "
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
F6Y8q/e/7v8/T8zxfXB7AAA=
"

Большая строка это как раз закодированный и сжатый бинарник, тестовое приложение.

Тестовое приложение

В оригинале в закодированном виде было простое консольное приложение, без зависимостей и подключаемых библиотек. Я же решил зайти чуть дальше и сваял полноценное графическое приложение на Qt — для теста внешних зависимостей, естественно без статической сборки, чтобы этот цирк с понями максимально походил на реальное использование, со всеми реальными проблемами.

Вот так происходит упаковка:

#!/usr/bin/env bash

mkdir Release
cd Release
cmake -DCMAKE_BUILD_TYPE=Release ..
make
gzip -f testapp
cat testapp.gz |base64 > out.base64
cat ../head.sh > final.sh
echo \" >> final.sh
cat out.base64 >> final.sh
echo \" >> final.sh
chmod +x ./final.sh

Все достаточно банально, поэтому останавливаться на этом не будем и перейдем к самому веселому:

my $fd = syscall(319, $name, 1);

Вот где колдунство! И магии тут действительно много. Сейчас буду объяснять.

Проблема

Для начала обрисую проблему:

The exec(2) system call always requires a filename or absolute path (the filename is always a char*). posix_spawn also has similar requirements for a filename.

Вообщем бинарник должен быть в файле, а файл — в файловой системе. Поэтому типичный вариант запуска бинарника из строки это использование временного файла:

echo 'main(){}' | gcc -xc -o /tmp/a.out && chmod u+x /tmp/a.out && /tmp/a.out && rm -f /tmp/a.out

Это работает но не всегда удобно, поскольку можно попасть на read-only файловую систему или нехватку свободного места.

Волшебный memfd_create

В Linux есть syscalls — системные функции, которые программы вызывают когда нужно взаимодействовать с ресурсами ОС: устройствами, памятью или диском. И уже достаточно давно есть функция memfd_create. Вот что это такое на хорошем литературном английском:

This handy little system call is something like malloc(3), but instead of returning a pointer to a chunk of memory, it returns a file descriptor which refers to an anonymous (i.e. memory-only) file. This is only visible in the filesystem as a symlink in /proc//fd/ (e.g. /proc/10766/fd/3), which, as it turns out, execve(2) will happily use to execute an ELF binary.

Вообщем она позволяет создать анонимный файл в памяти, работать с которым (как с файлом) возможно только через специальную виртуальную файловую систему /proc.

В том числе поставить туда бит выполнения и запустить. Без записи на диск.

Возвращаемся к волшебной строчке:

my $fd = syscall(319, $name, 1);

319 — числовой номер системного вызова memfd_create для x86_64 архитектуры.

Определен он в /usr/include/bits/syscall.h через цепочку вложений как:

#define __NR_memfd_create 319

Perl и syscall

Конечно же нормальные люди вызывают системные функции из Си а не из скриптов. Но мне можно, поэтому я вызываю:

my $fd = syscall(319, $name, 1);    

Обожаю перл — каждую строчку можно разбирать неделями.

my $fd — объявление переменной fd и присвоение ей результата вызова системной функции, число.

$name — передача переменной c именем создаваемого файла, после вызова в этой переменной будет его имя, строка.

1 — константа MFD_CLOEXEC, определена в /usr/include/linux/memfd.h В результате успешного вызова в переменной $fd будет либо номер дескриптора созданного файла либо -1 в качестве ошибки вызова.

Проверка на ошибку:

 if (-1 == $fd) { die "memfd_create: $!"; }   

die — немедленный выход из программы, как вы наверное догадались.

Следующая магическая строчка:

open(my $fh, ">&=".$fd) or die "open: $!";    

Что тут происходит на литературном английском:

Perl’s open(), which is normally used to open files, can also be used to turn an already-open file descriptor into a file handle by specifying something like >&=X (where X is a file descriptor) instead of a file name.

Если по простому, то мы открываем дескриптор файла как обычный файл, например для того чтобы сделать в него запись:

print $fh "test";    

Но перед записью наш бинарник еще надо декодировать:

my $bin = `echo "'"$bin_encoded"'" | base64 -d | gunzip`;    

base64 -d  — раскодировать из формата Base64 gunzip — распаковать

Обратите внимание на `` кавычки — они означают запуск команды на исполнение, которая написана внутри таких кавычек.

| — стандартные пайпы, означает что результат вызова функции слева передается на вход функции справа.

В результате в переменной $bin должен образоваться наш бинарник в раскодированном виде.

Дальше мы его просто записываем через открытый выше дескриптор:

print $fh $bin;    

И наконец запускаем:

exec {"/proc/$$/fd/$fd"} "memfd";

Снова на красивом английском:

The syntax for calling exec() is a bit odd, and explained much better in the documentation. For now, we’ll take it on faith that the file is passed as a string in curly braces and there follows a comma-separated list of process arguments. We can use the variable $$ to get the pid of our own Perl process

В общем, запуск происходит через виртуальную файловую систему /proc, в вызов подставляется PID текущего процесса ($$) и номер дескриптора нашего виртуального файла.

Elfexec

Конечно же я не один такой умный, и есть готовые интересные решения, использующие такой же подход:

echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d | elfexec

Про одну такую штуку стоит упомянуть:

Utility to execute ELF binary directly from stdin pipe. It is useful to run binary via SSH without copy or install it on remote systems. Да да, бинарник через pipe, именно так.

Интересный вариант с компиляцией без временных файлов и последующим запуском:

echo '
#include <unistd.h>

int main(int argc, char* argv[])
{
    write(STDOUT_FILENO, "Hello!\n", 7);
    return 0;
}
' | cc -xc - -o /dev/stdout | elfexec

В общем, страшная штука.

★★★

Проверено: hobbit ()
Последнее исправление: hobbit (всего исправлений: 2)

Ответ на: комментарий от Werenter

Самое важное - отсутствие записи на диск, а значит про проблему read-only файловой системы и отсутствия места можно забыть.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Нет, вопрос скорее в том, зачем вообще так делать. Чем скрипт на перле с бинарником внутри лучше просто бинарника?

Werenter ★★★
()
Ответ на: комментарий от Werenter

Тем, что будет работать даже на файловой системе, смонтированной с noexec.

kmeaw ★★★
()
Ответ на: комментарий от Werenter

Это называется многоуровневая загрузка. Первый уровень - шелл-скрипт, из которого запускается Perl, из которого запускается уже бинарник, который например является инсталлятором для основного ПО.

Смысл - в контроле выполнения и гибкости: можно отобразить юзеру нормальную ошибку вместо ‘core dumped’, можно зашить несколько бинарников - для разных архитектур и окружений. Функция memfd_create есть также во FreeBSD, но сходу не получилось там запустить.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от Werenter

в большинстве линух обычно есть tmpfs-овский /run и иже с ним. обычно туда и льют времянку.
а тут для размещения используется другой принцип. даже просто как исследование возможностей весьма отлично :)

теперь осталось научиться сливать исполняемый бинарь через поток сразу в э-э-э-э интерпретатор ELF :)

pfg ★★★★★
()
Ответ на: комментарий от pfg

теперь осталось научиться сливать исполняемый бинарь через поток сразу в э-э-э-э интерпретатор ELF :)

так уже, в самом конце статьи.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от pfg

Так можно ведь вместо curl ... | sh делать curl ... | elfexec. За безопасность короче.

Werenter ★★★
()
Последнее исправление: Werenter (всего исправлений: 1)
Ответ на: комментарий от alex0x08

elfexec - это не интерпретатор ELF, как системный ld.so. Там внутри такой же трюк с memfd_create + execve({/proc/self/fd/$fd}) используется.

Было бы прикольно научиться честно парсить ELF на perl или python без дополнительных зависимостей. Тогда можно будет прикольные вещи делать, типа загрузки двух бинарей в одно общее адресное пространство для быстрых пайпов.

kmeaw ★★★
()
Ответ на: комментарий от kmeaw

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

Мьсе знает толк ;)

Как-то видел видео в интернете на котором мужик присунул дельфину, ни в какое сравнение с этой идеей не идет.

alex0x08 ★★★
() автор топика

А сами либы Qt должны быть установлены в системе?

При большом размере закодированного бинарника запуск будет ощутимо тормозить видимо?

rumgot ★★★★★
()
Ответ на: комментарий от rumgot

А сами либы Qt должны быть установлены в системе?

Для этого тестового бинарника - да, собственно я как раз и хотел проверить работу с системными библиотеками. В оригинальной статье был просто консольный бинарь без зависимостей.

При большом размере закодированного бинарника запуск будет ощутимо тормозить видимо?

Врядли, если только не гигабайт в base64 запихать. Ну и потом есть куда более оптимальные способы: можно например разделить на стадии запуска, сначала запускается мелкий бинарник, который подгружает остальное. Остальное можно запихать в zip-архив, который читается с конца файла и слепить его со стартовым скриптом.

alex0x08 ★★★
() автор топика

Червяка не зря нарисовал =) Ибо единственная цель которую как минимум я придумал это малвари и им подобное дабы без следов запускаться на noexec RO файловой системе, не очевидным для пользователя способом.

Как вариант защиты жёсткий prctl хук или нашлёпка firejail --seccomp.keep=memfd_create app только там не всё так гладко, ибо есть --seccomp.32 и фильтрация не так очевидна как может показаться. Собранное с gcc -m32 обходит фильтры seccomp ЕМНИП, но надо проверять.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Малварь на линуксах вообщем-то редкость. Да и смысл? Сейчас же везде контейнеры и виртуализация, сам по себе запуск без эскалации - мало полезен. Я все-таки исхожу из использования для инсталлятора.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Функция memfd_create есть также во FreeBSD, но сходу не получилось там запустить.

Потому что там нету proc по дефолту.

firkax ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Как вариант защиты жёсткий prctl хук или нашлёпка

Это не защита. Если у тебя в системе что-то постороннее уже запустилось, то взлом удался. Это из той же серии как прятать компилятор («а то злоумышленник сможет скомпилировать экплоит»).

firkax ★★★★★
()
Ответ на: комментарий от firkax

Нет и не включена по-умолчанию - сильно разные вещи.
И потом уже можно считать что есть, поскольку очень много софта ее требует. Java например та же.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

И потом уже можно считать что есть, поскольку очень много софта ее требует. Java например та же.

Теоретик или пользуешься freebsd? Нет, её там в подавляющем большинстве случаев нет. И джава прекрасно работает без неё. Может какие-то фичи с получением списка процессов не работают только, но это что-то узкоспециализированное.

А, ну и даже если ты смонтируешь proc - он отличается от линуксового, не помню в чём, но возможно и в работе с /fd/ в том числе.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Ну конечно же я теоретик, че там. Достаточно посмореть скрины в галерее и статьи чтобы это понять )

Ч0рным по белому пишут при установке JDK уже 20 лет, с момента появления джавы во FreeBSD:

This OpenJDK implementation requires fdescfs(5) mounted on /dev/fd and procfs(5) mounted on /proc.

Но нет, давайте забьем.

Вот тут можно поискать вхождения proc/self, proc/cpuinfo и так далее чтобы примерно прикинуть что может отвалиться если не слушать ментейнеров.

Из того что я знаю: джава получает собственный PID как раз из /proc/self, через свой pid делается по классике блокировка и проверка на повторный запуск.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

This OpenJDK implementation requires fdescfs(5) mounted on /dev/fd and procfs(5) mounted on /proc.

Эту надпись я тоже видел, поступил с ней именно так:

Но нет, давайте забьем.

Потому как не хочу засорять систему 20 лет назад депрекейтнутым хламом.

И, удивительно, на работе джавы это нигде никак не отразилось.

Из того что я знаю: джава получает собственный PID как раз из /proc/self

Ну нет, те джава-проги, которые я запускал, как-то узнают свой pid несмотря на отсутствие proc. Наверно, они используют сисколл getpid() для этого, как делают все нормальные люди.

через свой pid делается по классике блокировка и проверка на повторный запуск.

Странная у тебя классика. Для проверки на повторный запуск pid не нужен. А джаве не нужна эта проверка. она может быть нужна приложениям, в ней запущеным, на их усмотрение.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Потому как не хочу засорять систему 20 лет назад депрекейтнутым хламом.

Ну понятно, держи в курсе. Нормальным людям просто работать надо, поэтому вопрос ставится не про «засорение» а про необходимость. Если примера с джавой мало - ну например Google Chrome точно также требует /proc. Причем у хрома есть headless режим, который используется тулзами вроде Selenium, для симуляции действий пользователя на сайте - вполне себе серверное применение. .NET требует procfs, Linux Compat требует, хоть она и монтируется в /compat/proc

Странная у тебя классика.

При первом запуске программа сохраняет свой pid в файл на диске, при повторном - этот файл проверяет и считывает если есть. Дальше считанный pid ищется среди запущенных процессов, если он есть - приложение считается запущенным.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Ну, я всем этим не пользовался, только линуксулятором давно (и там другой proc, но не суть). А для джавы по факту не нужен.

Про pid ну да знаю такое, но это всё-таки не «блокировка через pid». pid там только для информации, а блокировка по-хорошему делается через flock(), можно и на пустом файле.

firkax ★★★★★
()
Ответ на: комментарий от firkax

а блокировка по-хорошему делается через flock(), можно и на пустом файле.

Увы но нет, «file lock» это ныне как раз теория, на практике стало слишком много сетевых файловых систем, NAS в каждом офисе и облачные хранилища.

«pid lock» тем и хорош что использует две атомарные операции: отдельно запись и отдельно чтение, поэтому все готово к сетевым сбоям в процессе работы.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Зачем хранить локфайл в облачном хранилище? Ему самое место в tmpfs.

«pid lock» тем и хорош что использует две атомарные операции: отдельно запись и отдельно чтение, поэтому все готово к сетевым сбоям в процессе работы.

И это очень плохо, нужно чтобы была одна атомарная операция «проверить занятость и захватить если не занято». Без flock это можно через просто создание файла с O_CREAT|O_EXCL, но такой способ страдает от упавшего демона, файл он при этом не удалит (и придётся делать всю эту возню со сравнением pid-ов, которая тоже уязвима в race condition в итоге, хотя и в маловероятном сценарии), а вот лок снимется сам.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 3)
Ответ на: комментарий от firkax

Зачем хранить локфайл в облачном хранилище? Ему самое место в tmpfs.

Самое частое явление: .lock файл по месту хранения данных. Так делают например H2 или Elasticsearch (да это опять джава, которая ‘нинужна’) Дальше база растет и переносится в NAS, на сетевой диск, ну и .lock файл оказывается на сетевой FS.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от gns

А что на это всякие apparmor c selinux скажут?

Разумеется вылезет «nag screen» поперек всего KDE с сообщением «подозрительное приложение, точно хотите запустить? да/нет/пожаловаться».

Что за удивительный вопрос для ЛОРа-то.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Да вот не всегда. Есть какие-то хитрые эльфы, которые всякие там digsig-и не видят. Он, вроде как, эльф, но хидеры в нем не все. Типа дигсигу сказано, что запускать только подписанные файлы, э этот сам себе эльф система без всякой подписи запускает. Мы в Астре на такое налетали, чем история кончилась, я не знаю.

gns ★★★★★
()
Ответ на: комментарий от gns

Этих syscall на самом деле два, в статье - для 64битного бинарника а отдельно еще есть для 32х битного. В перле есть специальная тулза h2ph для генерации специальной библиотеки syscall.ph, в которой номера syscall прописаны по-нормальному и откуда они по-идее должны браться. То что я реализовал на самом деле жесткая оптимизация. https://perldoc.perl.org/functions/syscall

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Да видел уже. Прогрепал сорцы ядра на тему memfd_create.

Не все так страшно, тупо файл в tmpfs. Можно еще man memfd_create почитать. А вот elfexec поинтересней будет.

gns ★★★★★
()
Ответ на: комментарий от alex0x08

Да не особо. Они рассказывают про типичный юзкейс с тем, что один процесс может поменять размеры разделяемой области памяти с фатальными последствиями для другого, вот и открывают файлы с помощью memfd_create, ставят на них печати и мапят на память. Одного пока не понимаю, mmap нужен для произвольного доступа, что бы lseek не звать, или еще для чего?

gns ★★★★★
()
Ответ на: комментарий от gns

Одного пока не понимаю, mmap нужен для произвольного доступа, что бы lseek не звать, или еще для чего?

Это вопрос для собеседования линуксового программиста чтоли?

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

Не, чисто поговорить. Я пока никого на работу не зову. :) Меня данный конкретный случай заинтересовал. Описан способ создания разделяемой памяти с гарантироанным размером. Ну хорошо. Запомним.

gns ★★★★★
()
Ответ на: комментарий от gns

Я пока никого на работу не зову.

Меня теперь только по контракту можно позвать, вместе с бригадой )

Описан способ создания разделяемой памяти с гарантироанным размером

Ну мне всегда подход из nginx нравился для такого:

#if (NGX_SETPROCTITLE_USES_ENV)

    /* allocate the spare 300 bytes for the new binary process title */

    env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
               "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
               "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
               "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
               "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

alex0x08 ★★★
() автор топика

В этот раз гораздо лучше. Осталось графоманию убрать, будет норм твит.

t184256 ★★★★★
()
Ответ на: комментарий от aol

Вы этими вашими пейлоадами как будто застряли в 90х, если честно.

Я тут сижу вырезаю обработку javascript-кода из apache configuration, который оказывается умеет сам по сети лазить будучи библиотекой, а вы про какие-то там пейлоады.

Даже сраный sl4j logback как оказалось содержит внутри себя полноценный сервер, стоило лишь чуть покопать.

Сейчас реверс-шелл из каждой дырки, телеметрия и автообновления у каждого калькулятора, а вы про штуки времен червя Морриса.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от alex0x08

ужс, ужс…..

// какой инфакрт жопы случится, если ты окунешься в какой-нить npm я вообще боюсь представить… (всё плохо, да :))

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 1)

Понимаю, для чего может пригодиться, но может ли пригодиться для чего-то законного? 😁

eugrus ★★★★★
()
Ответ на: комментарий от aol

Да я в курсе, оттуда и пошло все это поветрие.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от eugrus

Это в первую очередь комбинация из скрипта и бинарника.

Предназначение?

Какая-то универсальная тулза, инсталлятор - там где надо чтобы оно запускалось всегда и везде.

alex0x08 ★★★
() автор топика
Ответ на: комментарий от eugrus

А что есть версия Касперского под линукс да еще с перехватом запуска бинарников?

alex0x08 ★★★
() автор топика

Концовка классная. Из серии «я познаю мир».

BceM_IIpuBeT ★★☆☆☆
()
Ответ на: комментарий от eugrus

может ли пригодиться для чего-то законного?

Довольно странный сценарий, но иногда встречается в корпоративной среде - разработчик ходит на сервера и приносит с собой инструменты для настройки и отладки своего софта, например gRPC-клиента, который ходит в unix domain socket. Безопасники закрутили гайки - запретили ssh port forwarding, сделали /home и world-writable директории noexec, а рута не дают без сложных согласований. Правильным способом было бы пройти аудит и опакетить клиента, а потом раскатить его везде, но это слишком долго, а тикеты надо закрывать уже вчера.

kmeaw ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.