Jak zabezpečit Ubnt verze 5.5.x a 5.6.x, které jsou děravé a napadnutelné virem motherfuckerem, moth3r či čímkoliv jiným díky zranitelnosti popsané v Exploit DB.
V čem spočívá problém?
Webový server používá php2 a nekontroluje přihlášení, když přijme soubor a rovnou jej zapíše kamkoliv do filesystému tak, jak je definováno v hlavičce http požadavku. Navíc v systému AirOS nejsou řešeny uživatelské role na úrovni filesystému, tudíž webserver běží s plnými právy a s přístupem kamkoliv.
Řešení je nahradit děravou verzi webserveru neděravou. Respektive, ve webserveru (lighttpd) chyba není. Chyba je v php2, ten je zkompilován v souboru /bin/cgi
. To jsem zjistil experimentálně. Neděravou verzi najdeme ve verzích firmware 5.6.3 a vyšší.
Postup řešení
- Najdu nezranitelnou binárku
/bin/cgi
(v ubnt fw 5.6.3 či vyšší). - Binárku musím dostat do starého ubnt. Pokud chci, aby byla dostupná i po rebootu, musím použít
/etc/persistent
, tam se však nevejde. V běhu ji tam nahrajete díky RAM (tmpfs), ale nezapíšete ji na flashku. Je moc velká. Můžeme ji však zkomprimovat, a pak se tam už vejde. - Zajistíme, aby se binárka po startu rozbalila, třeba do
/tmp
. - Pak je třeba upravit konfiguraci webserveru lighttpd, aby volal naši novou binárku pro cgi, ta je však v
/usr/etc/lighttpd/lighttpd.conf
, který není možné měnit (readonly filesystem), takže si jej zkopírujeme třeba do/tmp
a tam jej upravíme. - Upravíme také
/etc/lighttpd.conf
, aby neincludoval soubor z/usr/etc
, ale z/tmp
. - Zajistíme restart webserveru.
Výsledek? Máte zabezpečené zařízení!
Abyste postup nemuseli vymýšlet, můžete si rovnou stáhnout soubor shield.tgz (klidně si jej vytvořte dle postupu sami). V souboru jecgi
– binárka z fw 5.6.3 (je jedno, jestli XW nebo XM, jsou stejné). Také je tam „instalační a spouštěcí“ skript shield
.
Pro prvotní instalaci stačí nahrát shield.tgz
do /etc/persistent
a spustit.
tar -xzf shield.tgz shield ; ./shield
Co vlastně obsahuje soubor shield
? – Funguje na základě výše popsaného řešení, doplnil jsem jej o komentář, pro vyšší přehlednost.
#!/bin/sh per=/etc/persistent if [ -e $per/shield.tgz ] ; then #kontrola zda mam v rc.poststart co mam mit a pokud ne, tak to zapisu #tohle se bude dit jenom jednou grep "shield.tgz" $per/rc.poststart 2>/dev/null >/dev/null || \ echo "cd $per ; tar -xzf shield.tgz shield ; ./shield" >> $per/rc.poststart && cfgmtd -p /etc/ -w if [ ! -e /tmp/cgi ] ; then #nemam li novy cgi soubor ktery neni deravy, rozbalit si jej # zde muzete byt kreativni a pripadne si jej stahnout z webu, ale bylo by to po kazdem rebootu... cd /tmp #vyextraktuj cgi soubor tar -xzf $per/shield.tgz cgi fi #zkopiruj default konfigurak ktery nelze upravit, je readonly cp /usr/etc/lighttpd/lighttpd.conf /tmp/lighttpd.conf #uprav konfigurak v /tmp kteri pousti cgi aby pustil bezpecne cgi sed -i 's:/bin/cgi:/tmp/cgi:g' /tmp/lighttpd.conf #uprav konfigurak v /etc/ aby neincludoval /usr... ale /tmp... sed -i 's:/usr/etc/lighttpd/lighttpd.conf:/tmp/lighttpd.conf:g' /etc/lighttpd.conf #reloaduj lighttpd, tim ze ho sestrelis, ubnt si jej nahodi pkill lighttpd echo "web server zabezpecen" else echo "chyba: nemas nahrany shield.tgz v systemu" fi
Nedostatky?
Je možné, že novější binárka způsobí nějakou nefunkčnost ve webovém rozhraní pro určité funkce, ale při zběžné kontrole jsem na nic nenarazil.
Doufám, že toto řešení pomůže všem, kteří z různých důvodů nemohou či nechtějí upgradovat firmware na nejnovější.