PL Emulacja Firmware dla zabawy i hajsu

6 minute read

PL Emulacja Firmware dla zabawy i hajsu

Zastanawiasz się może jak tu sobie pohakować IoT nie niszcząc domowego routera? A może szkolisz się z atakowania aplikacji webowych czy low level ale niewiesz czy psucie takiego fizycznego sprzętu jest dla Ciebie?

Jeśli czytasz dalej to w takim razie pozwól mi wykroić z Twojego życia kilka dni. No może nie kilka, maksymalnie dwa jak wszystko pójdzie dobrze (a pewnie nie pójdzie co z korzyścią zaowocuje upgrade’m Twojej wiedzy, mam taką szczerą nadzieję). Postaram się tchnąć w Ciebie taką małą nutę inspiracji do tych tematów albo wręcz skutecznie Cię do nich zniechęcić, zobaczymy jak to nam wyjdzie.

Pewnie kiedyś temat ten mógł obić Ci się o uszy - emulacja firmware, damned, to coś co wydaje się być karkołomną operacją. Wiele godzin spędzonych na bezsensownych próbach uruchomienia serwera HTTP, a już całego systemu routera to Panie zapomnij. Aha, jakby tego było mało to jeszcze oczywiście gdzieś ten assembler się czai bo tych błędów typu Buffer Overflow czy Heap (oprócz Weba) to trochę jest i jak to w ogóle można łapać. Fakt, nie jest łatwo ale od czegoś w końcu trzeba zacząć a Świat idzie do przodu, chociaż jakby tak spojrzeć na naszą branżę cybersec to on generalnie nie idzie a gna i co chwila powstają nowe narzędzia do różnych rzeczy. Tak samo jest i w tym przypadku.

Jest sobie taki framework o nazwie Emux. Emux jest jednym z kilku (w zasadzie jednym z dwóch sensownych obok Firmadyne) frameworków, o których wiem, służacych do emulacji firmware różnych urządzeń na architekturach RISCowych - tych najpopularniejszych takich jak ARM czy MIPS.

Emux jest fajny. Już po paru poleceniach możesz sobie odpalić (zemulować - tak to profesjonalnie brzi) cały system badanego routera! W pakiecie dostajesz także kilka narzędzi do debugu jak gdbserver itp (jeśli lubisz na grubo). Jest także tworzona “wirtualna sieć” i tylko w zasadzie odpalenie Burpa czy ZAPa dzieli Cię od wielogodzinnej zabawy.

Sandbox z Emuxem

Parę dni temu myślałem podobnie podczas uruchamiania Emuxa aż doszedłem do momentu, w którym coś nie działało. A nie działało coś kluczowego (brak połączenia z serwerem NFS z poziomu Qemu) i po godzinach szukania rozwiązania wpadłem na inny pomysł.

Postanowiłem wgłębić się jak ten framework działa i manualnie odtworzyć proces emulacji chociaż jednego z urządzeń (na chwilę obecną Emux ma możliwość emulacji kilku firmware różnych urządzeń). Postawiłem na firmware routera Tenda AC15 ponieważ działa on na ARMie i jako router spodobał mi się po prostu jego design.

Będziemy teraz przygotowywać system plików, z którego wystartujemy nasz firmware do badań. Zaczynamy z instalacją linuksa na VM. Ja wybrałem Debiana w wersji netinstal (sam system operacyjny z serwerem SSH). Instalujemy program socat oraz pobieramy projekt Emux:

Przygotowanie Hostfs

git clone --depth 1 --single-branch  https://github.com/therealsaumil/emux.git

Teraz z montujemy sobie nasz system plików z Emuxowego dla architektury ARM (Tenda AC15 działa właśnie na ARMie). Niech się dzieje wszystko z naszego domowego folderu /work!

mkdir ~/work ; cd ~/work

Tworzymy nowy system plików ext2, z którego będziemy korzystać:

dd if=/dev/zero of=~/new-hostfs-arm.ext2 bs=1M count=256
mkfs.ext2 ~/new-hostfs-arm.ext2

Super. Narazie go zostawimy w spokoju, teraz zajmiemy się systemem plików z Emuxa, który leży w katalogu /emux/files/emux/hostfs/hostfs-arm.ext2.bz2. Oczyścimy go ze zbędnych rzeczy i wszyskie pliki przeniesiemy do naszego nowopowstałego systemu plików - new-hostfs-arm.ext2. Montujemy starego do folderu hostfs-arm:

