IoT - справжнісінький тренд останнього часу. Майже всюди в ньому використовується ядро Linux. Однак статей по вирусописательстве і шелл-КОДІНГ під цю платформу порівняно мало. Думаєш, писати шелл-код під Linux - тільки для обраних? Давай з'ясуємо як написати вірус для Linux!
БАЗА ДЛЯ НАПИСАННЯ ВІРУСУ ДЛЯ LINUX
Що потрібно для роботи?
Для компіляції шелл-коду нам знадобиться компілятор і лінковщік. Ми будемо використовувати nasm і ld. Для перевірки роботи шелл-коду ми напишемо невелику програму на С. Для її компіляції нам знадобиться gcc. Для деяких перевірок буде потрібен rasm2 (частина фреймворка radare2). Для написання допоміжних функцій ми будемо використовувати Python.
Що нового в x64?
Якщо говорити більш конкретно, то всі 32-бітові регістри загального призначення зберігаються, додаються їх розширені версії (rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp) і кілька нових регістрів загального призначення (r8, r9, r10, r11 , r12, r13, r14, r15).
З'являється нова угода про виклики (на відміну від архітектури x86, воно тільки одне). Згідно з ним, при виконанні функції кожен регістр використовується для певних цілей, а саме:
Syscall. Що? Як? Навіщо?
Syscall - це спосіб, за допомогою якого user-mode взаємодіє з ядром в Linux. Він використовується для різних завдань: операції введення-виведення, запис і читання файлів, відкриття і закриття програм, робота з пам'яттю і мережею і так далі. Для того щоб виконати syscall. необхідно:
• завантажити відповідний номер функції в регістр rax;
• завантажити вхідні параметри в інші регістри;
• викликати переривання під номером 0x80 (починаючи з версії ядра 2.6 це робиться через виклик syscall).
Номери потрібних syscall-функцій можна знайти, наприклад, тут.
Як видно, код push 0x00 скомпілюється в наступні байти 6a 00. Якби ми використовували такий код, наш шелл-код би не спрацював. Функція скопіювала б все, що знаходиться до байта зі значенням 0x00.
Ось начебто і все.
JUST DO IT!
Якщо ти дочитав до цього місця, то вже повинна скластися картина, як буде працювати наш шелл-код.
Насамперед необхідно підготувати параметри для функції execve () і потім правильно розташувати їх на стеку. Функція буде виглядати наступним чином:
Другий параметр є масивом argv []. Перший елемент цього масиву містить шлях до виконуваного файлу.
Третій параметр являє собою інформацію про оточення, нам він не потрібен, тому буде мати значення null.
Спочатку отримаємо нульовий байт. Ми не можемо використовувати структуру виду mov eax, 0x00, оскільки це призведе до появи null-байтів в коді, так що ми будемо використовувати наступну інструкцію:
Залишимо це значення в регістрі rdx - воно ще знадобиться як символ кінця рядка і значення третього параметра (яке буде null).
Для того щоб перевернути рядок і перевести її в hex. можна використовувати наступну функцію на Python:
Викличемо цю функцію для /bin/sh:>>>rev.rev_str("/bin/sh ")