Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Nesten alle av oss bruker tjenestene til nettbutikker, noe som betyr at vi før eller siden risikerer å bli offer for JavaScript-sniffer - spesiell kode som angripere implementerer på et nettsted for å stjele bankkortdata, adresser, pålogginger og passord til brukere .

Nesten 400 000 brukere av nettsiden og mobilapplikasjonen British Airways har allerede blitt rammet av sniffere, samt besøkende på den britiske nettsiden til sportsgiganten FILA og den amerikanske billettdistributøren Ticketmaster. PayPal, Chase Paymenttech, USAePay, Moneris - disse og mange andre betalingssystemer ble infisert.

Threat Intelligence Group-IB-analytiker Viktor Okorokov snakker om hvordan sniffere infiltrerer nettsidekode og stjeler betalingsinformasjon, samt hvilke CRM-er de angriper.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

"Skjult trussel"

Det hendte slik at JS-sniffere i lang tid forble ute av syne for antivirusanalytikere, og banker og betalingssystemer så dem ikke som en alvorlig trussel. Og helt forgjeves. Group-IB-eksperter analysert 2440 infiserte nettbutikker, hvis besøkende – totalt rundt 1,5 millioner mennesker per dag – sto i fare for å gå på kompromiss. Blant ofrene er ikke bare brukere, men også nettbutikker, betalingssystemer og banker som utstedte kompromitterte kort.

Rapport Group-IB ble den første studien av darknet-markedet for sniffere, deres infrastruktur og metoder for inntektsgenerering, som gir skaperne deres millioner av dollar. Vi identifiserte 38 familier av sniffere, hvorav bare 12 tidligere var kjent for forskere.

La oss dvele i detalj ved de fire snifferfamiliene som ble studert under studien.

ReactGet Family

Sniffere fra ReactGet-familien brukes til å stjele bankkortdata på nettbutikksider. Snifferen kan fungere med et stort antall forskjellige betalingssystemer som brukes på nettstedet: én parameterverdi tilsvarer ett betalingssystem, og individuelle oppdagede versjoner av snifferen kan brukes til å stjele legitimasjon, samt til å stjele bankkortdata fra betaling former for flere betalingssystemer samtidig, som den såkalte universelle snifferen. Det ble funnet at i noen tilfeller utfører angripere phishing-angrep på nettbutikkadministratorer for å få tilgang til nettstedets administrative panel.

En kampanje med denne familien av sniffere startet i mai 2017; nettsteder som kjører CMS og Magento, Bigcommerce og Shopify-plattformer ble angrepet.

Hvordan ReactGet implementeres i koden til en nettbutikk

I tillegg til den "klassiske" implementeringen av et skript via en lenke, bruker operatørene av ReactGet-familien av sniffere en spesiell teknikk: ved hjelp av JavaScript-kode sjekker de om den nåværende adressen der brukeren befinner seg oppfyller visse kriterier. Den ondsinnede koden vil bare bli utført hvis understrengen er til stede i gjeldende URL kassen eller ett trinns utsjekking, en side/, ut/onepag, kassa/en, ckout/en. Dermed vil snifferkoden bli utført nøyaktig i det øyeblikket brukeren fortsetter å betale for kjøp og legger inn betalingsinformasjon i skjemaet på nettstedet.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Denne snifferen bruker en ikke-standard teknikk. Offerets betalings- og personopplysninger samles inn og kodes ved hjelp av base64, og deretter brukes den resulterende strengen som en parameter for å sende en forespørsel til angriperens nettsted. Oftest imiterer banen til porten en JavaScript-fil, for eksempel resp.js, data.js og så videre, men lenker til bildefiler brukes også, GIF и JPG. Det særegne er at snifferen lager et bildeobjekt som måler 1 x 1 piksel og bruker den tidligere mottatte lenken som parameter src Bilder. Det vil si at for brukeren vil en slik forespørsel i trafikken se ut som en forespørsel om et vanlig bilde. En lignende teknikk ble brukt i ImageID-familien av sniffere. I tillegg brukes teknikken med å bruke et bilde på 1 x 1 piksel i mange legitime online analyseskript, som også kan villede brukeren.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Versjonsanalyse

Analyse av de aktive domenene brukt av ReactGet sniffer-operatører avslørte mange forskjellige versjoner av denne familien av sniffere. Versjoner er forskjellige i tilstedeværelse eller fravær av obfuskasjon, og i tillegg er hver sniffer designet for et spesifikt betalingssystem som behandler bankkortbetalinger for nettbutikker. Etter å ha sortert gjennom verdien av parameteren som tilsvarer versjonsnummeret, mottok Group-IB-spesialister en komplett liste over tilgjengelige sniffervarianter, og ved navnene på skjemafeltene som hver sniffer ser etter i sidekoden, identifiserte de betalingssystemene som snifferen er rettet mot.

Liste over sniffere og deres tilhørende betalingssystemer