mkdir hostfs-arm
mount hostfs-arm.ext2 hostfs-arm/

a następnie robimy jak już wspominałem trochę czystek:

  • usuwamy plik /etc/init.d/S60emux - jest to skrypt, który montuje partycję z serwera NFS i uruchamia firmware (my zrobimy to inaczej)
  • usuwamy plik /etc/profile.d/emux.sh - jest to skrypt startowy uruchamiający się po podłączeniu do emulowanego firmware przez SSH

I teraz (działając cały czas w zamontowanym hostfs-arm/):

  • kopiujemy folder z repozytorium Emuxa /emux/files/emux/AC15 do folderu /emux
  • rozpakowujemy folder /emux/AC15/squashfs-root.tar.bz2 w to samo miejsce, z taką samą nazwą (/emux/AC15/squashfs-root)
  • kopiujemy folder /emux/AC15/preload do folderu /squashfs-root
  • tworzymy skrypt #1 i zapisujemygo go tutaj squashfs-root/root/init.sh
  • tworzymy skrypt #2 i zapisujemygo go tutaj squashfs-root/emux/AC15/squashfs-root/go.sh
#1

cd /emux/AC15/
./loadnvram nvram_AC15.ini
mount --bind /proc /emux/AC15/squashfs-root/proc
mount --bind /sys /emux/AC15/squashfs-root/sys
mount --bind /dev /emux/AC15/squashfs-root/dev
cd /emux/AC15/squashfs-root
chroot /emux/AC15/squashfs-root

Skrypt #1 ładuje pewne parametry do NVRAM oraz montuje wymagane foldery /proc, /sys oraz /dev. Na samym końcu następuje zmiana folderu głównego na folder z firmware urządzenia czyli “/”.

#2

export LD_PRELOAD="/preload/libnvram-armx.so:/preload/tenda_hooks.so"
/etc_ro/init.d/rcS;/bin/sh

Skrypt #2 ładuje odpowiednie biblioteki oraz startuje skrypt uruchomieniowy naszego firmware.

No to Git! Teraz pozostaje nam zamontować nasz nowy system plików a następnie przekopiwać cały wcześniej ogarnięty system plików do nowego i wymontować wszystko:

mkdir new-hostfs-arm
mount new-hostfs-arm.ext2 new-hostfs-arm/
cp -a ~/hostfs-arm/. new-hostfs-arm/
umount new-hostfs-arm
umount hostfs-arm

Uff, pierwszy akt za zami.

Qemu - pierwsze uruchomienie

W folderze /work w którym się zabunkrowaliśmy, będziemy potrzebowali Qemu do odpalenia naszego firmware. Zabieramy się do pracy:

cp ~/emux/files/emux/run/qemu-bin/qemu-system-arm-7.0.0 .

Teraz kopiujemy sobie folder z firmware routera do naszego folderu work/

cp -r ~/emux/files/emux/AC15/ .

Rozpakowujemy też pliki z flashem w folderze /AC15/flashmem/flash.tar.bz2. Musimy także skopiować do kernel (/emux/files/emux/template/kernel/zImage-2.6.39.4-vexpress) do folderu AC15/kernel/ ponieważ tam jest tylko dowiązanie symboliczne zamiast pliku. Mamy to.

Skrypt uruchomieniowy będzie wyglądał w ten sposób:

./qemu-system-arm-7.0.0 \
-M vexpress-a9 -m 256M -kernel ./AC15/kernel/zImage-2.6.39.4-vexpress \
-drive file=./hostfs-arm.ext2,if=sd,format=raw \
-drive file=./AC15/flashmem/flash0.bin,if=pflash \
-drive file=./AC15/flashmem/flash1.bin,if=pflash \
-append "pty.legacy_count=16 console=ttyAMA0 rw root=/dev/mmcblk0 rootwait rootfstype=ext2 mtdparts=armflash:0x1000000(All),0x40000@0(Bootloader),0xf70000@0x40000(KernelFS),0xda632c@0x209cd4(RootFS),0x10000@0xfb0000(crash),0x10000@0xfc0000(Policy),0x10000@0xfd0000(CFM_BACKUP),0x10000@0xfe0000(CFM),0x10000@0xff0000(nvram)  EMUX=AC15" \
-net nic,model=lan9118 -net tap,ifname=tap0,script=no,downscript=no \
-no-reboot -nographic -serial mon:stdio -monitor tcp:127.0.0.1:55555,server,nowait

