عندما لا يكون "أ" يساوي "أ". في أعقاب الاختراق

حدثت قصة غير سارة لأحد أصدقائي. ولكن على الرغم من أن الأمر كان مزعجًا بالنسبة لميخائيل، إلا أنه كان مسليًا بالنسبة لي.

ويجب أن أقول أن صديقي تماما UNIX-المستخدم: يمكنه تثبيت النظام بنفسه ك, فب وقم بإجراء إعدادات بسيطة NGINX.
ولديه عشرات أو مواقع ونصف مخصصة لأدوات البناء.

أحد هذه المواقع المخصصة للمناشير يحتل موقعًا ثابتًا في أعلى محركات البحث. هذا الموقع هو مراجع غير تجاري، ولكن هناك من اعتاد مهاجمته. الذي - التي دوس، ثم القوة الغاشمة، ثم يكتبون تعليقات فاحشة ويرسلون الإساءات إلى الاستضافة وإلى RKN.
وفجأة هدأ كل شيء، وتبين أن هذا الهدوء ليس جيدًا، وبدأ الموقع في ترك السطور العليا لنتائج البحث تدريجيًا.

عندما لا يكون "أ" يساوي "أ". في أعقاب الاختراق

كان هذا مقولة، ثم قصة المشرف نفسها.

كان وقت النوم يقترب عندما رن الهاتف: "سان، ألن تنظر إلى الخادم الخاص بي؟ يبدو لي أنني تعرضت للاختراق، لا أستطيع إثبات ذلك، لكن الشعور لم يتركني للأسبوع الثالث. ربما حان الوقت بالنسبة لي للحصول على علاج لجنون العظمة؟

وتلا ذلك نقاش دام نصف ساعة، ويمكن تلخيصه على النحو التالي:

  • وكانت تربة القرصنة خصبة للغاية؛
  • يمكن للمهاجم الحصول على حقوق المستخدم المتميز؛
  • أن الهجوم (إذا حدث) كان يستهدف هذا الموقع على وجه التحديد؛
  • تم تصحيح مناطق المشاكل وتحتاج فقط إلى فهم ما إذا كان هناك أي اختراق؛
  • لا يمكن أن يؤثر الاختراق على كود الموقع وقواعد البيانات.

فيما يتعلق بالنقطة الأخيرة.

عندما لا يكون "أ" يساوي "أ". في أعقاب الاختراق

فقط عنوان IP للواجهة الأمامية البيضاء هو الذي يطل على العالم. لا يوجد تبادل بين الواجهات الخلفية والواجهة الأمامية باستثناء http(s)، والمستخدمون/كلمات المرور مختلفة، ولم يتم تبادل أي مفاتيح. في العناوين الرمادية، يتم إغلاق كافة المنافذ باستثناء 80/443. عناوين IP للواجهة الخلفية البيضاء معروفة فقط لمستخدمين اثنين، يثق بهم ميخائيل تمامًا.

تم تثبيته على الواجهة الأمامية ديبيان 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?
- انتظر، أنا لا أعرف حتى كيف أفعل هذا!
- حسنًا، اذهبي إلى النوم..

إنجن إكس من الواضح أنه تم إعادة بنائه وتم إخفاء مخرجات القائمة باستخدام "-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 دعونا نحاول تثبيته باستخدام جدبولحسن الحظ هناك مفتاح --with-cc-opt -g الحاضر ونأمل أن التحسين -O2 لن يؤذينا. وفي نفس الوقت، لأنني لا أعرف كيف ngx_dump_config يمكن معالجتها في الحالة "ت":لن نستدعي هذه الكتلة، بل سنثبتها باستخدام الحالة "ر":

لماذا يمكنك استخدام "-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;
    }

بالطبع، إذا تم تغيير الكود في هذا الجزء وليس في الحالة "ت":، فإن طريقتي لن تنجح.

اختبار 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;

دعونا نلقي نظرة على ما يحدث هنا بالترتيب.

عازمون عامل المستخدم"ياندكس/جوجل:

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;

هذا صحيح، والدقة الوحيدة هي ذلك 'أ' != 'أ' كذلك 'س' != 'س':

عندما لا يكون "أ" يساوي "أ". في أعقاب الاختراق

وبالتالي، تتلقى روبوتات محرك البحث، بدلاً من النص السيريلي العادي بنسبة 100%، بيانات معدلة مخففة باللاتينية 'أ' и "س". لا أجرؤ على مناقشة كيفية تأثير ذلك على تحسين محركات البحث، ولكن من غير المرجح أن يكون لمثل هذا الخليط من الرسائل تأثير إيجابي على المواضع في نتائج البحث.

ماذا يمكنني أن أقول يا شباب مع الخيال.

مراجع

تصحيح الأخطاء باستخدام GDB
gdb(1) — صفحة دليل Linux
ستراس (1) — صفحة دليل Linux
Nginx - الوحدة النمطية ngx_http_sub_module
حول المناشير والمناشير والمناشير الكهربائية

المصدر: www.habr.com

إضافة تعليق