Sniffer URL Betalingssystem
reactjsapi.com/react.js Authorize.Net
ajaxstatic.com/api.js?v=2.1.1 Kortlagring
ajaxstatic.com/api.js?v=2.1.2 Authorize.Net
ajaxstatic.com/api.js?v=2.1.3 Authorize.Net
ajaxstatic.com/api.js?v=2.1.4 eWAY Rask
ajaxstatic.com/api.js?v=2.1.5 Authorize.Net
ajaxstatic.com/api.js?v=2.1.6 adyen
ajaxstatic.com/api.js?v=2.1.7 USAePay
ajaxstatic.com/api.js?v=2.1.9 Authorize.Net
apitstatus.com/api.js?v=2.1.1 USAePay
apitstatus.com/api.js?v=2.1.2 Authorize.Net
apitstatus.com/api.js?v=2.1.3 Moneris
apitstatus.com/api.js?v=2.1.5 USAePay
apitstatus.com/api.js?v=2.1.6 PayPal
apitstatus.com/api.js?v=2.1.7 Salviepenger
apitstatus.com/api.js?v=2.1.8 Verisign
apitstatus.com/api.js?v=2.1.9 PayPal
apitstatus.com/api.js?v=2.3.0 Stripe
apitstatus.com/api.js?v=3.0.2 Realex
apitstatus.com/api.js?v=3.0.3 PayPal
apitstatus.com/api.js?v=3.0.4 LinkPoint
apitstatus.com/api.js?v=3.0.5 PayPal
apitstatus.com/api.js?v=3.0.7 PayPal
apitstatus.com/api.js?v=3.0.8 DataCash
apitstatus.com/api.js?v=3.0.9 PayPal
asianfoodgracer.com/footer.js Authorize.Net
billgetstatus.com/api.js?v=1.2 Authorize.Net
billgetstatus.com/api.js?v=1.3 Authorize.Net
billgetstatus.com/api.js?v=1.4 Authorize.Net
billgetstatus.com/api.js?v=1.5 Verisign
billgetstatus.com/api.js?v=1.6 Authorize.Net
billgetstatus.com/api.js?v=1.7 Moneris
billgetstatus.com/api.js?v=1.8 Salviepenger
billgetstatus.com/api.js?v=2.0 USAePay
billgetstatus.com/react.js Authorize.Net
cloudodesc.com/gtm.js?v=1.2 Authorize.Net
cloudodesc.com/gtm.js?v=1.3 ANZ eGate
cloudodesc.com/gtm.js?v=2.3 Authorize.Net
cloudodesc.com/gtm.js?v=2.4 Moneris
cloudodesc.com/gtm.js?v=2.6 Salviepenger
cloudodesc.com/gtm.js?v=2.7 Salviepenger
cloudodesc.com/gtm.js?v=2.8 Chase Paymentech
cloudodesc.com/gtm.js?v=2.9 Authorize.Net
cloudodesc.com/gtm.js?v=2.91 adyen
cloudodesc.com/gtm.js?v=2.92 PsiGate
cloudodesc.com/gtm.js?v=2.93 Cyberkilde
cloudodesc.com/gtm.js?v=2.95 ANZ eGate
cloudodesc.com/gtm.js?v=2.97 Realex
geisseie.com/gs.js USAePay
gtmproc.com/age.js Authorize.Net
gtmproc.com/gtm.js?v=1.2 Authorize.Net
gtmproc.com/gtm.js?v=1.3 ANZ eGate
gtmproc.com/gtm.js?v=1.5 PayPal
gtmproc.com/gtm.js?v=1.6 PayPal
gtmproc.com/gtm.js?v=1.7 Realex
livecheckpay.com/api.js?v=2.0 Salviepenger
livecheckpay.com/api.js?v=2.1 PayPal
livecheckpay.com/api.js?v=2.2 Verisign
livecheckpay.com/api.js?v=2.3 Authorize.Net
livecheckpay.com/api.js?v=2.4 Verisign
livecheckpay.com/react.js Authorize.Net
livegetpay.com/pay.js?v=2.1.2 ANZ eGate
livegetpay.com/pay.js?v=2.1.3 PayPal
livegetpay.com/pay.js?v=2.1.5 Cyberkilde
livegetpay.com/pay.js?v=2.1.7 Authorize.Net
livegetpay.com/pay.js?v=2.1.8 Salviepenger
livegetpay.com/pay.js?v=2.1.9 Realex
livegetpay.com/pay.js?v=2.2.0 Cyberkilde
livegetpay.com/pay.js?v=2.2.1 PayPal
livegetpay.com/pay.js?v=2.2.2 PayPal
livegetpay.com/pay.js?v=2.2.3 PayPal
livegetpay.com/pay.js?v=2.2.4 Verisign
livegetpay.com/pay.js?v=2.2.5 eWAY Rask
livegetpay.com/pay.js?v=2.2.7 Salviepenger
livegetpay.com/pay.js?v=2.2.8 Salviepenger
livegetpay.com/pay.js?v=2.2.9 Verisign
livegetpay.com/pay.js?v=2.3.0 Authorize.Net
livegetpay.com/pay.js?v=2.3.1 Authorize.Net
livegetpay.com/pay.js?v=2.3.2 Første globale datagateway
livegetpay.com/pay.js?v=2.3.3 Authorize.Net
livegetpay.com/pay.js?v=2.3.4 Authorize.Net
livegetpay.com/pay.js?v=2.3.5 Moneris
livegetpay.com/pay.js?v=2.3.6 Authorize.Net
livegetpay.com/pay.js?v=2.3.8 PayPal
livegetpay.com/pay.js?v=2.4.0 Verisign
maxstatics.com/site.js USAePay
mediapack.info/track.js?d=funlove.com USAePay
mediapack.info/track.js?d=qbedding.com Authorize.Net
mediapack.info/track.js?d=vseyewear.com Verisign
mxcounter.com/c.js?v=1.2 PayPal
mxcounter.com/c.js?v=1.3 Authorize.Net
mxcounter.com/c.js?v=1.4 Stripe
mxcounter.com/c.js?v=1.6 Authorize.Net
mxcounter.com/c.js?v=1.7 eWAY Rask
mxcounter.com/c.js?v=1.8 Salviepenger
mxcounter.com/c.js?v=2.0 Authorize.Net
mxcounter.com/c.js?v=2.1 Braintree
mxcounter.com/c.js?v=2.10 Braintree
mxcounter.com/c.js?v=2.2 PayPal
mxcounter.com/c.js?v=2.3 Salviepenger
mxcounter.com/c.js?v=2.31 Salviepenger
mxcounter.com/c.js?v=2.32 Authorize.Net
mxcounter.com/c.js?v=2.33 PayPal
mxcounter.com/c.js?v=2.34 Authorize.Net
mxcounter.com/c.js?v=2.35 Verisign
mxcounter.com/click.js?v=1.2 PayPal
mxcounter.com/click.js?v=1.3 Authorize.Net
mxcounter.com/click.js?v=1.4 Stripe
mxcounter.com/click.js?v=1.6 Authorize.Net
mxcounter.com/click.js?v=1.7 eWAY Rask
mxcounter.com/click.js?v=1.8 Salviepenger
mxcounter.com/click.js?v=2.0 Authorize.Net
mxcounter.com/click.js?v=2.1 Braintree
mxcounter.com/click.js?v=2.2 PayPal
mxcounter.com/click.js?v=2.3 Salviepenger
mxcounter.com/click.js?v=2.31 Salviepenger
mxcounter.com/click.js?v=2.32 Authorize.Net
mxcounter.com/click.js?v=2.33 PayPal
mxcounter.com/click.js?v=2.34 Authorize.Net
mxcounter.com/click.js?v=2.35 Verisign
mxcounter.com/cnt.js Authorize.Net
mxcounter.com/j.js Authorize.Net
newrelicnet.com/api.js?v=1.2 Authorize.Net
newrelicnet.com/api.js?v=1.4 Authorize.Net
newrelicnet.com/api.js?v=1.8 Salviepenger
newrelicnet.com/api.js?v=4.5 Salviepenger
newrelicnet.com/api.js?v=4.6 Westpac PayWay
nr-public.com/api.js?v=2.0 PayFort
nr-public.com/api.js?v=2.1 PayPal
nr-public.com/api.js?v=2.2 Authorize.Net
nr-public.com/api.js?v=2.3 Stripe
nr-public.com/api.js?v=2.4 Første globale datagateway
nr-public.com/api.js?v=2.5 PsiGate
nr-public.com/api.js?v=2.6 Authorize.Net
nr-public.com/api.js?v=2.7 Authorize.Net
nr-public.com/api.js?v=2.8 Moneris
nr-public.com/api.js?v=2.9 Authorize.Net
nr-public.com/api.js?v=3.1 Salviepenger
nr-public.com/api.js?v=3.2 Verisign
nr-public.com/api.js?v=3.3 Moneris
nr-public.com/api.js?v=3.5 PayPal
nr-public.com/api.js?v=3.6 LinkPoint
nr-public.com/api.js?v=3.7 Westpac PayWay
nr-public.com/api.js?v=3.8 Authorize.Net
nr-public.com/api.js?v=4.0 Moneris
nr-public.com/api.js?v=4.0.2 PayPal
nr-public.com/api.js?v=4.0.3 adyen
nr-public.com/api.js?v=4.0.4 PayPal
nr-public.com/api.js?v=4.0.5 Authorize.Net
nr-public.com/api.js?v=4.0.6 USAePay
nr-public.com/api.js?v=4.0.7 EBizCharge
nr-public.com/api.js?v=4.0.8 Authorize.Net
nr-public.com/api.js?v=4.0.9 Verisign
nr-public.com/api.js?v=4.1.2 Verisign
ordercheckpays.com/api.js?v=2.11 Authorize.Net
ordercheckpays.com/api.js?v=2.12 PayPal
ordercheckpays.com/api.js?v=2.13 Moneris
ordercheckpays.com/api.js?v=2.14 Authorize.Net
ordercheckpays.com/api.js?v=2.15 PayPal
ordercheckpays.com/api.js?v=2.16 PayPal
ordercheckpays.com/api.js?v=2.17 Westpac PayWay
ordercheckpays.com/api.js?v=2.18 Authorize.Net
ordercheckpays.com/api.js?v=2.19 Authorize.Net
ordercheckpays.com/api.js?v=2.21 Salviepenger
ordercheckpays.com/api.js?v=2.22 Verisign
ordercheckpays.com/api.js?v=2.23 Authorize.Net
ordercheckpays.com/api.js?v=2.24 PayPal
ordercheckpays.com/api.js?v=2.25 PayFort
ordercheckpays.com/api.js?v=2.29 Cyberkilde
ordercheckpays.com/api.js?v=2.4 PayPal Payflow Pro
ordercheckpays.com/api.js?v=2.7 Authorize.Net
ordercheckpays.com/api.js?v=2.8 Authorize.Net
ordercheckpays.com/api.js?v=2.9 Verisign
ordercheckpays.com/api.js?v=3.1 Authorize.Net
ordercheckpays.com/api.js?v=3.2 Authorize.Net
ordercheckpays.com/api.js?v=3.3 Salviepenger
ordercheckpays.com/api.js?v=3.4 Authorize.Net
ordercheckpays.com/api.js?v=3.5 Stripe
ordercheckpays.com/api.js?v=3.6 Authorize.Net
ordercheckpays.com/api.js?v=3.7 Authorize.Net
ordercheckpays.com/api.js?v=3.8 Verisign
ordercheckpays.com/api.js?v=3.9 PayPal
ordercheckpays.com/api.js?v=4.0 Authorize.Net
ordercheckpays.com/api.js?v=4.1 Authorize.Net
ordercheckpays.com/api.js?v=4.2 Salviepenger
ordercheckpays.com/api.js?v=4.3 Authorize.Net
reactjsapi.com/api.js?v=0.1.0 Authorize.Net
reactjsapi.com/api.js?v=0.1.1 PayPal
reactjsapi.com/api.js?v=4.1.2 Flint
reactjsapi.com/api.js?v=4.1.4 PayPal
reactjsapi.com/api.js?v=4.1.5 Salviepenger
reactjsapi.com/api.js?v=4.1.51 Verisign
reactjsapi.com/api.js?v=4.1.6 Authorize.Net
reactjsapi.com/api.js?v=4.1.7 Authorize.Net
reactjsapi.com/api.js?v=4.1.8 Stripe
reactjsapi.com/api.js?v=4.1.9 Feit sebra
reactjsapi.com/api.js?v=4.2.0 Salviepenger
reactjsapi.com/api.js?v=4.2.1 Authorize.Net
reactjsapi.com/api.js?v=4.2.2 Første globale datagateway
reactjsapi.com/api.js?v=4.2.3 Authorize.Net
reactjsapi.com/api.js?v=4.2.4 eWAY Rask
reactjsapi.com/api.js?v=4.2.5 adyen
reactjsapi.com/api.js?v=4.2.7 PayPal
reactjsapi.com/api.js?v=4.2.8 QuickBooks kjøpmannstjenester
reactjsapi.com/api.js?v=4.2.9 Verisign
reactjsapi.com/api.js?v=4.2.91 Salviepenger
reactjsapi.com/api.js?v=4.2.92 Verisign
reactjsapi.com/api.js?v=4.2.94 Authorize.Net
reactjsapi.com/api.js?v=4.3.97 Authorize.Net
reactjsapi.com/api.js?v=4.5 Salviepenger
reactjsapi.com/react.js Authorize.Net
sydneysalonsupplies.com/gtm.js eWAY Rask
tagsmediaget.com/react.js Authorize.Net
tagstracking.com/tag.js?v=2.1.2 ANZ eGate
tagstracking.com/tag.js?v=2.1.3 PayPal
tagstracking.com/tag.js?v=2.1.5 Cyberkilde
tagstracking.com/tag.js?v=2.1.7 Authorize.Net
tagstracking.com/tag.js?v=2.1.8 Salviepenger
tagstracking.com/tag.js?v=2.1.9 Realex
tagstracking.com/tag.js?v=2.2.0 Cyberkilde
tagstracking.com/tag.js?v=2.2.1 PayPal
tagstracking.com/tag.js?v=2.2.2 PayPal
tagstracking.com/tag.js?v=2.2.3 PayPal
tagstracking.com/tag.js?v=2.2.4 Verisign
tagstracking.com/tag.js?v=2.2.5 eWAY Rask
tagstracking.com/tag.js?v=2.2.7 Salviepenger
tagstracking.com/tag.js?v=2.2.8 Salviepenger
tagstracking.com/tag.js?v=2.2.9 Verisign
tagstracking.com/tag.js?v=2.3.0 Authorize.Net
tagstracking.com/tag.js?v=2.3.1 Authorize.Net
tagstracking.com/tag.js?v=2.3.2 Første globale datagateway
tagstracking.com/tag.js?v=2.3.3 Authorize.Net
tagstracking.com/tag.js?v=2.3.4 Authorize.Net
tagstracking.com/tag.js?v=2.3.5 Moneris
tagstracking.com/tag.js?v=2.3.6 Authorize.Net
tagstracking.com/tag.js?v=2.3.8 PayPal

