Egy törés anatómiája

Ha ezt a múltbeli linket szeretted, akkor a most következő post neked tetszeni fog.
Tegnap délután érdekes anomáliára lettem figyelmes az egyik szerveremen. Azt vettem észre, hogy megjelent egy általam ismeretlen “dead” nevű ELF bináris a /tmp könyvtáramban, a www-data user jogosultságaival. Az ilyesmit betörésnek hívjuk, és amellett, hogy bűntény, izgalmas ujjgyakorlatra ad lehetőséget: keressük meg, hogy ki, honnan és hogyan valósította meg a dolgot, vadásszuk le a gonosz boszorkát. Megkerestük, levadásztuk.

Első körben eltüntettem a binárist a /tmp-ből. Nem letöröltem, később még szükség lesz rá. A /tmp könyvtáron ott van a “noexec” paraméter mindenkinél, ugye? Ez felelős azért, hogy ne futhasson onnan semmi.
Az első dolgom az volt, hogy megtaláljam a rést a pajzson: hogy került hozzám fel ez a bináris. Mivel a tulajdonos a www-data, vagyis a webszerver volt, megnéztem a neten, hogy jött-e ki Apache távoli sebezhetőség, amióta offline játszottam a GTA-val. Ez kb. egy napnyi idő, és a válasz nem.
Az ember legjobb barátja ilyenkor a log, megnéztem hát az Apache általános error logját, és a következő érdekes bejegyzést találtam:

[Sun Jul 10 06:27:13 2005] [notice] Accept mutex: sysvsem (Default: sysvsem)
–12:52:24– http://www.gennadouglass.com/
=> `index.html’
Resolving www.gennadouglass.com… 65.57.241.122
Connecting to www.gennadouglass.com[65.57.241.122]:80… connected.
HTTP request sent, awaiting response… 200 OK
Length: 30,679 [text/html]

0K ………. ………. ……… 100% 24.62 KB/s

12:52:26 (24.62 KB/s) – `index.html’ saved [30679/30679]

Ez bizony elég csúnyán néz ki: valaki szemmel láthatóan wget-et használt, hogy letöltse a binárist a gépemre. A méret azonos, a név nem, de ez már elegendő bizonyíték, hogy ez az, amit keresek. Ki a fene használ normál körülmények között wget-et Apache-ból, nem igaz?
Ekkor egyből eszembe jutott a közelmúltban felfedezett PEAR XML_RPC sebezhetőség, ami lehetőséget ad távoli parancsok futtatására. Ugyan én frissítettem az XML_RPC-met 1.3.2-re, de az egyik kliensem Drupal engine-t használ, és a jelek szerint az független, saját xmlrpc-t használ, gondoltam. Meg is néztem az illető ügyfél webszerver logját arról az időről, amikor a fenti Apache log entry keletkezett, vagyis 12:52:26 körülről. Ezt találtam:

0-1pool17-223.nas6.houston4.tx.us.da.qwest.net – – [10/Jul/2005:12:52:18 +0200] “POST /xmlrpc.php HTTP/1.1” 200 255 “-” “Internet Explorer 6.0” “-“
0-1pool17-223.nas6.houston4.tx.us.da.qwest.net – – [10/Jul/2005:12:52:26 +0200] “POST /xmlrpc.php HTTP/1.1” 200 201 “-” “Internet Explorer 6.0” “-“
0-1pool17-223.nas6.houston4.tx.us.da.qwest.net – – [10/Jul/2005:12:52:33 +0200] “POST /xmlrpc.php HTTP/1.1” 200 201 “-” “Internet Explorer 6.0” “-“
0-1pool17-223.nas6.houston4.tx.us.da.qwest.net – – [10/Jul/2005:12:52:36 +0200] “POST /xmlrpc.php HTTP/1.1” 200 201 “-” “Internet Explorer 6.0” “-“

Ez bizony elég randa, íme a támadó IP-címe, a négy POST parancs, amivel feltöltötték (illetve letöltötték) a bűnös programot a gépre. (Internet Explorerrel, pf, script kiddie.)
Ezen a ponton történt az, hogy az ügyfél web root-jából eltávolítottam az xmlrpc.php file-t, amit kihasználtak, az ügyfelet persze értesítve erről, és tömören az okról is. Először történt ilyen, hogy ennyire drasztikus voltam.
Ezután következhetett a file megvizsgálása, mire is jó ez, ha már megkaptam ajándékba.
A file-t megnézve egyből látszott ugyebár, hogy ELF bináris, valamint még pár dolog, amit most megszűrve idecopyzok (még így is baromi hosszú lesz):

