Acasă - Date
Analizoare de pachete de rețea. Wireshark (interceptor de pachete de rețea) Cum să verificați un port folosind wireshark

Schema generala

Secvența de pași pe care trebuie să-i efectueze un program care utilizează biblioteca pcap (de la PacketCAPture) pentru a-și îndeplini sarcina este următoarea:

  • Definiți interfața de rețea care va fi ascultată. (Pe Linux, acesta ar putea fi eth0, pe BSD xl1).
  • Inițializați pcap. În acest caz, biblioteca este informată pe ce interfață vom asculta datele. Este posibil să ascultați mai multe interfețe simultan (în sesiuni diferite).
  • Dacă este necesar să creați un filtru (de exemplu, ne interesează doar pachetele TCP care sosesc pe portul 23), „compilați” acest filtru și aplicați-l unei anumite sesiuni.
  • Accesați ciclul de primire a pachetelor. După aceasta, de fiecare dată când sosește un alt pachet și trece prin filtrul specificat, este apelată o funcție care trebuie definită în prealabil. Această funcție poate efectua orice acțiune dorim. Poate analiza pachetul și îl poate da utilizatorului, îl poate salva pe disc sau nu poate face nimic.
  • Când ați terminat, trebuie să închideți toate sesiunile deschise.

Să luăm în considerare pașii enumerați în detaliu.

Definiția interfeței

Pentru a determina interfața pe care să ascultați, puteți utiliza două metode.

Primul este că numele interfeței este specificat de utilizator. Luați în considerare următorul program:

#include #include Int principal(int argc, char *argv) ( char *dev = argv; printf("Dispozitiv: %s\n", dev); return(0); )

Utilizatorul specifică interfața pasând numele acesteia ca prim argument programului nostru. Desigur, interfața specificată de utilizator trebuie să existe.

A doua modalitate este să aflați numele interfeței din biblioteca însăși:

#include #include Int main() ( char *dev, errbuf; dev = pcap_lookupdev(errbuf); printf("Dispozitiv: %s\n", dev); return(0); )

În acest caz, pcap ne oferă numele interfeței pe care o deține. Linia errbuf va conține o descriere a erorii dacă apare una la executarea apelului pcap_lookupdev().

Deschiderea unei interfețe pentru interceptarea pachetelor

Pentru a crea o sesiune de interceptare a traficului, trebuie să apelați funcția pcap_open_live(). Prototipul acestei funcții (din pagina de manual pcap) arată astfel:

Pcap_t *pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf)

Primul argument este numele dispozitivului pe care l-am definit în pasul anterior. snaplen este un număr întreg care specifică numărul maxim de octeți ai unui cadru de rețea care va fi capturat de bibliotecă. Dacă promisc este setat la true, interfața intră în așa-numitul mod promiscuu (pachetele adresate altor stații din rețea sunt interceptate). to_ms - timeout în milisecunde (dacă valoarea este setată la zero, citirea va avea loc până la prima eroare, dacă este setată la minus unu - la infinit). În cele din urmă, errbuf este linia în care vom primi mesajul de eroare. Funcția returnează mânerul de sesiune (descriptor).

Pentru a demonstra, să ne uităm la o bucată de cod:

#include Pcap_t *mâner; handle = pcap_open_live(somedev, BUFSIZ, 1, 0, errbuf);

Aici se deschide o interfață, al cărei nume este indicat în linia somedev , indicând câți octeți ai pachetului de capturat (valoarea BUFSIZ este definită în pcap.h). Interfața de rețea comută în modul promiscuu. Datele vor fi citite până când apare o eroare. În cazul unei erori, puteți afișa descrierea textului acesteia pe ecran folosind indicatorul errbuf.

O notă despre interceptarea traficului în moduri promiscue și non-promiscue: cele două metode sunt foarte diferite. În cazul interceptării traficului în modul non-promiscuu, nodul primește doar traficul care este direcționat către sau legat de acesta. Doar traficul către, de la și direcționat prin gazdă va fi interceptat de programul nostru. În modul promiscuu, interfața de rețea acceptă toate pachetele care vin prin cablu. Într-un mediu necomutat, acesta ar putea fi tot traficul de rețea. Avantajul său clar este că oferă un număr mai mare de pachete de interceptat, ceea ce poate fi (sau nu) util în funcție de ceea ce interceptați fluxul de rețea.