Passordsniffer

En av fordelene med JavaScript-sniffere som jobber på klientsiden av et nettsted, er deres allsidighet: ondsinnet kode som er innebygd på et nettsted kan stjele alle typer data, enten det er betalingsdata eller påloggingsinformasjonen og passordet til en brukerkonto. Group-IB-spesialister oppdaget et utvalg av en sniffer som tilhører ReactGet-familien, designet for å stjele e-postadresser og passord til nettstedsbrukere.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Kryss med ImageID-sniffer

Under analysen av en av de infiserte butikkene, ble det funnet at nettstedet ble infisert to ganger: i tillegg til den ondsinnede koden til ReactGet-familiesnifferen, ble koden til ImageID-familiesnifferen oppdaget. Denne overlappingen kan være bevis på at operatørene bak begge sniffere bruker lignende teknikker for å injisere ondsinnet kode.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Universal sniffer

En analyse av et av domenenavnene knyttet til ReactGet sniffer-infrastrukturen viste at samme bruker hadde registrert tre andre domenenavn. Disse tre domenene imiterte domenene til virkelige nettsteder og ble tidligere brukt til å være vert for sniffere. Ved analyse av koden til tre legitime nettsteder ble det oppdaget en ukjent sniffer, og videre analyse viste at det var en forbedret versjon av ReactGet snifferen. Alle tidligere overvåkede versjoner av denne familien av sniffere var rettet mot et enkelt betalingssystem, det vil si at hvert betalingssystem krevde en spesiell versjon av snifferen. I dette tilfellet ble det imidlertid oppdaget en universell versjon av snifferen som er i stand til å stjele informasjon fra skjemaer relatert til 15 forskjellige betalingssystemer og moduler av e-handelssider for å utføre online betalinger.