[email protected]:~$ strings dead
blackout.int0x.us
NOTICE %s :Unable to comply.
/usr/dict/words
%s : USERID : UNIX : %s
NOTICE %s :GET <host> <save as>
NOTICE %s :Unable to create socket.
NOTICE %s :Unable to resolve address.
NOTICE %s :Unable to connect to http.
GET /%s HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.2.16-3 i686)
Host: %s:80
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
NOTICE %s :Receiving file.
NOTICE %s :Saved as %s
NOTICE %s :Spoofs: %d.%d.%d.%d
NOTICE %s :Spoofs: %d.%d.%d.%d – %d.%d.%d.%d
NOTICE %s :Kaiten wa goraku
NOTICE %s :NICK <nick>
NOTICE %s :Nick cannot be larger than 9 characters.
NICK %s
NOTICE %s :DISABLE
Disabled
Enabled and awaiting orders
NOTICE %s :Current status is: %s.
NOTICE %s :Already disabled.
NOTICE %s :Password too long! > 254
NOTICE %s :Disable sucessful.
NOTICE %s :ENABLE <pass>
NOTICE %s :Already enabled.
NOTICE %s :Wrong password
NOTICE %s :Password correct.
NOTICE %s :Removed all spoofs
NOTICE %s :What kind of subnet address is that? Do something like: 169.40
NOTICE %s :Unable to resolve %s
NOTICE %s :UDP <target> <port> <secs>
NOTICE %s :Packeting %s.
NOTICE %s :PAN <target> <port> <secs>
NOTICE %s :Panning %s.
NOTICE %s :TSUNAMI <target> <secs>
NOTICE %s :Tsunami heading for %s.
NOTICE %s :UNKNOWN <target> <secs>
NOTICE %s :Unknowning %s.
NOTICE %s :MOVE <server>
NOTICE %s :TSUNAMI <target> <secs> = Special packeter that wont be blocked by most firewalls
NOTICE %s :PAN <target> <port> <secs> = An advanced syn flooder that will kill most network drivers
NOTICE %s :UDP <target> <port> <secs> = A udp flooder
NOTICE %s :UNKNOWN <target> <secs> = Another non-spoof udp flooder
NOTICE %s :NICK <nick> = Changes the nick of the client
NOTICE %s :SERVER <server> = Changes servers
NOTICE %s :GETSPOOFS = Gets the current spoofing
NOTICE %s :SPOOFS <subnet> = Changes spoofing to a subnet
NOTICE %s :DISABLE = Disables all packeting from this client
NOTICE %s :ENABLE = Enables all packeting from this client
NOTICE %s :KILL = Kills the client
NOTICE %s :GET <http address> <save as> = Downloads a file off the web and saves it onto the hd
NOTICE %s :VERSION = Requests version of client
NOTICE %s :KILLALL = Kills all current packeting
NOTICE %s :HELP = Displays this
NOTICE %s :IRC <command> = Sends this command to the server
NOTICE %s :SH <command> = Executes a command
NOTICE %s :Killing pid %d.

És még sok minden más. Ami ebből látszik, az a következő:
1. Ez egy DDOS támadásokhoz tartozó zombie program, aminek távolról lehet valahogy parancsokat adni, és különböző syn flood attackokat végez. Huncut.
2. Érdekes lehet a következő string: “blackout.int0x.us”.
3. Meg ez is: “#t0x1c”.

Kb. ezen a ponton csatlakozott be Frank és Blint a munkába, ezért mostantól többes számban beszélek.
Kicsit megakadtunk, hogy akkor most pontosan mit és hogy csinál a program, amíg ellenőrzött körülmények között el nem indítottam, és észre nem vettem, hogy bár látszólag nem fut le, valójában a háttérben indít egy processzt, ami pedig egy IRC szerverhez csatlakozik:

Majd egy netstat, és ami minket érdekel belőle:

sh-2.05b# netstat -atpn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.1.69:34617 65.57.241.122:6667 ESTABLISHED4613/-bash