Cu toate acestea, interceptarea traficului în modul promiscuu poate fi detectată; un alt nod poate determina cu mare precizie dacă folosim modul promiscuu. În plus, funcționează numai în medii fără comutare (cum ar fi hub-uri sau switch-uri care sunt inundate cu pachete arp). În al treilea rând, dacă rețeaua este încărcată puternic, programul nostru va folosi o cantitate mare de resurse de sistem.

Filtrarea traficului

Adesea este necesar un interceptor de pachete pentru a intercepta nu toate, ci doar anumite pachete. De exemplu, sunt momente când vrem să interceptăm traficul pe portul 23 (telnet) în căutarea parolelor. Sau poate vrem să interceptăm un fișier trimis prin portul 21 (FTP). Poate că vrem doar să interceptăm Trafic DNS(al 53-lea port UDP). În orice caz, foarte rar este necesar să interceptați toate datele. Funcțiile pcap_compile() și pcap_setfilter() sunt folosite pentru a filtra traficul.

Odată ce am apelat pcap_open_live() și avem o sesiune de captare a traficului funcțională, putem aplica filtrul nostru. Desigur, puteți implementa filtrul manual prin analizarea antetelor ETH/IP/TCP după primirea pachetului, dar utilizarea filtrului intern pcap este mai eficientă și, de asemenea, mai simplă.

Înainte de a putea aplica un filtru, trebuie să-l „compilați”. Expresia filtrului este stocată într-un șir obișnuit (matrice de caractere). Sintaxa unor astfel de expresii este descrisă în detaliu în pagina de manual tcpdump (man tcpdump).

Funcția pcap_compile() este utilizată pentru a compila filtrul. Prototipul său arată astfel:

Int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

Primul argument este mânerul (descriptorul) sesiunii noastre (pcap_t *handle în exemplul anterior). Următorul argument este un pointer către zona din memorie în care vom stoca versiunea compilată a filtrului nostru. Urmează expresia de filtru în sine în formă sfoară obișnuită. Următorul parametru determină dacă expresia noastră trebuie să fie optimizată sau nu (ca de obicei, 0 înseamnă nu, 1 înseamnă da). Ultimul parametru este masca de rețea la care este aplicat filtrul nostru. Funcția returnează -1 în caz de eroare, toate celelalte valori indică finalizarea cu succes.

Odată compilată expresia, aceasta trebuie aplicată, ceea ce se face folosind funcția pcap_setfilter(). Prototipul său este următorul:

Int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

Primul argument este mânerul (descriptorul) sesiunii noastre de interceptare a pachetelor, al doilea este un pointer către versiunea compilată a expresiei pentru filtru (de obicei, al doilea argument al funcției pcap_compile()).

Următorul exemplu demonstrează utilizarea unui filtru:

#include Pcap_t *mâner; // descriptor de sesiune char dev = "eth0"; // interfata pe care vom asculta char errbuf; // Linie cu eroare struct bpf_program filter; // Expresie compilată pentru filtrul char filter_app = "port 23"; // Expresie pentru masca filtrului bpf_u_int32; // Mască de rețea a interfeței noastre bpf_u_int32 net; // adresa IP a interfeței noastre pcap_lookupnet(dev, &net, &mask, errbuf); handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); pcap_compile(handle, &filter, filter_app, 0, net); pcap_setfilter(mâner, &filtru);

Acest program pregătește un interceptor pentru pachetele care merg către sau dinspre portul 23, în mod promiscuu, pe interfața eth0. Exemplul conține funcția pcap_lookupnet(), care returnează adresa de rețeași masca de rețea pentru dispozitivul al cărui nume îi este transmis ca parametru. Utilizarea lui este necesară deoarece pentru a aplica un filtru trebuie să cunoaștem adresa și masca de rețea.

Interceptarea pachetelor

Există două tehnici de interceptare a pachetelor. Puteți intercepta și procesa câte un pachet la un moment dat, sau puteți lucra cu un grup de pachete setând o buclă specială care va rula până când pcap interceptează un anumit număr de pachete. Pentru a lucra în primul mod, se folosește funcția pcap_next(). Prototipul pcap_next():

U_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

