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
| public class BurpExtender implements IBurpExtender, IScannerCheck {
private IBurpExtenderCallbacks callbacks;
private IExtensionHelpers helpers;
// 定義要檢測的敏感資訊模式
private static final Pattern[] SENSITIVE_PATTERNS = {
Pattern.compile("api[_-]?key[\"']?\\s*[:=]\\s*[\"']?([a-zA-Z0-9]{20,})",
Pattern.CASE_INSENSITIVE),
Pattern.compile("password[\"']?\\s*[:=]\\s*[\"']?([^\"'\\s]+)",
Pattern.CASE_INSENSITIVE),
Pattern.compile("secret[_-]?key[\"']?\\s*[:=]\\s*[\"']?([a-zA-Z0-9]{16,})",
Pattern.CASE_INSENSITIVE)
};
@Override
public void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks) {
this.callbacks = callbacks;
this.helpers = callbacks.getHelpers();
callbacks.setExtensionName("Sensitive Data Scanner");
callbacks.registerScannerCheck(this);
}
@Override
public List<IScanIssue> doPassiveScan(IHttpRequestResponse baseRequestResponse) {
List<IScanIssue> issues = new ArrayList<>();
byte[] response = baseRequestResponse.getResponse();
if (response == null) return null;
IResponseInfo responseInfo = helpers.analyzeResponse(response);
int bodyOffset = responseInfo.getBodyOffset();
String responseBody = new String(Arrays.copyOfRange(response,
bodyOffset, response.length));
// 檢查敏感資訊模式
for (Pattern pattern : SENSITIVE_PATTERNS) {
Matcher matcher = pattern.matcher(responseBody);
if (matcher.find()) {
issues.add(new CustomScanIssue(
baseRequestResponse.getHttpService(),
helpers.analyzeRequest(baseRequestResponse).getUrl(),
new IHttpRequestResponse[] { baseRequestResponse },
"Sensitive Data Exposure",
"Potential sensitive data found: " + matcher.group(0),
"Medium"
));
}
}
return issues.isEmpty() ? null : issues;
}
@Override
public List<IScanIssue> doActiveScan(IHttpRequestResponse baseRequestResponse,
IScannerInsertionPoint insertionPoint) {
// 主動掃描:嘗試注入 payload
List<IScanIssue> issues = new ArrayList<>();
// 測試 SQL 注入
String[] sqlPayloads = {"'", "\"", "' OR '1'='1", "1; DROP TABLE users--"};
for (String payload : sqlPayloads) {
byte[] checkRequest = insertionPoint.buildRequest(payload.getBytes());
IHttpRequestResponse checkResponse = callbacks.makeHttpRequest(
baseRequestResponse.getHttpService(), checkRequest);
if (checkResponse.getResponse() != null) {
String response = new String(checkResponse.getResponse());
// 檢查錯誤訊息
if (response.contains("SQL syntax") ||
response.contains("mysql_fetch") ||
response.contains("ORA-") ||
response.contains("PostgreSQL")) {
issues.add(new CustomScanIssue(
baseRequestResponse.getHttpService(),
helpers.analyzeRequest(baseRequestResponse).getUrl(),
new IHttpRequestResponse[] { checkResponse },
"SQL Injection",
"SQL injection vulnerability detected with payload: " + payload,
"High"
));
break;
}
}
}
return issues.isEmpty() ? null : issues;
}
@Override
public int consolidateDuplicateIssues(IScanIssue existingIssue,
IScanIssue newIssue) {
if (existingIssue.getIssueName().equals(newIssue.getIssueName())) {
return -1; // 保留舊的問題
}
return 0; // 兩個問題都保留
}
}
|