Så i begynnelsen av arbeidet søkte snifferen etter grunnleggende skjemafelt som inneholder offerets personlige opplysninger: fullt navn, fysisk adresse, telefonnummer.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Snifferen søkte deretter over 15 forskjellige prefikser som tilsvarer forskjellige betalingssystemer og online betalingsmoduler.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Deretter ble offerets personlige data og betalingsinformasjon samlet inn og sendt til et nettsted kontrollert av angriperen: i dette spesielle tilfellet ble to versjoner av den universelle ReactGet-snifferen oppdaget, plassert på to forskjellige hackede nettsteder. Begge versjonene sendte imidlertid stjålne data til det samme hackede nettstedet zoobashop.com.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Analyse av prefiksene som snifferen brukte for å søke etter felt som inneholder offerets betalingsinformasjon, gjorde at vi kunne fastslå at denne snifferprøven var rettet mot følgende betalingssystemer:

  • Authorize.Net
  • Verisign
  • Første data
  • USAePay
  • Stripe
  • PayPal
  • ANZ eGate
  • Braintree
  • DataCash (MasterCard)
  • Realex-betalinger
  • PsiGate
  • Heartland betalingssystemer

Hvilke verktøy brukes til å stjele betalingsinformasjon?

Det første verktøyet, oppdaget under analysen av angripernes infrastruktur, brukes til å tilsløre ondsinnede skript som er ansvarlige for tyveri av bankkort. Et bash-skript som bruker prosjektets CLI ble oppdaget på en av angriperens verter javascript-obfuscator for å automatisere tilsløring av snifferkode.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Det andre oppdagede verktøyet er designet for å generere kode som er ansvarlig for å laste hovedsnifferen. Dette verktøyet genererer JavaScript-kode som sjekker om brukeren er på betalingssiden ved å søke etter strenger i brukerens nåværende adresse kassen, kurven og så videre, og hvis resultatet er positivt, laster koden hovedsnifferen fra angripernes server. For å skjule ondsinnet aktivitet er alle linjer, inkludert testlinjer for å bestemme betalingssiden, samt en lenke til snifferen, kodet med base64.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Phishing-angrep