Primul argument este mânerul sesiunii noastre, al doilea este un pointer către o structură în care vor fi stocate informații despre pachet, cum ar fi ora la care a fost interceptat, lungimea pachetului și lungimea părții sale individuale ( de exemplu, dacă pachetul este fragmentat). pcap_next() returnează un pointer u_char la locația de memorie în care este stocat pachetul descris de această structură.

Demonstrație de utilizare a pcap_next() pentru a captura un singur pachet:

#include #include int main() ( pcap_t *handle; char *dev; char errbuf; // linie care descrie structura de eroare filtrul bpf_program; // filtru compilat char filter_app = "port 23"; // filtru bpf_u_int32 mask; // masca de rețea bpf_u_int32 net ; // adresa noastră ip struct pcap_pkthdr // antetul pachetului care va umple pcap const u_char *packet // definește interfața dev = pcap_lookupdev(errbuf); (dev, &net, &mask, errbuf // deschideți sesiunea de interceptare în modul promiscuu handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf) // compilați și aplicați filtrul de pachete pcap_compile(handle, &filter, filter_app); 0, net); pcap_setfilter(handle, &filter // interceptează pachetul = pcap_next(handle, &header) // imprimă lungimea acestuia în consolă printf("Jacked un pachet cu lungimea de [%d]); , header.len / închide sesiunea pcap_close(handle);

Acest program interceptează pachetele de pe dispozitiv pe care le returnează pcap_lookupdev(), punându-l în modul pormisc. Detectează un pachet care vine prin portul 23 (telnet) și își afișează dimensiunea în octeți. Apelarea pcap_close() închide o sesiune de captură deschisă.

Metoda alternativă, deși mai greu de înțeles, este probabil să fie mai utilă. Există foarte puține (dacă există) capturi de pachete care folosesc pcap_next() . În marea majoritate a cazurilor folosesc pcap_loop() sau pcap_dispatch() (care, la rândul său, utilizează pcap_loop()). Pentru a înțelege utilizarea acestor două funcții, trebuie să înțelegeți ideea funcțiilor de apel invers.

Funcțiile de apel invers sunt o tehnică de programare folosită frecvent. Principiul este destul de simplu. Să presupunem că aveți un program care așteaptă un eveniment. În scopul, de exemplu, de a procesa o apăsare a tastei. De fiecare dată când o tastă este apăsată, vreau să apelez o funcție care se va ocupa de acel eveniment. Funcția pe care o folosesc este o funcție de apel invers. De fiecare dată când utilizatorul apasă o tastă, programul meu va apela o funcție de apel invers. Funcțiile de apel invers sunt folosite în pcap, dar în loc să le apeleze când utilizatorul apasă o tastă, pcap le apelează atunci când primește un alt pachet. pcap_loop() și pcap_dispatch() sunt funcții care folosesc mecanismul funcției de apel invers aproape în același mod. Ambele apelează o funcție de apel invers de fiecare dată când pcap interceptează un pachet care trece prin filtru (cu excepția cazului în care, desigur, filtrul este compilat și aplicat sesiunii, altfel toate pachetele interceptate sunt transmise funcției de apel invers)

Prototipul funcției pcap_loop():

Int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user);

Primul argument este mâna noastră de sesiune. Următorul întreg îi spune pcap_loop() câte pachete totale să capteze (o valoare negativă înseamnă că pachetele trebuie capturate până când apare o eroare). Al treilea argument este numele funcției de apel invers (numai numele, fără paranteze). Ultimul argument este folosit în unele aplicații, dar de obicei este pur și simplu setat la NULL. pcap_dispatch() este aproape identic, singura diferență este modul în care funcțiile gestionează timeout-ul, a cărui valoare este setată când este apelată pcap_open_live().

pcap_loop() pur și simplu ignoră timeout-urile, spre deosebire de pcap_dispatch() . Detaliile sunt în man pcap.

Înainte de a da un exemplu de utilizare a pcap_loop(), trebuie să ne uităm la formatul funcției noastre de apel invers. Nu putem defini în mod arbitrar un prototip de funcție de apel invers deoarece pcap_loop() nu va ști ce să facă cu el. Prototipul funcției noastre de apel invers ar trebui să fie astfel:

Să aruncăm o privire mai atentă. În primul rând, funcția returnează o valoare goală (void). Acest lucru are sens, deoarece pcap_loop() nu poate ști ce să facă cu valoarea returnată. Primul argument este același cu ultimul argument pentru pcap_loop(). Orice valoare este folosită ca ultim argument pentru pcap_loop() este transmisă ca prim argument funcției de apel invers de fiecare dată când este apelată din pcap_loop() . Al doilea argument este antetul pcap, care conține informații despre momentul în care a fost capturat pachetul, dimensiunea acestuia etc. Structura pcap_pkthdr este definită în pcap.h după cum urmează:

Struct pcap_pkthdr ( struct timeval ts; // timestamp bpf_u_int32 caplen; // lungimea părții capturate a pachetului bpf_u_int32 len; // lungimea totală a pachetului);

Ultimul argument al funcției de apel invers este cel mai interesant. Acesta este un pointer către un buffer, care conține de fapt întregul pachet capturat folosind pcap_loop().

Cum se utilizează variabila pachet? Pachetul conține multe atribute, așa că, după cum vă puteți imagina, nu este de fapt un șir, ci un set de structuri (de exemplu, un pachet TCP/IP va conține un antet ethernet, ip, tcp și datele în sine). Parametrul de pachet, care este de tip u_char , este de fapt o versiune serializată a acestor structuri. Pentru a obține date utile din aceste structuri, trebuie să efectuăm câteva transformări.

În primul rând, trebuie să avem structuri definite în programul pe care îl vom folosi. Vom folosi următoarele structuri (de fapt le-am putea lua direct din fișierele antet, dar numele câmpurilor structurilor variază de la platformă la platformă, așa că acestea sunt folosite în scopuri demonstrative):

Struct sniff_ethernet ( u_char ether_dhost; u_char ether_shost; u_short ether_type; /* IP? ARP? RARP? etc */ ); // Structura antetului IP sniff_ip ( #if BYTE_ORDER == LITTLE_ENDIAN u_int ip_hl:4, ip_v:4; #endif #if BYTE_ORDER == BIG_ENDIAN u_int ip_v:4, /* versiunea */ ip_hl:4; /* lungimea antetului */ #endif /* not _IP_VHL */ u_char ip_tos u_short ip_id #define IP_RF 0x8000 /* flag fragment rezervat */ #define IP_DF 0x4000 /* dont flag */ #define IP_MF 0x2000 /* flag mai multe fragmente */ #define 0x1fff /* masca pentru fragmentarea biților */ u_char ip_ttl /* time to live */ u_char ip_p /* protocol */ u_short ip_sum */ struct in_addr ip_src, ip_dst; struct sniff_tcp ( u_short th_sport; u_short th_dport; tcp_seq th_seq; /* numărul de secvență */ tcp_seq th_ack; /* numărul de confirmare */ #dacă BYTE_ORDER == LITTLE_ENDIAN u_int ,/* 4:00:_; * offset de date */ #endif #if BYTE_ORDER == BIG_ENDIAN u_int th_off:4, /* offset de date */ th_x2:4 /* (neutilizat) */ #endif u_char th_flags #define TH_FIN 0x01 #define TH_SYN 0; TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS \ (TH_FIN|TH_SYN|TH_T_TH|TH_TH|TH_TH|TH_TH|TH_TH|TH__TH| short th_win /* fereastra */ u_short th_sum /* checksum */ u_short th_urp /* urgent pointer */ );

Dacă sunt folosite descrieri de structură din fișierele antet standard, uneori, pentru ca un program care folosește o descriere antet TCP să se compila fără erori, este necesar să definiți simbolul _BSD_SOURCE înainte de a include fișierele antet. Mod alternativ- definiți manual structurile care descriu antetul TCP.

pcap folosește în mod natural exact aceleași structuri atunci când captează pachete. Apoi pur și simplu creează un șir u_char (buffer) și copiază datele din structuri în el. Cum se analizează un șir înapoi în structuri? Acest lucru se realizează cu ușurință folosind indicatori și conversii de tip.

Mai întâi, să declarăm variabilele de care avem nevoie pentru a analiza pachetul u_char în anteturi separate:

Const struct sniff_ethernet *ethernet; const struct sniff_ip *ip; const struct sniff_tcp *tcp; const char *sarcină utilă; int size_ethernet = sizeof(struct sniff_ethernet); int size_ip = sizeof(struct sniff_ip); int size_tcp = sizeof(struct sniff_tcp);

Acum facem conversia tipului:

Ethernet = (struct sniff_ethernet*)(pachet); ip = (struct sniff_ip*)(pachet + dimensiune_ethernet); tcp = (struct sniff_tcp*)(pachet + size_ethernet + size_ip); sarcină utilă = (u_char *)(pachet + size_ethernet + size_ip + size_tcp);

După aceasta, putem accesa câmpurile tuturor structurilor în mod obișnuit, de exemplu:

Dacă (tcp->th_flags & TH_URG) ( ... ); ... printf("TTL = %d\n", ip->ip_ttl);

Închidere

Când ați terminat, trebuie să închideți sesiunea. Acest lucru se face folosind funcția pcap_close().

Fiecare membru al echipei ][ are propriile preferințe în ceea ce privește software-ul și utilitățile pentru
test de stilou. În urma consultării, am aflat că alegerea variază atât de mult încât este posibil
creați un adevărat set de programe dovedite. Asta este
hotărât. Pentru a nu face un amestec, am împărțit întreaga listă în subiecte - și în
De data aceasta, vom atinge utilitățile pentru adulmecarea și manipularea pachetelor. Folosește-l pe
sănătate.

Wireshark

Netcat

Dacă vorbim despre interceptarea datelor, atunci Network Miner va fi scos din aer
(sau dintr-un dump pre-preparat în format PCAP) fișiere, certificate,
imagini și alte medii, precum și parole și alte informații pentru autorizare.
O caracteristică utilă este să căutați acele secțiuni de date care conțin cuvinte cheie
(de exemplu, autentificarea utilizatorului).

Scapy

Site:
www.secdev.org/projects/scapy

Un must-have pentru orice hacker, este un instrument puternic pentru
manipularea interactivă a pachetelor. Primiți și decodați cele mai multe pachete
diferite protocoale, răspunde la cerere, injectează modificată și
un pachet creat de tine - totul este ușor! Cu ajutorul lui, puteți realiza un întreg
o serie de sarcini clasice, cum ar fi scanarea, tracoruta, atacurile și detectarea
infrastructura de retea. Într-o sticlă primim un înlocuitor pentru astfel de utilități populare,
cum ar fi: hping, nmap, arpspoof, arp-sk, arping, tcpdump, tetheral, p0f etc. La asta
era timpul Scapy vă permite să îndepliniți orice sarcină, chiar și cea mai specifică
o sarcină care nu poate fi realizată niciodată de un alt dezvoltator deja creat
mijloace. În loc să scrieți un întreg munte de linii în C pentru, de exemplu,
generarea unui pachet greșit și fuzzing-ul unui daemon este suficient
introduceți câteva rânduri de cod folosind Scapy! Programul nu are
interfață grafică, iar interactivitatea se realizează prin intermediul interpretului
Piton. Odată ce ați înțeles, nu vă va costa nimic să creați incorect
pachete, injectează cadrele 802.11 necesare, combină abordări diferite în atacuri
(să zicem, otrăvirea cache-ului ARP și saltul VLAN), etc. Dezvoltatorii înșiși insistă
pentru a se asigura că capacitățile lui Scapy sunt utilizate în alte proiecte. Conectându-l
ca modul, este ușor să creați un utilitar pentru diferite tipuri de cercetare în zonă,
căutarea vulnerabilităților, injecție Wi-Fi, execuție automată a anumitor
sarcini, etc.

pachet

Site:
Platformă: *nix, există un port pentru Windows

O dezvoltare interesantă care permite, pe de o parte, să genereze oricare
pachet Ethernet și, pe de altă parte, trimite secvențe de pachete cu scopul
verificări lățime de bandă. Spre deosebire de alte instrumente similare, pachet
are o interfață grafică, permițându-vă să creați pachete în cel mai simplu mod
formă. Mai departe - mai mult. Crearea și trimiterea sunt deosebit de elaborate
secvențe de pachete. Puteți seta întârzieri între trimitere,
trimite pachete cu viteza maxima pentru a verifica lățimea de bandă
secțiunea rețelei (da, aici se vor depune) și, ceea ce este și mai interesant -
modificarea dinamică a parametrilor în pachete (de exemplu, adresa IP sau MAC).

Pe lângă conectarea la canalul de transmisie a datelor, monitorul trebuie să aibă mod eficient identificați ce pachete IP să fie interceptate pe măsură ce sosesc. Protocoale de nivel de aplicație De obicei, conexiunile sunt realizate la un anumit port TCP, de exemplu, HTTP utilizează porg 80. Pentru a monitoriza traficul HTTP, monitorul de pachete se poate limita la a lua în considerare traficul TCP pe portul 80. Această decizie poate fi luată pentru fiecare pachet specific prin analiza câmpului de protocol din antetul IP și numerele portului sursă și destinație din antetul TCP. Cu toate acestea, este destul de dificil să izolați tot traficul HTTP. Unele site-uri Web nu folosesc acest port, dar folosesc porturile 8000 sau 8080. În plus, unele aplicații pot comunica prin portul 80 folosind un protocol diferit. Deși porturile sunt alocate unor aplicații specifice, dezvoltatorul aplicației sau administrator de sistem poate ignora aceste instrucțiuni și poate utiliza portul 80 pentru o aplicație care utilizează un alt protocol.

În plus, Web-ul are un protocol HTTPS care utilizează portul 443. Un monitor de pachete poate capta traficul HTTPS prin monitorizarea traficului TCP care conține portul 443 ca număr de port sursă și destinație. Cu toate acestea, datele trimise prin HTTPS sunt criptate utilizând un Secure Socket Layer (. SSL). Monitorul nu poate identifica mesajele HTTP trimise prin aceste conexiuni TCP. Cu toate acestea, poate intercepta traficul TCP pe portul 443 pentru a calcula statistici de bază, cum ar fi numărul de conexiuni și octeți transferați folosind HTTPS. Alte transferuri inițiate de browser web pot utiliza protocoale diferite de nivel de aplicație. În unele cazuri, acest trafic poate fi interceptat prin monitorizarea porturilor alocate acestor protocoale. Cu toate acestea, o serie de aplicații folosesc protocoale care atribuie în mod dinamic numere de port atunci când transmit date. De exemplu, clientul și serverul FTP (File Transfer Protocol) pot selecta în mod dinamic numărul portului pentru conexiunea TCP utilizată pentru transferul de date. De asemenea, multe protocoale de streaming media nu folosesc de obicei numere de porturi specifice pentru a transmite date audio și video, așa cum va fi discutat mai detaliat mai târziu în Secțiunea 14.4.4.

Interceptarea traficului cu anteturi IP și TCP specifice necesită aplicarea unui filtru pachetelor IP pe măsură ce ajung. Filtrarea pachetelor cât mai devreme posibil reduce costul general asociat cu copierea și procesarea pachetelor care sunt apoi aruncate. Monitorul de pachete poate avea un software special anarate care clasifică pachetele atunci când sunt primite. placa de retea. Dacă suportul anar nu este prezent, pachetele pot fi filtrate de sistemul de operare sau de aplicație. Un număr mare de programe de monitorizare a pachetelor se bazează pe instrumentul tcpdump.

LJLM, Tcpj bazat pe filtrul de pachete Berkeley (BPF)

 


Citire:



De ce procesorul de pe computerul meu devine foarte fierbinte?

De ce procesorul de pe computerul meu devine foarte fierbinte?

Nu am avut de gând să scriu acest articol, am fost îndemnat să-l scriu de multe întrebări despre supraîncălzirea laptopului, curățarea acestuia și înlocuirea pastei termice. Pe...

Ce este modul „Turbo” în browserele moderne: Chrome, Yandex, Opera

Ce este modul „Turbo” în browserele moderne: Chrome, Yandex, Opera

Multe browsere web cunoscute, de exemplu, Yandex.Browser, au un mod special „Turbo”, care poate crește semnificativ viteza...

Cel mai simplu șablon. Șabloane HTML simple. Mamba - șablon de o pagină

Cel mai simplu șablon.  Șabloane HTML simple.  Mamba - șablon de o pagină

Toate șabloanele prezentate pentru site-ul dvs. sunt construite pe versiuni moderne de HTML5 și CSS3. În plus, autorii folosesc astfel de caracteristici la modă precum...

3 baze de informații distribuite

3 baze de informații distribuite

Crearea și configurarea unei baze de date distribuite (RDB) în 1C 8.3 Contabilitate (și alte configurații) este necesară în cazurile în care nu este posibil...

imagine-alimentare RSS