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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
| # ========== 信息收集工具 ==========
import requests
import dns.resolver
import socket
from typing import List, Dict, Set
from urllib.parse import urlparse
import re
class InformationGathering:
"""信息收集"""
def __init__(self, target: str):
self.target = target
self.results = {
'subdomains': set(),
'open_ports': [],
'technologies': [],
'sensitive_files': [],
'emails': set(),
'social_accounts': set()
}
def enumerate_subdomains(self) -> Set[str]:
"""子域名枚举"""
wordlist = [
'www', 'mail', 'ftp', 'admin', 'blog', 'api',
'dev', 'staging', 'test', 'app', 'mobile'
]
for subdomain in wordlist:
domain = f"{subdomain}.{self.target}"
try:
# DNS查询
dns.resolver.resolve(domain, 'A')
self.results['subdomains'].add(domain)
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
continue
return self.results['subdomains']
def scan_ports(self, ports: List[int] = None) -> List[int]:
"""端口扫描"""
if ports is None:
ports = [21, 22, 23, 25, 53, 80, 110, 443, 445, 3306, 3389, 8080]
open_ports = []
for port in ports:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
try:
sock.connect((self.target, port))
open_ports.append(port)
except socket.error:
pass
finally:
sock.close()
self.results['open_ports'] = open_ports
return open_ports
def identify_technologies(self) -> List[str]:
"""技术栈识别"""
url = f"http://{self.target}"
try:
response = requests.get(url, timeout=10)
# 检查响应头
headers = response.headers
technologies = []
# Server头
if 'Server' in headers:
technologies.append(f"Server: {headers['Server']}")
# X-Powered-By头
if 'X-Powered-By' in headers:
technologies.append(f"PoweredBy: {headers['X-Powered-By']}")
# 检查HTML中的技术特征
content = response.text
# WordPress
if 'wp-content' in content:
technologies.append("WordPress")
# jQuery
if 'jquery' in content.lower():
technologies.append("jQuery")
# React
if 'react' in content.lower():
technologies.append("React")
# Vue
if 'vue' in content.lower():
technologies.append("Vue")
self.results['technologies'] = technologies
except requests.RequestException:
pass
return self.results['technologies']
def find_sensitive_files(self) -> List[str]:
"""敏感文件扫描"""
sensitive_paths = [
'/robots.txt',
'/.git/config',
'/.env',
'/wp-config.php',
'/web.config',
'/.htaccess',
'/admin',
'/phpmyadmin',
'/backup.zip',
'/database.sql'
]
found_files = []
for path in sensitive_paths:
url = f"http://{self.target}{path}"
try:
response = requests.get(url, timeout=5)
if response.status_code in [200, 301, 302]:
found_files.append(path)
except requests.RequestException:
continue
self.results['sensitive_files'] = found_files
return found_files
def extract_emails(self) -> Set[str]:
"""提取邮箱地址"""
url = f"http://{self.target}"
try:
response = requests.get(url, timeout=10)
content = response.text
# 邮箱正则
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
emails = set(re.findall(email_pattern, content, re.IGNORECASE))
self.results['emails'] = emails
except requests.RequestException:
pass
return self.results['emails']
def generate_report(self) -> Dict:
"""生成报告"""
return {
'target': self.target,
'subdomains': list(self.results['subdomains']),
'open_ports': self.results['open_ports'],
'technologies': self.results['technologies'],
'sensitive_files': self.results['sensitive_files'],
'emails': list(self.results['emails']),
'social_accounts': list(self.results['social_accounts'])
}
|