En analyse av angripernes nettverksinfrastruktur avdekket at den kriminelle gruppen ofte bruker phishing for å få tilgang til det administrative panelet til målnettbutikken. Angripere registrerer et domene som visuelt ligner på en butikks domene, og distribuerer deretter et falskt Magento-administrasjonspanel påloggingsskjema på det. Hvis det lykkes, vil angriperne få tilgang til det administrative panelet til Magento CMS, som gir dem muligheten til å redigere nettstedkomponenter og implementere en sniffer for å stjele kredittkortdata.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
infrastruktur

Domenenavn Dato for oppdagelse/opptreden
mediapack.info 04.05.2017
adsgetapi.com 15.06.2017
simcounter.com 14.08.2017
mageanalytics.com 22.12.2017
maxstatics.com 16.01.2018
reactjsapi.com 19.01.2018
mxcounter.com 02.02.2018
apitstatus.com 01.03.2018
orderracker.com 20.04.2018
tagstracking.com 25.06.2018
adsapigate.com 12.07.2018
trust-tracker.com 15.07.2018
fbstatspartner.com 02.10.2018
billgetstatus.com 12.10.2018
www.aldenmlilhouse.com 20.10.2018
balletbeautlful.com 20.10.2018
bargalnjunkie.com 20.10.2018
payselector.com 21.10.2018
tagsmediaget.com 02.11.2018
hs-payments.com 16.11.2018
ordercheckpays.com 19.11.2018
geisseie.com 24.11.2018
gtmproc.com 29.11.2018
livegetpay.com 18.12.2018
sydneysalonsupplies.com 18.12.2018
newrelicnet.com 19.12.2018
nr-public.com 03.01.2019
cloudodesc.com 04.01.2019
ajaxstatic.com 11.01.2019
livecheckpay.com 21.01.2019
asianfoodgracer.com 25.01.2019

G-Analytics-familien

Denne familien av sniffere brukes til å stjele kundekort fra nettbutikker. Det aller første domenenavnet som ble brukt av gruppen ble registrert i april 2016, noe som kan tyde på at gruppen startet aktivitet i midten av 2016.

I den nåværende kampanjen bruker gruppen domenenavn som imiterer virkelige tjenester, som Google Analytics og jQuery, og maskerer aktiviteten til sniffere med legitime skript og domenenavn som ligner på legitime. Nettsteder som kjører Magento CMS ble angrepet.

Hvordan G-Analytics implementeres i koden til en nettbutikk

Et særtrekk ved denne familien er bruken av ulike metoder for å stjele brukerbetalingsinformasjon. I tillegg til den klassiske injeksjonen av JavaScript-kode på klientsiden av nettstedet, brukte den kriminelle gruppen også kodeinjeksjonsteknikker på serversiden av nettstedet, nemlig PHP-skript som behandler brukerangitte data. Denne teknikken er farlig fordi den gjør det vanskelig for tredjepartsforskere å oppdage skadelig kode. Group-IB-spesialister oppdaget en versjon av en sniffer innebygd i nettstedets PHP-kode, ved å bruke et domene som en port dittm.org.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
En tidlig versjon av en sniffer ble også oppdaget som bruker samme domene til å samle inn stjålne data dittm.org, men denne versjonen er beregnet for installasjon på klientsiden av en nettbutikk.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Gruppen endret senere taktikk og begynte å fokusere mer på å skjule ondsinnet aktivitet og kamuflasje.

I begynnelsen av 2017 begynte gruppen å bruke domenet jquery-js.com, maskert som et CDN for jQuery: når brukeren går til nettstedet til angripere, blir brukeren omdirigert til et legitimt nettsted jquery.com.

Og i midten av 2018 tok gruppen i bruk domenenavnet g-analytics.com og begynte å skjule snifferens aktiviteter som en legitim Google Analytics-tjeneste.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Versjonsanalyse

Under analysen av domenene som ble brukt til å lagre snifferkode, ble det funnet at nettstedet inneholder et stort antall versjoner, som er forskjellige i nærvær av tilsløring, samt tilstedeværelse eller fravær av uoppnåelig kode lagt til filen for å distrahere oppmerksomheten og skjule ondsinnet kode.

Totalt på siden jquery-js.com Seks versjoner av sniffere ble identifisert. Disse sniffere sender de stjålne dataene til en adresse som ligger på samme nettsted som snifferen selv: hxxps://jquery-js[.]com/latest/jquery.min.js:

  • hxxps://jquery-js[.]com/jquery.min.js
  • hxxps://jquery-js[.]com/jquery.2.2.4.min.js
  • hxxps://jquery-js[.]com/jquery.1.8.3.min.js
  • hxxps://jquery-js[.]com/jquery.1.6.4.min.js
  • hxxps://jquery-js[.]com/jquery.1.4.4.min.js
  • hxxps://jquery-js[.]com/jquery.1.12.4.min.js