tcp 0 0 192.168.1.69:34331 65.57.241.122:6667 ESTABLISHED4334/irssi-text

Megvolt tehát az IRC szerver címe, ami egyébként egyezik a http címmel, ahonnan az eredeti bináris jött: www.gennadouglass.com, illetve 65.57.241.122. Kis intuícióval megspórólhattam volna ezt a kört.
Az inkriminált processzt persze kilőttem azonnal, és be is léptünk a bűnös IRC-szerverre, ahol kb. 20 zombie várt parancsra.
Itt megint megakadtunk: mi a szintaxisa a programnak? A paraméterek/opciók megvoltak (lásd feljebb a kilistázott stringeket), de hogy adjuk meg őket, hogy a program el is fogadja? A választ Frank szemfülessége hozta: említettem az előbb a gyanús stringeket, na ő talált még egyet: vajon mi lehet ez: “NOTICE %s :Kaiten wa goraku”. Beütöttük hát a Google-ba a “Kaiten wa goraku” stringet, és láss csodát, az első találaton (szeretünk Google!):
http://packetstormsecurity.nl/irc/kaiten.c:

“This is a IRC based distributed denial of service client. It connects to the server specified below and accepts commands via the channel specified. The syntax is: !<nick> <command>”

Itt volt hát, a teljes forrása a kis zombie programunknak, szintaktikával, mindennel együtt. Érdekes megfigyelni, hogy a program írója gondolt a kevésbé tehetséges script kiddie-kre is, és kedvesen megjelölte, hogy hol kell beparaméterezni a forrást fordítás előtt, “EDIT THESE”, és “STOP HERE!” stringekkel. Jó, hogy grafikus telepítőt nem gyártott hozzá. Mivel a packetstormsecurity.nl teljesen más host, mint a mi kis IRC csatornánk, okkal feltételezhetjük, hogy a mi script kiddie-jeink tényleg azok: tehetségtelen pöcsök, akik arra is képtelenek, hogy rendesen levédjék az IRC csatornájukat, vagy hogy átírják a bejelentkező stringet a forrásban.

Merre tovább? Én részemről letiltottam az adott szerveren tűzfal szinten a script kiddie-k IP-jét. Írtam emailt az IP tulajdonosának (Spiderhost, Inc.), hogy az egyik általuk hostolt IP-n erősen illegális tevékenység folyik.
További tervek: kihasználva a programban levő távoli parancsfuttató lehetőséget, tervezzük, hogy az összes fertőzött hostra tolunk egy broadcast-, vagy logüzenetet sok felkiáltójellel, hogy “your host is infected, disinfect, do this and that”, tömören kifejtve persze, hogy mi a teendő. Az is felmerült bennünk, hogy a programban levő “védhetetlen” syn flood attackot felhasználjuk az IRC szerver ellen, de ez még megfontolás tárgya, hiszen az már szintén bűncselekmény, önbíráskodás, meg még nem tudom mi lenne. Egyelőre annyi történik, hogy logoljuk a csatorna forgalmát; tegnap dél körül ébredt fel a kis okoskánk, ha ma is ugyanezt teszi, akkor be fog jelentkezni a kis csatornájára, ahol meg fog lepődni a forgalom láttán, nekünk pedig már több IP lesz a birtokunkban: egy dinamikus, ahonnan tegnap feltöltötte nekem a binárist, egy, ahonnan majd bejelentkezik, és hát magának a szervernek az IP-je. Ezzel a három adattal már van mit kezdenie pl. az FBI-nak, ha esetleg (mert ez is esélyes) elküldjük nekik a vonatkozó logokat, stb. Attól függően, hogy mennyire mennek utána egy ilyen esetnek, az USA-ban elég könnyű elkapni ezek alapján valakit, aki nem eléggé elővigyázatos (és van okunk feltételezni, hogy a mi embereink nem azok). Ha még (Blint ötlete alapján) azt is elhintem az FBI-nak, hogy a core routeremet gyilkolták le a srácok, akkor az USA törvényei szerint ez már terrorista cselekménynek fog minősülni, amiért, ha jól sejtem, statárius bírósági döntés alapján pöcsletépés-szintű büntetés jár.

Mi megtesszük, ami tőlünk telik.

Update: Secret, a #t0x1c topik op-ja megjelent a színen, kb. pont akkor, mint tegnap. A társalgás folyik, egyelőre a másra mutogatásnál tartunk.

