Встроенный бинарник на Linux
Продолжаю раскрывать интересную тему запуска программ через жопу нестандартными способами. В этот раз расскажу про запуск ELF-бинарника из скрипта и без записи в файловую систему.
Что тут происходит
Я уже создавал один универсальный скрипт запуска для четырех разных систем, но там в качестве основного тестового приложения использовалась Java.
В этот раз решил раскопать тему упаковки и запуска именно настоящего бинарника.
По мотивам вот этой статьи. Еще этой и вот этой.
Проект выложен вот тут целиком: https://github.com/alex0x08/linux-elf-inline
Все тесты проводились на 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 achar*
).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 likemalloc(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/<PID>/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’sopen()
, 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
Обратите внимание на `` кавычки — они означают запуск команды на исполнение, которая написана внутри таких кавычек.
| — стандартные пайпы, означает что результат вызова функции слева передается на вход функции справа.
В результате в переменной $bin должен образоваться наш бинарник в раскодированном виде.
Дальше мы его просто записываем через открытый выше дескриптор:
print $fh $bin;
exec {"/proc/$/fd/$fd"} "memfd";
The syntax for callingexec()
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