Senere domene g-analytics.com, brukt av gruppen i angrep siden midten av 2018, fungerer som et oppbevaringssted for flere sniffere. Totalt ble 16 forskjellige versjoner av snifferen oppdaget. I dette tilfellet var porten for å sende stjålne data forkledd som en lenke til et bildeformat GIF: hxxp://g-analytics[.]com/__utm.gif?v=1&_v=j68&a=98811130&t=pageview&_s=1&sd=24-bit&sr=2560×1440&vp=2145×371&je=0&_u=AACAAEAB~&jid=1841704724&gjid=877686936&cid
= 1283183910.1527732071
:

  • hxxps://g-analytics[.]com/libs/1.0.1/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.10/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.11/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.12/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.13/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.14/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.15/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.16/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.3/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.4/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.5/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.6/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.7/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.8/analytics.js
  • hxxps://g-analytics[.]com/libs/1.0.9/analytics.js
  • hxxps://g-analytics[.]com/libs/analytics.js

Inntektsgenerering av stjålne data

Den kriminelle gruppen tjener penger på de stjålne dataene ved å selge kort gjennom en spesiallaget underjordisk butikk som tilbyr tjenester til kortere. Analyse av domenene brukt av angriperne tillot oss å fastslå det google-analytics.cm ble registrert av samme bruker som domenet cardz.vc. Domene cardz.vc refererer til en butikk som selger stjålne bankkort Cardsurfs (Flysurfs), som ble populær tilbake i tiden med aktiviteten til den underjordiske handelsplattformen AlphaBay som en butikk som selger bankkort stjålet ved hjelp av en sniffer.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Analyserer domenet analytical.is, som ligger på samme server som domenene som brukes av sniffere for å samle inn stjålne data, oppdaget Group-IB-spesialister en fil som inneholder cookie-tyver-logger, som senere ser ut til å ha blitt forlatt av utvikleren. En av oppføringene i loggen inneholdt et domene iozoz.com, som tidligere ble brukt i en av snifferne som var aktive i 2016. Antagelig ble dette domenet tidligere brukt av en angriper for å samle inn kort stjålet ved hjelp av en sniffer. Dette domenet ble registrert på en e-postadresse [e-postbeskyttet], som også ble brukt til å registrere domener cardz.su и cardz.vc, knyttet til kardebutikken Cardsurfs.

Basert på dataene som er innhentet, kan det antas at G-Analytics-familien av sniffere og den underjordiske butikken som selger bankkort Cardsurfs administreres av de samme personene, og butikken brukes til å selge bankkort stjålet ved hjelp av snifferen.

infrastruktur

Domenenavn Dato for oppdagelse/opptreden
iozoz.com 08.04.2016
dittm.org 10.09.2016
jquery-js.com 02.01.2017
g-analytics.com 31.05.2018
google-analytics.is 21.11.2018
analytisk.til 04.12.2018
google-analytics.to 06.12.2018
google-analytics.cm 28.12.2018
analytical.is 28.12.2018
googlc-analytics.cm 17.01.2019

Familien Illum

Illum er en familie av sniffere som brukes til å angripe nettbutikker som kjører Magento CMS. I tillegg til å introdusere ondsinnet kode, bruker operatørene av denne snifferen også introduksjonen av fullverdige falske betalingsformer som sender data til porter kontrollert av angripere.

Ved analyse av nettverksinfrastrukturen som ble brukt av operatørene av denne snifferen, ble det notert et stort antall ondsinnede skript, utnyttelser, falske betalingsformer, samt en samling eksempler med ondsinnede sniffere fra konkurrenter. Basert på informasjon om datoene for utseendet til domenenavnene som brukes av gruppen, kan det antas at kampanjen startet i slutten av 2016.

Hvordan Illum implementeres i koden til en nettbutikk

De første versjonene av snifferen som ble oppdaget, ble innebygd direkte i koden til det kompromitterte nettstedet. De stjålne dataene ble sendt til cdn.illum[.]pw/records.php, ble porten kodet ved hjelp av base64.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Senere ble en pakket versjon av snifferen oppdaget som bruker en annen port - records.nstatistics[.]com/records.php.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Ifølge rapportere Willem de Groot, den samme verten ble brukt i snifferen, som ble implementert på butikkens nettsted, eid av det tyske politiske partiet CSU.

Analyse av angripernes nettside

Group-IB-spesialister oppdaget og analyserte et nettsted som ble brukt av denne kriminelle gruppen til å lagre verktøy og samle inn stjålet informasjon.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Blant verktøyene som ble funnet på angripernes server var skript og utnyttelser for å eskalere privilegier i Linux OS: for eksempel Linux Privilege Escalation Check Script utviklet av Mike Czumak, samt en utnyttelse for CVE-2009-1185.

Angriperne brukte to utnyttelser direkte for å angripe nettbutikker: første i stand til å injisere ondsinnet kode i core_config_data ved å utnytte CVE-2016-4010, andre utnytter en RCE-sårbarhet i plugins for CMS Magento, slik at vilkårlig kode kan kjøres på en sårbar webserver.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Under analysen av serveren ble det også oppdaget forskjellige prøver av sniffere og falske betalingsformer, brukt av angripere for å samle inn betalingsinformasjon fra hackede nettsteder. Som du kan se fra listen nedenfor, ble noen skript laget individuelt for hvert hacket nettsted, mens en universalløsning ble brukt for visse CMS og betalingsgatewayer. For eksempel skript segapay_standart.js и segapay_onpage.js designet for implementering på nettsteder som bruker Sage Pay-betalingsporten.

Liste over skript for ulike betalingsgatewayer