Update 2: Megtörtént az IRC-s chat session, vegyes eredményekkel. Összefoglalva: Secret (operátor 1) egy 17 éves srác, aki hullámzó teljesítményt mutatott: kezdetben eléggé meg volt ijedve a jelek szerint, aztán megjött a hangja és fenyegetőzött. Később megjött a haverja, icenix, aki egyből a fenyegetőzésre tért, de hogy akármelyikük tud-e valamit azon kívül, hogy sebezhetőségeket kihasznál proof-of-concept kóddal, az nem derült ki.

IRC log Secret-tel.
IRC log négyesben Frankkel és Icenix-szel.

Update 3: Mint látható, viszonylag passzívak voltunk a chat közben. Próbáltuk kiugrasztani a nyulat a bokorból, hogy pontosan mennyire jók ezek a srácok, de a legtöbb, amit tettek, az a fenyegetőzés volt, illetve néhány fake adattal berémiszteni próbálás, valamint a már kijavított xmlrpc bug felemlegetése. Ebből azt a következtetést vontuk le, hogy tényleg script kiddie-kről van szó, de azért nem bízzuk el magunkat. A srácok szerverének IP-je kitiltva, figyeljük a logokat – ennél többet nem tehetünk.

Update 4: A srácok közben IP-t váltottak, valamint elrejtették a csatornátjukat. A délután folyamán ezen kívül nem láttam aktivitást tőlük. Azt jegyezném meg továbbá, hogy ahogy elnézem, ez a Fallen nevű arc sem vigyáz magára túlzottan. A jelek szerint ő lehetett az, aki engem megtört, és most ugyanúgy QWest-es dinamikus IP-ről csatlakozik. Az sem túl megfontolt dolog, hogy van egy hálózatod, amit tudod, hogy megtalált két arc (ezek volnánk mi), de nem véded le éjszakára. Szemmel láthatóan mindenki alszik, most azon gondolkodom, hogy csináljak-e valami gonoszat (mondjuk a tervezett logos megoldást), vagy menjek inkább aludni.
A jelenlegi (2005-07-12 01:19) /WHO kimenet:

01:18 -!- #t0x1c int0x[t] H 0 [email protected] [JFCCPCYH]
01:18 -!- #t0x1c int0x[dd] H 0 [email protected] [WTMP]
01:18 -!- #t0x1c int0x[ss] H 0 [email protected] [EGNPAKW]
01:18 -!- #t0x1c int0x[gb] H 0 [email protected] [GDBDSXST]
01:18 -!- #t0x1c int0x[e0] H 0 [email protected] [JKCSN]
01:18 -!- #t0x1c int0x[o] H 0 [email protected] [HVOIBBJ]
01:18 -!- #t0x1c int0x[n] H 0 [email protected] [PGFU]
01:18 -!- #t0x1c int0x[r0] H 0 [email protected] [IGMQ]
01:18 -!- #t0x1c int0x[oo] H 0 [email protected] [LWFE]
01:18 -!- #t0x1c Fallen H* 0 [email protected]
[Dead Inside]
01:18 -!- #t0x1c int0x[tt] H 0 [email protected] [CSJYSRC]
01:18 -!- #t0x1c int0x[j] H 0 [email protected] [QMBGQNKV]
01:18 -!- #t0x1c int0x[a] H 0 [email protected] [DBFY]
01:18 -!- #t0x1c int0x[gg] H+ 0 [email protected] [PQAYZMFE]
01:18 -!- #t0x1c int0x[nn] H+ 0 [email protected] [WUYFH]
01:18 -!- #t0x1c int0x[2d] H+ 0 [email protected] [ZPMGFCM]
01:18 -!- #t0x1c int0x[pn] H+ 0 [email protected] [FPUWHC]
01:18 -!- #t0x1c int0x[qq] H+ 0 [email protected] [VLBLORB]
01:18 -!- #t0x1c int0x[k] H+ 0 [email protected] [XYGRDDJ]
01:18 -!- #t0x1c int0x[y] H+ 0 [email protected] [PANI]
01:18 -!- #t0x1c int0x[ww] H+ 0 [email protected] [PEKJB]
01:18 -!- End of /WHO list

Figyeljük meg Fallen mozgását.