pl  |  en

SuperAdminka i śledztwo w logach

Była 20:29, gdy nacisnęłam kombinację klawiszy esc :x p e y wysyłając ostatniego maila. Wstałam od biurka, piłka na której siedziałam potoczyła się pod biurko Maćka. W tym momencie rozległ się dzwięk telefonu alarmowego. Spokojna, kojąca melodia. Oho!

- Dobry wieczór MegiTeam, Zarych, Magda Zarych, w czym mogę pomóc?
- Pani Magdo, pomocy, strony mi nie działają. Ktoś nadpisał pliki php doklejając do nich jakiś kod.
- Rozumiem. Czy ma Pan może WordPressa na koncie?
- Mam, ale aktualizuję go regularnie.
- Dobrze, że dba Pan o aktualizacje WordPressa, ale być może jakaś wtyczka jest dziurawa. Czy może mi Pan podesłać mailem ścieżkę do przykładowego zmodyfikowanego pliku? Po datach modyfikacji często da się prześledzić w logach w jaki sposób plik został nadpisany.
- Pani Magdo, niestety wszystkie pliki mają stare daty modyfikacji 🙁
- Panie Kliencie, takie zagadki to jest coś, co lubię najbardziej - czekam na maila!

Odłożyłam telefon i podeszłam do biurowej szafy. Zdecydowanym ruchem odsunęłam drzwi. Mój kostium SuperAdminki wisiał tak, jak go ostatnio zostawiłam. Nie sądziłam, że jeszcze dzisiaj mi się przyda. Szybko wbiłam się w niego i zapięłam pelerynkę. Hmm trochę ciasnawy – znowu skurczył się w praniu.

Wykopałam piłkę spod biurka kolegi i usiadłam przy swoim netbuczku. Z niecierpliwością czekałam na maila, zabijając czas liczeniem okruszków na klawiaturze. Szanujący się admin przesypuje okruszki ze starej do nowej przy zmianie klawiatury. Moja kolekcja byłaby większa, gdyby serwis Słoneczko.net mi jej nie wyczyścił. A może raczej nie podebrał?

<Ding, dong!>

Jest!

From: Klient@BKAC
To: SuperAdminka@MegiTeam

W nawiązaniu do rozmowy telefonicznej przesyłam 
/ścieżkę/do/pliku.php

VPS jaś, konto małgosia

z poważaniem
Klient

Niecierpliwość przeszła w pełne skupienie – przede mną jedno zadanie: seek and destroy. Zalogowałam się na serwer klienta, ręce same ułożyły się do odpowiednich komend.

$ ls -l /ścieżka/do/pliku.php
-rw-rw-r-- 1 małgosia małgosia 145722 2013-04-19 14:07 /ścieżka/do/pliku.php

Stara data może zmylić mniej wprawne oko ale nie spatchowane oczy SuperAdminki.