Manus Betalingsporten
sr.illum[.]pw/mjs_special/visiondirect.co.uk.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs_special/topdierenshop.nl.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/tiendalenovo.es.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/pro-bolt.com.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/plae.co.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/ottolenghi.co.uk.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/oldtimecandy.com.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs_special/mylook.ee.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/mjs_special/luluandsky.com.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs_special/julep.com.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/mjs_special/gymcompany.es.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/grotekadoshop.nl.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs_special/fushi.co.uk.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs_special/fareastflora.com.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs_special/compuindia.com.js //request.payrightnow[.]cf/alldata.php
sr.illum[.]pw/mjs/segapay_standart.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/mjs/segapay_onpage.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/mjs/replace_standart.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/mjs/all_inputs.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/mjs/add_inputs_standart.js //request.payrightnow[.]cf/checkpayment.php
sr.illum[.]pw/magento/payment_standart.js //cdn.illum[.]pw/records.php
sr.illum[.]pw/magento/payment_redirect.js //payrightnow[.]cf/?payment=
sr.illum[.]pw/magento/payment_redcrypt.js //payrightnow[.]cf/?payment=
sr.illum[.]pw/magento/payment_forminsite.js //paymentnow[.]tk/?payment=

Vert betaling nå[.]tk, brukt som en port i et manus payment_forminsite.js, ble oppdaget som emneAltnavn i flere sertifikater knyttet til CloudFlare-tjenesten. I tillegg inneholdt programlederen et manus evil.js. Etter navnet på skriptet å dømme, kan det brukes som en del av utnyttelsen av CVE-2016-4010, takket være at det er mulig å injisere ondsinnet kode i bunnteksten på et nettsted som kjører CMS Magento. Verten brukte dette skriptet som en port request.requestnet[.]tkbruker samme sertifikat som verten betaling nå[.]tk.

Falske betalingsskjemaer

Figuren under viser et eksempel på et skjema for inntasting av kortdata. Dette skjemaet ble brukt til å infiltrere en nettbutikk og stjele kortdata.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Følgende figur viser et eksempel på et falskt PayPal-betalingsskjema som ble brukt av angripere for å infiltrere nettsteder med denne betalingsmetoden.
Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
infrastruktur

Domenenavn Dato for oppdagelse/opptreden
cdn.illum.pw 27/11/2016
records.nstatistics.com 06/09/2018
request.payrightnow.cf 25/05/2018
paymentnow.tk 16/07/2017
betalingslinje.tk 01/03/2018
paymentpal.jf 04/09/2017
requestnet.tk 28/06/2017

CoffeeMokko-familien

CoffeMokko-familien av sniffere, designet for å stjele bankkort fra nettbutikkbrukere, har vært i bruk siden minst mai 2017. Antagelig er operatørene av denne familien av sniffere den kriminelle gruppen Group 1, beskrevet av RiskIQ-spesialister i 2016. Nettsteder som kjører CMS-er som Magento, OpenCart, WordPress, osCommerce og Shopify ble angrepet.

Hvordan CoffeMokko implementeres i koden til en nettbutikk

Operatører av denne familien lager unike sniffere for hver infeksjon: snifferfilen ligger i katalogen src eller js på angripernes server. Innlemming i nettstedskoden utføres via en direkte lenke til snifferen.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Snifferkoden hardkoder navnene på skjemafeltene som data må stjeles fra. Snifferen sjekker også om brukeren er på betalingssiden ved å sjekke listen over søkeord med brukerens nåværende adresse.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Noen oppdagede versjoner av snifferen ble tilslørt og inneholdt en kryptert streng der hovedgruppen av ressurser var lagret: den inneholdt navnene på skjemafeltene for ulike betalingssystemer, samt portadressen som de stjålne dataene skulle sendes til.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Den stjålne betalingsinformasjonen ble sendt til et script på angripernes server underveis /savePayment/index.php eller /tr/index.php. Antagelig brukes dette skriptet til å sende data fra porten til hovedserveren, som konsoliderer data fra alle sniffere. For å skjule de overførte dataene, krypteres all betalingsinformasjon til offeret ved hjelp av base64, og så forekommer flere tegnerstatninger:

  • "e"-tegnet erstattes med ":"
  • "w"-symbolet erstattes med "+"
  • "o"-tegnet erstattes med "%"
  • "d"-tegnet erstattes med "#"
  • tegnet "a" erstattes med "-"
  • symbolet "7" erstattes med "^"
  • tegnet "h" erstattes med "_"
  • "T"-symbolet erstattes med "@"
  • tegnet "0" erstattes av "/"
  • "Y"-tegnet erstattes med "*"

Som et resultat av tegnerstatninger kodet ved hjelp av base64 Dataene kan ikke dekodes uten å utføre omvendt konvertering.

Slik ser et fragment av snifferkode ut som ikke er tilsløret:

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Infrastrukturanalyse

I tidlige kampanjer registrerte angripere domenenavn som ligner på legitime nettbutikksider. Domenet deres kan avvike fra det legitime ett etter ett symbol eller et annet TLD. Registrerte domener ble brukt til å lagre snifferkode, en lenke til denne var innebygd i butikkkoden.

Denne gruppen brukte også domenenavn som minner om populære jQuery-plugins (slickjs[.]org for nettsteder som bruker plugin slick.js), betalingsporter (sagecdn[.]org for nettsteder som bruker betalingssystemet Sage Pay).

Senere begynte gruppen å lage domener hvis navn ikke hadde noe å gjøre med butikkens domene eller temaet for butikken.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Hvert domene tilsvarte et nettsted der katalogen ble opprettet /js eller / src. Sniffer-skript ble lagret i denne katalogen: en sniffer for hver ny infeksjon. Snifferen ble innebygd i nettsidekoden via en direkte lenke, men i sjeldne tilfeller endret angripere en av nettsidefilene og la til skadelig kode til den.