Sprawdzamy czy ścieżki się zgadzają i zapisujemy sobie nasz skrypt pod nazwą run.sh. Musimy jeszcze stworzyć sobie mini-automat do tworzenia sieci pomiędzy naszym systemem a Qemu. Skrypt network.sh poniżej:

/usr/bin/chown root.hawk /dev/net/tun
/usr/bin/chmod g+rw /dev/net/tun
/usr/bin/tunctl -t tap0 -u hawk
/usr/sbin/ifconfig tap0 192.168.100.1 up
/usr/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/usr/sbin/iptables -I FORWARD 1 -i tap0 -j ACCEPT
/usr/sbin/iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
/usr/sbin/dnsmasq

PL Emulacja Firmware dla zabawy i hajsu

Cóż.. pozostaje nam poodpalać ten cały bałagan i przetestować go.

chmod +x network.sh ; sudo ./network.sh
chmod +x run.sh ; sudo ./run.sh

Powinniśmy dostać baner powitalny. Jako login wpisujemy root i jesteśmy już w głównym folderze systemu plików. Teraz uruchamiamy nasz skrypt #1.

chmod +x ./root/init.sh ; ./root/init.sh

PL Emulacja Firmware dla zabawy i hajsu

Dane powinny być dodane do NVRAM, foldery /proc, /sys oraz /dev zamontowane.

Zauważ, że jeszcze jesteśmy w podstawowym systemie plików dla architektury ARM. Firmware naszego routera znajduje się właśnie w katalogu /emux/AC15/squashfs-root i to właśnie tam przenosimy się chrootem, żeby wystartować skrypt uruchomieniowy i to teraz robimy:

chmod +x go.sh ./go.sh

PL Emulacja Firmware dla zabawy i hajsu PL Emulacja Firmware dla zabawy i hajsu

Pozostaje nam tylko uruchomić program socat (na VM Debianie), żeby transportował ruch pomiędzy Qemu - naszą wirtualką z debianem a naszym systemem operacyjnym lokalnie.

socat TCP-LISTEN:2080,fork,reuseaddr TCP:192.168.100.2:80 &

PL Emulacja Firmware dla zabawy i hajsu

Voila!

Wnioski

Proces ze swoją maszyną wirtualną, na której wszystko uruchamiamy można oczywiście pominąć - nic nie stoi na przeszkodzie abyś poustawiał sobie na swoim lokalnym systemie albo zmontować obraz dokera jak w Emux.

Faktem jest, że nie każdy FW da się emulować z powodzeniem za pomocą qemu. Urządzenia są bardzo różne i wymagają niekiedy dostępu do innych podzespołów, pamięci itp - jest to rzeczywiście problem.

Stworzenie środowiska do testów w taki sposób zamiast używania frameworków posiada moim zdaniem conajmniej dwie zalety:

  • poznajesz jak to wszystko działa. Być może kiedyś jeszcze będziesz potrzebował uruchomić firmware na jakiejś dzikiej architekturze bez możliwości korzystania z fizycznego urządzenia. Warto wiedzieć, że jest taka możliwość.

  • uczysz się. Jak sam widzisz, niektóre FW z powodzeniem da się uruchomić a co za tym idzie jest to dobry start i alternatywa do wejścia w świat IoT Security. Tyle na początek wystarczy

Mega Sekurak Hacking Party

PL Emulacja Firmware dla zabawy i hajsu

W czerwcu tego roku na Mega Sekurak Hacking Party będę miał przyjemność opowiadać o bardziej zaawansowanych podatnościach typu Os Command Execution kryjących się właśnie w podobnym urządzeniu do tego, które miliśmy dzisiaj okazję emulować, tyle, że na żywo.

Zachęcam Cię gorąco do uczestnictwa bo ciekawych tematów będzie naprawdę sporo!

Na mojej prelekcji będzie gdzieś ukryty taki EasterEgg ;) Jeśli go złapiesz i napiszesz do mnie - dostaniesz taką finalnie zmontowaną wirtualną maszynę jak ta, którą składaliśmy powyżej z informacją gdzie leży Twój pierwszy Os Command Injection :)

PS. Do końca maja z kodem: mshp-mw-30 macie zniżkę 30% na bilety standard.

Mam nadzięję do zobaczenia!