$ stat /ścieżka/do/pliku.php

  File: `/ścieżka/do/pliku.php'
  Size: 145722    	Blocks: 304        IO Block: 4096   regular file
Device: 14h/20d	Inode: 15206483    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/    małgosia)   Gid: ( 1000/    małgosia)
Access: 2013-06-04 20:40:45.668939603 +0200
Modify: 2013-04-19 14:07:32.232343460 +0200
Change: 2012-06-04 18:50:32.232343460 +0200

Ha! Data modyfikacji i-węzła: dzisiaj, 18:50 – wygląda obiecująco. W i-węźle trzymane są informację o pliku (uprawnienia, nazwa i takie tam) i datę modyfikacji można łatwo zmanipulować, ale kto by sobie tym zawracał głowę.

Dobra, to chyba wiem już kiedy, kolejne pytanie to „jak?”.

Do plików na koncie można się dostać przez ssh, sftp, ftp lub… www. Ostatnia opcja nie zamierzona, ale niestety częsta. Obecność na koncie popularnego, otwartego, darmowego oprogramowania kazała mi zacząć od logów serwera WWW. Interesowały mnie wywołania POST, bo one mogą zmienić zawartość plików.

$ grep POST /var/nginx/logs/*/access.log |less

Dużo… ;/

$ grep POST /var/nginx/logs/*/access.log |grep 18:50

Pusto… ;/

To może poszukam wywołań z 18:4x? – zderzenie dwóch komórek mózgowych zaowocowało myślą – Żądanie zapisywane jest z datą odebrania a nie zakończenia. Jeżeli wykonywało się długo, a zmodyfikowany plik jest jednym z wielu, to musiało zacząć się wcześniej.

Rzuciłam okiem na format daty:

04/Jun/2013:20:30:00

$ grep POST /var/nginx/logs/*/access.log | grep 2013:18:4 |less

Już lepiej – tylko 108 wyników. Jakieś crony, formularz kontaktowy, panel admina… O, a to co?

/var/nginx/logs/a3dg6fg/access.log:87.117.228.259 - - [04/Jun/2013:18:48:17 +0200] "POST /wp-content/plugins/index.php?cookie=1 HTTP/1.1" 499 0 "-" "Mozilla/5.0 (Windows)" 344 "blogokotkach.pl" "119.991"

Kobieca intuicja podpowiedziała mi, że to jest to czego szukam. Sprawdziłam whoisem IP – rapidswatch.com, jakiś hosting w świecie szerokim – co oni mieliby tu POSTować? Kolejną wskazówką był czas obsługi żądania (ostatnia kolumna) oraz kod HTTP. 499 oznacza, że połączenie zostało przerwane przez klienta przed otrzymaniem odpowiedzi. Jeżeli żądanie wykonywało się ponad 2 min. i nie zakończyło to znaczy, że miało wiele do zrobienia.

Przeszłam do katalogu serwisu blogokotkach.pl i zajrzałam do pliku wp-content/plugins/index.php… Zajrzałam jeszcze raz… Im bardziej zaglądałam, tym bardziej było tam coś, czego się nie spodziewałam.

Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
We feel the room swayin'
While the band's playin'
One of your old favourite songs from way back when
So, take her wrap, fellas
Find her an empty lap, fellas
Dolly'll never go away again
Hello, Dolly
Well, hello, Dolly
(...)

Google oświeciło mnie, że faktycznie jest taki plugin do WordPressa. No cóż, dzień w którym nie dowiem się czegoś nowego to dzień stracony. Po co jednak ktoś miałby wysyłać jakieś dane do skryptu, którego zadaniem jest wyświetlanie losowych cytatów ze zdefiniowanego tekstu piosenki? Wczytałam się w kod…

From: SuperAdminka@MegiTeam
To: Klient@BKAC

Panie Kliencie, wiem już w jaki sposób zostały podmienione pliki php na koncie małgosia! W pliku ~/blogokotkach.pl/wp-content/plugins/index.php jest kod, który udaje plugin 'Hello Dolly' a w rzeczywistości jest backdoorem. Zablokowałam go. Wgrywam backup na Pana konto a w międzyczasie sprawdzę w jaki sposób ten index.php pojawił się na koncie.

Pozdrawiam
Ja
From: Klient@BKAC
To: SuperAdminka@MegiTeam

Kocham Panią, Pani Magdo. Czy zostanie Pani moją żoną?

No dobra, wcale tak nie było (ale mogło, c’nie?).

Zajęłam się przywracaniem backupu – to ta nudniejsza część, ale czasem trzeba też popracować. Wrzuciłam dane na konto tworząc nową strukturę katalogów. Poprosiłam klienta, by przepiął w naszym panelu domeny na nowe foldery, ale nie usuwał jeszcze skompromitowanych plików – mogą się przydać do dalszej diagnostyki. Znów mogłam zająć się grzebaniem po logach.

Jakby tu znaleźć początek tego włamu? Gdzie jest podatność?

Mogłam znów porównać logi z datą modyfikacji pliku (tym razem ~/blogokotkach.pl/wp-content/plugins/index.php), ale z głupia frant poszukałam wcześniejszych wywołań „POST /wp-content/plugins/index.php?cookie=1”

$ zgrep "POST /wp-content/plugins/index.php?cookie=1" /var/nginx/logs/a3dg6fg/access.log-*

/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:28:16 +0200] "POST /wp-content/plugins/index.php?cookie=1 HTTP/1.1" 200 185 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 183 "blogokotkach.pl" 3135 "blogokotkach.pl" "0.069"

No cóż, punktów za styl nie dostanę, ale działałam w afekcie i stanie wyższej konieczności więc (z)grep po wszystkich skompresowanych logach aplikacji musi mi zostać wybaczony. Ważne, że znalazłam – pierwsze wywołanie 4 kwietnia z IP 89.233.216.259. Ciekawe co jeszcze przyszło z tego adresu.

$ zgrep 89.233.216.259 /var/nginx/logs/a3dg6fg/access.log-20130405.gz

/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:39 +0200] "GET /wp-login.php HTTP/1.1" 200 2736 "-" "Opera/9.80 (Windows NT 5.1; U
; en) Presto/2.2.15 Version/10.10" 183 "blogokotkach.pl" "0.585"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:40 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 339 "blogokotkach.pl" "0.403"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:40 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 343 "blogokotkach.pl" "0.322"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:41 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 358 "blogokotkach.pl" "0.353"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:41 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 340 "blogokotkach.pl" "0.313"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:45 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; 
U; en) Presto/2.2.15 Version/10.10" 346 "blogokotkach.pl" "0.345"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:45 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 342 "blogokotkach.pl" "0.321"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:46 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 346 "blogokotkach.pl" "0.314"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:24:46 +0200] "POST /wp-login.php HTTP/1.0" 200 3667 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 361 "blogokotkach.pl" "0.335"
(...)
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:25:34 +0200] "POST /wp-login.php HTTP/1.0" 302 889 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 440 "blogokotkach.pl" "0.671"
/var/nginx/logs/a3dg6fg/access.log-20130405.gz:89.233.216.259 - - [04/Apr/2013:05:26:43 +0200] "POST /wp-admin/plugin-editor.php?file=index.php HTTP/1.0" 200 27663 "-" "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10" 675 "blogokotkach.pl" "3.269"

Tym razem żaden błąd w kodzie a zwykły atak na hasło. I to całkiem szybki, bo po ok. 4 minutach plik index.php został zmodyfikowany z poziomu panelu admina. To będzie długa noc dla klienta.

From: SuperAdminka@MegiTeam
To: Klient@BKAC

Niestety, atakujący metodą prób i błędów zgadł Pana hasło i dostał się do panelu admina bloga. Stało się to równo 2 miesiące wcześniej. Nie wiadomo, co od tego czasu wgrał na Pana konto więc jedynym sensownym rozwiązaniem jest postawienie od nowa ze świeżych źródeł wszystkich serwisów, które ma Pan na tym koncie. 

Proszę też od razu zmienić hasło do panelu admina i postarać się używać mocnych haseł. Dobre hasło to trudne do zgadnięcia i łatwe do zapamiętania. Może Pan je stworzyć przez zamianę w jakimś słowie małych liter na duże, na cyfry, dodać znaki specjalne. Na przykład tak

correct horse battery staple

😉

Rozwiązałam problem, pomogłam klientowi a na koniec jeszcze się pomądrzyłam – wieczór uważam za udany, czas do domu. Odwiesiłam kostium SuperAdminki, spakowałam laptopa do torby i udałam się w kierunku zachodzącego słońca, myśląc o nowym „ficzerze” inspirowanym dzisiejszym wydarzeniem.

THE END

PS. W następnym odcinku SuperAdminki dowiesz się, że nie tylko aplikacje PHP są dziurawe i nauczysz się używać strace’a. Stay tuned. 

PS2. Jakiego klienta poczty używam i co robi skrót klawiszowy esc :x p e y? Znasz odpowiedź? Wpisz ją w komentarzu!

 

  • Łukasz Proszek

    Łezka się w oku kręci. Mutt.

  • Arsen7

    Wyjście z vim do mutt, szyfrowanie, wysłanie. Szkoda, że już jestem żonaty 😉

  • mequation

    Przyjemnie się czytało, mam nadzieję że pojawią się więcej niż 2 odcinki z serii.

    BTW – Przy logach jak już jest word-wrap włączony to można by 1 liniowe odstępy dorzucić między kolejnymi wpisami, ewenualnie „pogrubić” istotną część loga by czytelnik mógł sprawniej je prześledzić 🙂

    • magdazarych

      Masz rację, dzięki. Wytłuściłam to, co według mnie jest istotne w logach i wynikach poleceń.

  • Grzegorz Głąb

    w kolejnym odcinku być może dodatkowo dowiemy się, że SuperAdminka już w przedszkolu liczyła na palcach rąk do 1024 (2^10 – dwa stany: palec wysunięty, palec schowany), a w barze zamawia 4 piwa pokazując barmanowi środkowy palec ;-D

    • magdazarych

      132 😀

  • Robert

    Hej, SuperAdminko, data modyfikacji i-węzła jest z roku 2012

    • magdazarych

      Brawo dla tego pana! Nie zwróciłam na to uwagi preparując wyniki 😀 Znajdziesz inne (już celowe) przekłamania? 🙂

  • Ris

    mutt.