Kodeanalyse

Første obfuskasjonsalgoritme

I noen oppdagede prøver av sniffere av denne familien, ble koden tilslørt og inneholdt krypterte data som er nødvendige for at snifferen skal fungere: spesielt sniffer-gateadressen, en liste over betalingsskjemafelt, og i noen tilfeller koden til en falsk betalingsskjema. I koden inne i funksjonen ble ressursene kryptert vha XOR med nøkkelen som ble sendt som et argument til samme funksjon.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Ved å dekryptere strengen med riktig nøkkel, unik for hver prøve, kan du få en streng som inneholder alle strengene fra snifferkoden atskilt med et skilletegn.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Andre obfuskeringsalgoritme

I senere prøver av sniffere av denne familien ble en annen tilsløringsmekanisme brukt: i dette tilfellet ble dataene kryptert ved hjelp av en selvskrevet algoritme. En streng som inneholder krypterte data som er nødvendig for at snifferen skal fungere, ble sendt som et argument til dekrypteringsfunksjonen.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Ved å bruke nettleserkonsollen kan du dekryptere de krypterte dataene og få tak i en matrise som inneholder snifferressurser.

Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene

Tilkobling til tidlige MageCart-angrep

Under analysen av et av domenene som ble brukt av gruppen som en gateway for å samle inn stjålne data, ble det funnet at dette domenet var vert for en infrastruktur for kredittkorttyveri, identisk med den som ble brukt av Group 1, en av de første gruppene, oppdaget av RiskIQ-spesialister.

To filer ble funnet på verten til CoffeMokko-familien av sniffere:

  • mage.js — fil som inneholder gruppe 1 snifferkode med portadresse js-cdn.link
  • mag.php — PHP-skript som er ansvarlig for å samle inn data stjålet av snifferen

Innholdet i mage.js-filen Fire JavaScript-sniffere som ligger og venter på deg i nettbutikkene
Det ble også fastslått at de tidligste domenene som ble brukt av gruppen bak CoffeMokko-familien av sniffere ble registrert 17. mai 2017:

  • link-js[.]link
  • info-js[.]link
  • track-js[.]link
  • map-js[.]link
  • smart-js[.]link

Formatet til disse domenenavnene samsvarer med gruppe 1-domenenavnene som ble brukt i 2016-angrepene.

Basert på de oppdagede fakta kan det antas at det er en sammenheng mellom operatørene av CoffeMokko-snifferene og den kriminelle gruppen Gruppe 1. Antagelig kunne CoffeMokko-operatører ha lånt verktøy og programvare fra sine forgjengere for å stjele kort. Det er imidlertid mer sannsynlig at den kriminelle gruppen bak bruken av CoffeMokko-familien av sniffere er de samme personene som utførte gruppe 1-angrepene. Etter publiseringen av den første rapporten om den kriminelle gruppens aktiviteter, var alle domenenavnene deres. blokkert og verktøyene ble studert i detalj og beskrevet. Gruppen ble tvunget til å ta en pause, avgrense sine interne verktøy og skrive om snifferkode for å fortsette sine angrep og forbli uoppdaget.

infrastruktur

Domenenavn Dato for oppdagelse/opptreden
link-js.link 17.05.2017
info-js.link 17.05.2017
track-js.link 17.05.2017
map-js.link 17.05.2017
smart-js.link 17.05.2017
adorebeauty.org 03.09.2017
security-payment.su 03.09.2017
braincdn.org 04.09.2017
sagecdn.org 04.09.2017
slickjs.org 04.09.2017
oakandfort.org 10.09.2017
citywlnery.org 15.09.2017
dobell.su 04.10.2017
childrensplayclothing.org 31.10.2017
jewsondirect.com 05.11.2017
shop-rnib.org 15.11.2017
closetlondon.org 16.11.2017
misshaus.org 28.11.2017
battery-force.org 01.12.2017
kik-vape.org 01.12.2017
greatfurnituretradingco.org 02.12.2017
etradesupply.org 04.12.2017
replacemyremote.org 04.12.2017
all-about-sneakers.org 05.12.2017
mage-checkout.org 05.12.2017
nililotan.org 07.12.2017
lamoodbighat.net 08.12.2017
walletgear.org 10.12.2017
dahlie.org 12.12.2017
davidsfootwear.org 20.12.2017
blackriverimaging.org 23.12.2017
exrpesso.org 02.01.2018
parks.su 09.01.2018
pmtonline.su 12.01.2018
otocap.org 15.01.2018
christohperward.org 27.01.2018
coffeetea.org 31.01.2018
energycoffe.org 31.01.2018
energytea.org 31.01.2018
teaffe.net 31.01.2018
adaptivecss.org 01.03.2018
coffeemokko.com 01.03.2018
londontea.net 01.03.2018
ukcoffe.com 01.03.2018
labbe.biz 20.03.2018
batterynart.com 03.04.2018
btosports.net 09.04.2018
chicksaddlery.net 16.04.2018
paypaypay.org 11.05.2018
ar500arnor.com 26.05.2018
authorizecdn.com 28.05.2018
slickmin.com 28.05.2018
bannerbuzz.info 03.06.2018
kandypens.net 08.06.2018
mylrendyphone.com 15.06.2018
freshchat.info 01.07.2018
3lift.org 02.07.2018
abtasty.net 02.07.2018
mechat.info 02.07.2018
zoplm.com 02.07.2018
zapaljs.com 02.09.2018
foodandcot.com 15.09.2018
freshdepor.com 15.09.2018
swappastore.com 15.09.2018
verywellfitnesse.com 15.09.2018
elegrina.com 18.11.2018
majsurplus.com 19.11.2018
top5value.com 19.11.2018

Kilde: www.habr.com

Legg til en kommentar