aws-security-mcp 0.4.3 → 0.5.0
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/README.md +18 -9
- package/dist/bin/aws-security-mcp.js +350 -16
- package/dist/bin/aws-security-mcp.js.map +1 -1
- package/dist/src/index.js +350 -16
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -1
package/dist/src/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var VERSION = "0.
|
|
7
|
+
var VERSION = "0.5.0";
|
|
8
8
|
|
|
9
9
|
// src/utils/aws-client.ts
|
|
10
10
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -3733,6 +3733,242 @@ var PatchComplianceFindingsScanner = class {
|
|
|
3733
3733
|
}
|
|
3734
3734
|
};
|
|
3735
3735
|
|
|
3736
|
+
// src/scanners/imdsv2-enforcement.ts
|
|
3737
|
+
import {
|
|
3738
|
+
EC2Client as EC2Client6,
|
|
3739
|
+
DescribeInstancesCommand as DescribeInstancesCommand5
|
|
3740
|
+
} from "@aws-sdk/client-ec2";
|
|
3741
|
+
function makeFinding11(opts) {
|
|
3742
|
+
const severity = severityFromScore(opts.riskScore);
|
|
3743
|
+
return { ...opts, severity, priority: priorityFromSeverity(severity) };
|
|
3744
|
+
}
|
|
3745
|
+
var Imdsv2EnforcementScanner = class {
|
|
3746
|
+
moduleName = "imdsv2_enforcement";
|
|
3747
|
+
async scan(ctx) {
|
|
3748
|
+
const { region, partition, accountId } = ctx;
|
|
3749
|
+
const startMs = Date.now();
|
|
3750
|
+
const findings = [];
|
|
3751
|
+
const warnings = [];
|
|
3752
|
+
try {
|
|
3753
|
+
const client = createClient(EC2Client6, region, ctx.credentials);
|
|
3754
|
+
const instances = [];
|
|
3755
|
+
let nextToken;
|
|
3756
|
+
do {
|
|
3757
|
+
const resp = await client.send(
|
|
3758
|
+
new DescribeInstancesCommand5({
|
|
3759
|
+
Filters: [{ Name: "instance-state-name", Values: ["running"] }],
|
|
3760
|
+
NextToken: nextToken
|
|
3761
|
+
})
|
|
3762
|
+
);
|
|
3763
|
+
if (resp.Reservations) {
|
|
3764
|
+
for (const reservation of resp.Reservations) {
|
|
3765
|
+
if (reservation.Instances) {
|
|
3766
|
+
instances.push(...reservation.Instances);
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
}
|
|
3770
|
+
nextToken = resp.NextToken;
|
|
3771
|
+
} while (nextToken);
|
|
3772
|
+
for (const instance of instances) {
|
|
3773
|
+
const instanceId = instance.InstanceId ?? "unknown";
|
|
3774
|
+
const instanceType = instance.InstanceType ?? "unknown";
|
|
3775
|
+
const state = instance.State?.Name ?? "unknown";
|
|
3776
|
+
const httpTokens = instance.MetadataOptions?.HttpTokens ?? "unknown";
|
|
3777
|
+
const hopLimit = instance.MetadataOptions?.HttpPutResponseHopLimit ?? 1;
|
|
3778
|
+
const instanceArn = `arn:${partition}:ec2:${region}:${accountId}:instance/${instanceId}`;
|
|
3779
|
+
if (httpTokens !== "required") {
|
|
3780
|
+
const description = [
|
|
3781
|
+
`EC2 instance ${instanceId} (type: ${instanceType}, state: ${state}) has HttpTokens set to "${httpTokens}".`,
|
|
3782
|
+
`IMDSv1 is accessible, allowing unauthenticated metadata requests.`
|
|
3783
|
+
];
|
|
3784
|
+
if (hopLimit > 1) {
|
|
3785
|
+
description.push(`HttpPutResponseHopLimit is ${hopLimit} (>1), which may allow containers to reach IMDS.`);
|
|
3786
|
+
}
|
|
3787
|
+
findings.push(
|
|
3788
|
+
makeFinding11({
|
|
3789
|
+
riskScore: 7.5,
|
|
3790
|
+
title: `EC2 instance ${instanceId} does not enforce IMDSv2`,
|
|
3791
|
+
resourceType: "AWS::EC2::Instance",
|
|
3792
|
+
resourceId: instanceId,
|
|
3793
|
+
resourceArn: instanceArn,
|
|
3794
|
+
region,
|
|
3795
|
+
description: description.join(" "),
|
|
3796
|
+
impact: "IMDSv1 allows attackers to steal IAM role credentials via SSRF attacks",
|
|
3797
|
+
remediationSteps: [
|
|
3798
|
+
"Enforce IMDSv2 by setting HttpTokens to 'required'.",
|
|
3799
|
+
"Run: aws ec2 modify-instance-metadata-options --instance-id " + instanceId + " --http-tokens required --http-endpoint enabled",
|
|
3800
|
+
"Set HttpPutResponseHopLimit to 1 unless running containers that need metadata access.",
|
|
3801
|
+
"Update launch templates and Auto Scaling groups to enforce IMDSv2 for new instances."
|
|
3802
|
+
]
|
|
3803
|
+
})
|
|
3804
|
+
);
|
|
3805
|
+
} else if (hopLimit > 1) {
|
|
3806
|
+
warnings.push(
|
|
3807
|
+
`Instance ${instanceId} enforces IMDSv2 but HttpPutResponseHopLimit is ${hopLimit} (>1). Verify this is intentional for containerized workloads.`
|
|
3808
|
+
);
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
return {
|
|
3812
|
+
module: this.moduleName,
|
|
3813
|
+
status: "success",
|
|
3814
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3815
|
+
resourcesScanned: instances.length,
|
|
3816
|
+
findingsCount: findings.length,
|
|
3817
|
+
scanTimeMs: Date.now() - startMs,
|
|
3818
|
+
findings
|
|
3819
|
+
};
|
|
3820
|
+
} catch (err) {
|
|
3821
|
+
return {
|
|
3822
|
+
module: this.moduleName,
|
|
3823
|
+
status: "error",
|
|
3824
|
+
error: err instanceof Error ? err.message : String(err),
|
|
3825
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3826
|
+
resourcesScanned: 0,
|
|
3827
|
+
findingsCount: 0,
|
|
3828
|
+
scanTimeMs: Date.now() - startMs,
|
|
3829
|
+
findings: []
|
|
3830
|
+
};
|
|
3831
|
+
}
|
|
3832
|
+
}
|
|
3833
|
+
};
|
|
3834
|
+
|
|
3835
|
+
// src/scanners/waf-coverage.ts
|
|
3836
|
+
import {
|
|
3837
|
+
ElasticLoadBalancingV2Client,
|
|
3838
|
+
DescribeLoadBalancersCommand
|
|
3839
|
+
} from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
3840
|
+
import {
|
|
3841
|
+
WAFV2Client,
|
|
3842
|
+
GetWebACLForResourceCommand
|
|
3843
|
+
} from "@aws-sdk/client-wafv2";
|
|
3844
|
+
function makeFinding12(opts) {
|
|
3845
|
+
const severity = severityFromScore(opts.riskScore);
|
|
3846
|
+
return { ...opts, severity, priority: priorityFromSeverity(severity) };
|
|
3847
|
+
}
|
|
3848
|
+
var WafCoverageScanner = class {
|
|
3849
|
+
moduleName = "waf_coverage";
|
|
3850
|
+
async scan(ctx) {
|
|
3851
|
+
const { region } = ctx;
|
|
3852
|
+
const startMs = Date.now();
|
|
3853
|
+
const findings = [];
|
|
3854
|
+
const warnings = [];
|
|
3855
|
+
try {
|
|
3856
|
+
const elbClient = createClient(ElasticLoadBalancingV2Client, region, ctx.credentials);
|
|
3857
|
+
const wafClient = createClient(WAFV2Client, region, ctx.credentials);
|
|
3858
|
+
const loadBalancers = [];
|
|
3859
|
+
let marker;
|
|
3860
|
+
do {
|
|
3861
|
+
const resp = await elbClient.send(
|
|
3862
|
+
new DescribeLoadBalancersCommand({ Marker: marker })
|
|
3863
|
+
);
|
|
3864
|
+
if (resp.LoadBalancers) {
|
|
3865
|
+
loadBalancers.push(...resp.LoadBalancers);
|
|
3866
|
+
}
|
|
3867
|
+
marker = resp.NextMarker;
|
|
3868
|
+
} while (marker);
|
|
3869
|
+
const internetFacing = loadBalancers.filter((lb) => lb.Scheme === "internet-facing");
|
|
3870
|
+
for (const lb of internetFacing) {
|
|
3871
|
+
const lbName = lb.LoadBalancerName ?? "unknown";
|
|
3872
|
+
const lbArn = lb.LoadBalancerArn ?? "unknown";
|
|
3873
|
+
const lbType = lb.Type ?? "unknown";
|
|
3874
|
+
if (lbType !== "application") {
|
|
3875
|
+
warnings.push(
|
|
3876
|
+
`Skipping ${lbType} load balancer "${lbName}" \u2014 WAF Web ACL association is only supported for ALBs.`
|
|
3877
|
+
);
|
|
3878
|
+
continue;
|
|
3879
|
+
}
|
|
3880
|
+
try {
|
|
3881
|
+
const wafResp = await wafClient.send(
|
|
3882
|
+
new GetWebACLForResourceCommand({ ResourceArn: lbArn })
|
|
3883
|
+
);
|
|
3884
|
+
if (!wafResp.WebACL) {
|
|
3885
|
+
findings.push(
|
|
3886
|
+
makeFinding12({
|
|
3887
|
+
riskScore: 7.5,
|
|
3888
|
+
title: `Internet-facing ALB ${lbName} has no WAF protection`,
|
|
3889
|
+
resourceType: "AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
3890
|
+
resourceId: lbName,
|
|
3891
|
+
resourceArn: lbArn,
|
|
3892
|
+
region,
|
|
3893
|
+
description: `Internet-facing Application Load Balancer "${lbName}" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,
|
|
3894
|
+
impact: "Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks",
|
|
3895
|
+
remediationSteps: [
|
|
3896
|
+
"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).",
|
|
3897
|
+
"Associate the Web ACL with the ALB using the REGIONAL scope.",
|
|
3898
|
+
"Enable WAF logging for visibility into blocked requests.",
|
|
3899
|
+
"Consider adding rate-based rules to mitigate DDoS at the application layer."
|
|
3900
|
+
]
|
|
3901
|
+
})
|
|
3902
|
+
);
|
|
3903
|
+
}
|
|
3904
|
+
} catch (wafErr) {
|
|
3905
|
+
const errMsg = wafErr instanceof Error ? wafErr.message : String(wafErr);
|
|
3906
|
+
const errName = wafErr instanceof Error ? wafErr.name ?? "" : "";
|
|
3907
|
+
if (errName === "WAFNonexistentItemException") {
|
|
3908
|
+
findings.push(
|
|
3909
|
+
makeFinding12({
|
|
3910
|
+
riskScore: 7.5,
|
|
3911
|
+
title: `Internet-facing ALB ${lbName} has no WAF protection`,
|
|
3912
|
+
resourceType: "AWS::ElasticLoadBalancingV2::LoadBalancer",
|
|
3913
|
+
resourceId: lbName,
|
|
3914
|
+
resourceArn: lbArn,
|
|
3915
|
+
region,
|
|
3916
|
+
description: `Internet-facing Application Load Balancer "${lbName}" does not have a WAF Web ACL associated. Traffic is not inspected for common web exploits.`,
|
|
3917
|
+
impact: "Without WAF, the ALB is exposed to SQL injection, XSS, and other OWASP Top 10 attacks",
|
|
3918
|
+
remediationSteps: [
|
|
3919
|
+
"Create a WAFv2 Web ACL with managed rule groups (e.g., AWSManagedRulesCommonRuleSet).",
|
|
3920
|
+
"Associate the Web ACL with the ALB using the REGIONAL scope.",
|
|
3921
|
+
"Enable WAF logging for visibility into blocked requests.",
|
|
3922
|
+
"Consider adding rate-based rules to mitigate DDoS at the application layer."
|
|
3923
|
+
]
|
|
3924
|
+
})
|
|
3925
|
+
);
|
|
3926
|
+
} else if (errName === "AccessDeniedException" || errName === "WAFInvalidParameterException") {
|
|
3927
|
+
warnings.push(
|
|
3928
|
+
`Could not check WAF for ALB "${lbName}": ${errMsg}. Ensure wafv2:GetWebACLForResource permission is granted.`
|
|
3929
|
+
);
|
|
3930
|
+
} else {
|
|
3931
|
+
warnings.push(`Error checking WAF for ALB "${lbName}": ${errMsg}`);
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
return {
|
|
3936
|
+
module: this.moduleName,
|
|
3937
|
+
status: "success",
|
|
3938
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3939
|
+
resourcesScanned: internetFacing.length,
|
|
3940
|
+
findingsCount: findings.length,
|
|
3941
|
+
scanTimeMs: Date.now() - startMs,
|
|
3942
|
+
findings
|
|
3943
|
+
};
|
|
3944
|
+
} catch (err) {
|
|
3945
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
3946
|
+
const errName = err instanceof Error ? err.name ?? "" : "";
|
|
3947
|
+
if (errName === "AccessDeniedException" || errName === "UnrecognizedClientException") {
|
|
3948
|
+
return {
|
|
3949
|
+
module: this.moduleName,
|
|
3950
|
+
status: "success",
|
|
3951
|
+
warnings: [`WAF coverage check skipped: ${errMsg}`],
|
|
3952
|
+
resourcesScanned: 0,
|
|
3953
|
+
findingsCount: 0,
|
|
3954
|
+
scanTimeMs: Date.now() - startMs,
|
|
3955
|
+
findings: []
|
|
3956
|
+
};
|
|
3957
|
+
}
|
|
3958
|
+
return {
|
|
3959
|
+
module: this.moduleName,
|
|
3960
|
+
status: "error",
|
|
3961
|
+
error: errMsg,
|
|
3962
|
+
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3963
|
+
resourcesScanned: 0,
|
|
3964
|
+
findingsCount: 0,
|
|
3965
|
+
scanTimeMs: Date.now() - startMs,
|
|
3966
|
+
findings: []
|
|
3967
|
+
};
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
};
|
|
3971
|
+
|
|
3736
3972
|
// src/tools/report-tool.ts
|
|
3737
3973
|
var SEVERITY_ICON = {
|
|
3738
3974
|
CRITICAL: "\u{1F534}",
|
|
@@ -4964,13 +5200,13 @@ var SCAN_GROUPS = {
|
|
|
4964
5200
|
mlps3_precheck: {
|
|
4965
5201
|
name: "\u7B49\u4FDD\u4E09\u7EA7\u9884\u68C0",
|
|
4966
5202
|
description: "GB/T 22239-2019 \u7B49\u4FDD\u4E09\u7EA7 AWS \u4E91\u79DF\u6237\u5C42\u914D\u7F6E\u68C0\u67E5",
|
|
4967
|
-
modules: ["service_detection", "secret_exposure", "ssl_certificate", "dns_dangling", "network_reachability", "iam_privilege_escalation", "tag_compliance", "disaster_recovery", "security_hub_findings", "guardduty_findings", "inspector_findings", "trusted_advisor_findings", "config_rules_findings", "access_analyzer_findings", "patch_compliance_findings"],
|
|
5203
|
+
modules: ["service_detection", "secret_exposure", "ssl_certificate", "dns_dangling", "network_reachability", "iam_privilege_escalation", "tag_compliance", "disaster_recovery", "security_hub_findings", "guardduty_findings", "inspector_findings", "trusted_advisor_findings", "config_rules_findings", "access_analyzer_findings", "patch_compliance_findings", "imdsv2_enforcement", "waf_coverage"],
|
|
4968
5204
|
reportType: "mlps3"
|
|
4969
5205
|
},
|
|
4970
5206
|
hw_defense: {
|
|
4971
5207
|
name: "\u62A4\u7F51\u84DD\u961F\u52A0\u56FA",
|
|
4972
5208
|
description: "\u62A4\u7F51\u524D\u5B89\u5168\u81EA\u67E5 \u2014 \u653B\u51FB\u9762+\u5F31\u70B9\u8BC4\u4F30",
|
|
4973
|
-
modules: ["service_detection", "secret_exposure", "network_reachability", "dns_dangling", "ssl_certificate", "iam_privilege_escalation", "security_hub_findings", "guardduty_findings", "inspector_findings", "config_rules_findings", "access_analyzer_findings", "patch_compliance_findings"],
|
|
5209
|
+
modules: ["service_detection", "secret_exposure", "network_reachability", "dns_dangling", "ssl_certificate", "iam_privilege_escalation", "security_hub_findings", "guardduty_findings", "inspector_findings", "config_rules_findings", "access_analyzer_findings", "patch_compliance_findings", "imdsv2_enforcement", "waf_coverage"],
|
|
4974
5210
|
findingsFilter: {
|
|
4975
5211
|
guardDutyTypes: ["Backdoor", "Trojan", "PenTest", "CryptoCurrency"],
|
|
4976
5212
|
minSeverity: "MEDIUM"
|
|
@@ -4979,7 +5215,7 @@ var SCAN_GROUPS = {
|
|
|
4979
5215
|
exposure: {
|
|
4980
5216
|
name: "\u516C\u7F51\u66B4\u9732\u9762\u8BC4\u4F30",
|
|
4981
5217
|
description: "\u8BC4\u4F30\u516C\u7F51\u53EF\u8FBE\u7684\u8D44\u6E90\u548C\u7AEF\u53E3",
|
|
4982
|
-
modules: ["network_reachability", "dns_dangling", "public_access_verify", "ssl_certificate", "security_hub_findings", "access_analyzer_findings"],
|
|
5218
|
+
modules: ["network_reachability", "dns_dangling", "public_access_verify", "ssl_certificate", "security_hub_findings", "access_analyzer_findings", "imdsv2_enforcement", "waf_coverage"],
|
|
4983
5219
|
findingsFilter: {
|
|
4984
5220
|
securityHubCategories: ["network", "public", "exposure", "port"]
|
|
4985
5221
|
}
|
|
@@ -5026,7 +5262,7 @@ var SCAN_GROUPS = {
|
|
|
5026
5262
|
new_account_baseline: {
|
|
5027
5263
|
name: "\u65B0\u8D26\u6237\u57FA\u7EBF\u68C0\u67E5",
|
|
5028
5264
|
description: "\u65B0 AWS \u8D26\u6237\u5B89\u5168\u57FA\u7EBF",
|
|
5029
|
-
modules: ["service_detection", "secret_exposure", "iam_privilege_escalation", "security_hub_findings", "guardduty_findings", "access_analyzer_findings"]
|
|
5265
|
+
modules: ["service_detection", "secret_exposure", "iam_privilege_escalation", "security_hub_findings", "guardduty_findings", "access_analyzer_findings", "imdsv2_enforcement"]
|
|
5030
5266
|
},
|
|
5031
5267
|
aggregation: {
|
|
5032
5268
|
name: "\u5B89\u5168\u670D\u52A1\u805A\u5408",
|
|
@@ -5036,7 +5272,7 @@ var SCAN_GROUPS = {
|
|
|
5036
5272
|
};
|
|
5037
5273
|
|
|
5038
5274
|
// src/resources/index.ts
|
|
5039
|
-
var SECURITY_RULES_CONTENT = `# AWS Security Scan Modules & Rules (
|
|
5275
|
+
var SECURITY_RULES_CONTENT = `# AWS Security Scan Modules & Rules (19 modules)
|
|
5040
5276
|
|
|
5041
5277
|
## 1. Service Detection (service_detection)
|
|
5042
5278
|
Detects which AWS security services are enabled and assesses overall security maturity.
|
|
@@ -5130,6 +5366,21 @@ Checks patch compliance status for SSM-managed instances.
|
|
|
5130
5366
|
- Missing non-security patches \u2192 MEDIUM (5.5).
|
|
5131
5367
|
- Instances without patch data flagged as LOW (3.0) for visibility.
|
|
5132
5368
|
- Includes platform info, missing/failed counts, and last scan time.
|
|
5369
|
+
|
|
5370
|
+
## 18. IMDSv2 Enforcement (imdsv2_enforcement)
|
|
5371
|
+
Checks if EC2 instances enforce IMDSv2 (Instance Metadata Service v2).
|
|
5372
|
+
- Lists all running EC2 instances and checks MetadataOptions.HttpTokens.
|
|
5373
|
+
- **HttpTokens != "required"** \u2014 Risk 7.5: IMDSv1 allows credential theft via SSRF attacks.
|
|
5374
|
+
- Also checks HttpPutResponseHopLimit \u2014 values >1 on containerized workloads noted as warning.
|
|
5375
|
+
- Remediation: Set HttpTokens to "required" via modify-instance-metadata-options.
|
|
5376
|
+
|
|
5377
|
+
## 19. WAF Coverage (waf_coverage)
|
|
5378
|
+
Checks if internet-facing ALBs have WAF Web ACL associated for protection.
|
|
5379
|
+
- Lists all ELBv2 load balancers, filters to internet-facing only.
|
|
5380
|
+
- For each internet-facing ALB, checks WAFv2 Web ACL association.
|
|
5381
|
+
- **No WAF Web ACL** \u2014 Risk 7.5: ALB exposed to SQL injection, XSS, and OWASP Top 10 attacks.
|
|
5382
|
+
- NLBs (L4) are skipped as WAF does not apply \u2014 noted in warnings.
|
|
5383
|
+
- Gracefully handles WAFv2 access denied or unavailable regions.
|
|
5133
5384
|
`;
|
|
5134
5385
|
var RISK_SCORING_CONTENT = `# Risk Scoring Model
|
|
5135
5386
|
|
|
@@ -5194,8 +5445,63 @@ var MODULE_DESCRIPTIONS = {
|
|
|
5194
5445
|
trusted_advisor_findings: "Aggregates security checks from AWS Trusted Advisor \u2014 requires Business or Enterprise Support plan.",
|
|
5195
5446
|
config_rules_findings: "Pulls non-compliant AWS Config Rule evaluation results \u2014 configuration compliance violations across all resource types.",
|
|
5196
5447
|
access_analyzer_findings: "Pulls active IAM Access Analyzer findings \u2014 resources accessible from outside the account (external principals, public access).",
|
|
5197
|
-
patch_compliance_findings: "Checks SSM Patch Manager compliance \u2014 managed instances with missing or failed security and system patches."
|
|
5448
|
+
patch_compliance_findings: "Checks SSM Patch Manager compliance \u2014 managed instances with missing or failed security and system patches.",
|
|
5449
|
+
imdsv2_enforcement: "Checks if EC2 instances enforce IMDSv2 (HttpTokens: required) \u2014 IMDSv1 allows credential theft via SSRF.",
|
|
5450
|
+
waf_coverage: "Checks if internet-facing ALBs have WAF Web ACL associated for protection against common web exploits."
|
|
5198
5451
|
};
|
|
5452
|
+
var HW_DEFENSE_CHECKLIST = `
|
|
5453
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
5454
|
+
\u{1F4CB} \u62A4\u7F51\u884C\u52A8\u8865\u5145\u63D0\u9192\uFF08\u8D85\u51FA\u81EA\u52A8\u5316\u626B\u63CF\u8303\u56F4\uFF09
|
|
5455
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
5456
|
+
|
|
5457
|
+
\u4EE5\u4E0B\u4E8B\u9879\u9700\u8981\u4EBA\u5DE5\u786E\u8BA4\u548C\u6267\u884C\uFF1A
|
|
5458
|
+
|
|
5459
|
+
\u26A0\uFE0F \u5E94\u6025\u9694\u79BB/\u6B62\u8840\u65B9\u6848
|
|
5460
|
+
\u25A1 \u51C6\u5907\u4E13\u7528\u9694\u79BB\u5B89\u5168\u7EC4\uFF08\u65E0 Inbound/Outbound \u89C4\u5219\uFF09
|
|
5461
|
+
\u25A1 \u5236\u5B9A\u5B9E\u4F8B\u9694\u79BB SOP\uFF1A\u544A\u8B66 \u2192 \u6392\u67E5 \u2192 \u5C01\u9501\u653B\u51FBIP \u2192 \u7F51\u7EDC\u9694\u79BB \u2192 \u5B89\u5168\u5904\u7F6E \u2192 \u8BB0\u5F55\u653B\u51FB\u9879
|
|
5462
|
+
\u25A1 \u660E\u786E\u5404\u7CFB\u7EDF\uFF08\u751F\u4EA7\u6838\u5FC3/\u751F\u4EA7\u975E\u6838\u5FC3/\u6D4B\u8BD5/\u5F00\u53D1\uFF09\u7684\u5E94\u6025\u5904\u7F6E\u65B9\u5F0F
|
|
5463
|
+
\u25A1 \u660E\u786E\u5404\u9879\u76EE\u8D26\u6237\u53CA\u8D44\u6E90\u7684\u8D1F\u8D23\u4EBA\u4E0E\u8054\u7CFB\u65B9\u5F0F
|
|
5464
|
+
|
|
5465
|
+
\u26A0\uFE0F \u6D4B\u8BD5/\u5F00\u53D1\u73AF\u5883\u5904\u7F6E
|
|
5466
|
+
\u25A1 \u975E\u6838\u5FC3\u7CFB\u7EDF\u5728\u62A4\u7F51\u671F\u95F4\u5173\u95ED
|
|
5467
|
+
\u25A1 \u6D4B\u8BD5/\u5F00\u53D1\u73AF\u5883\u5173\u95ED\u6216\u4E0E\u751F\u4EA7\u4FDD\u6301\u540C\u7B49\u5B89\u5168\u57FA\u7EBF
|
|
5468
|
+
\u25A1 \u786E\u8BA4\u54EA\u4E9B\u73AF\u5883\u53EF\u4EE5\u7D27\u6025\u5173\u505C\uFF0C\u907F\u514D\u653B\u51FB\u6269\u6563
|
|
5469
|
+
|
|
5470
|
+
\u26A0\uFE0F \u503C\u5B88\u56E2\u961F\u7EC4\u5EFA
|
|
5471
|
+
\u25A1 7\xD724 \u76D1\u63A7\u5FEB\u901F\u54CD\u5E94\u56E2\u961F
|
|
5472
|
+
\u25A1 \u6280\u672F\u4E0E\u98CE\u9669\u5206\u6790\u7EC4
|
|
5473
|
+
\u25A1 \u5B89\u5168\u7B56\u7565\u4E0B\u53D1\u7EC4
|
|
5474
|
+
\u25A1 \u4E1A\u52A1\u54CD\u5E94\u7EC4
|
|
5475
|
+
\u25A1 \u660E\u786E AWS TAM/Support \u8054\u7CFB\u65B9\u5F0F\uFF08ES/EOP \u5BA2\u6237\uFF09
|
|
5476
|
+
|
|
5477
|
+
\u26A0\uFE0F \u51FA\u5165\u7AD9\u8DEF\u5F84\u67B6\u6784\u56FE
|
|
5478
|
+
\u25A1 \u786E\u4FDD\u6240\u6709\u4E92\u8054\u7F51/DX \u4E13\u7EBF\u51FA\u5165\u7AD9\u8DEF\u5F84\u5728\u67B6\u6784\u56FE\u4E2D\u6E05\u6670\u6807\u6CE8
|
|
5479
|
+
\u25A1 \u660E\u786E\u5404 ELB/Public EC2/S3/DX \u7684\u6570\u636E\u6D41\u5411
|
|
5480
|
+
\u25A1 \u8BC6\u522B\u6240\u6709\u9762\u5411\u4E92\u8054\u7F51\u7684\u6570\u636E\u4EA4\u4E92\u63A5\u53E3
|
|
5481
|
+
|
|
5482
|
+
\u26A0\uFE0F \u4E3B\u52A8\u5F0F\u6E17\u900F\u6D4B\u8BD5
|
|
5483
|
+
\u25A1 \u62A4\u7F51\u524D\u8054\u7CFB\u5B89\u5168\u5382\u5546\uFF08\u9752\u85E4/\u957F\u4EAD/\u5FAE\u6B65\u7B49\uFF09\u8FDB\u884C\u6A21\u62DF\u653B\u51FB\u6F14\u7EC3
|
|
5484
|
+
\u25A1 \u57FA\u4E8E\u6E17\u900F\u6D4B\u8BD5\u62A5\u544A\u8FDB\u884C\u6B63\u5F0F\u62A4\u7F51\u524D\u7684\u5B89\u5168\u52A0\u56FA
|
|
5485
|
+
\u25A1 \u5173\u6CE8 AWS \u5B89\u5168\u516C\u544A\uFF08\u5DF2\u77E5\u6F0F\u6D1E\u4E0E\u8865\u4E01\uFF09
|
|
5486
|
+
|
|
5487
|
+
\u26A0\uFE0F WAR-ROOM \u5B9E\u65F6\u6C9F\u901A
|
|
5488
|
+
\u25A1 \u521B\u5EFA\u62A4\u7F51\u671F\u95F4\u4E13\u7528\u6C9F\u901A\u6E20\u9053\uFF08\u4F01\u5FAE/\u9489\u9489/\u98DE\u4E66/Chime\uFF09
|
|
5489
|
+
\u25A1 \u4E0E AWS TAM \u5EFA\u7ACB WAR-ROOM \u8054\u7CFB\uFF08\u4F01\u4E1A\u7EA7\u652F\u6301\u5BA2\u6237\uFF09
|
|
5490
|
+
\u25A1 \u7EDF\u4E00\u6848\u4F8B\u6807\u9898\u683C\u5F0F\uFF1A"\u3010\u62A4\u7F51\u3011+ \u95EE\u9898\u63CF\u8FF0"
|
|
5491
|
+
|
|
5492
|
+
\u26A0\uFE0F \u5BC6\u7801\u4E0E\u51ED\u8BC1\u7BA1\u7406
|
|
5493
|
+
\u25A1 \u6240\u6709 IAM \u7528\u6237\u7ED1\u5B9A MFA
|
|
5494
|
+
\u25A1 AKSK \u8F6E\u8F6C\u5468\u671F \u2264 90 \u5929
|
|
5495
|
+
\u25A1 \u907F\u514D\u5171\u4EAB\u8D26\u6237\u4F7F\u7528
|
|
5496
|
+
\u25A1 S3/Lambda/\u5E94\u7528\u4EE3\u7801\u4E2D\u65E0\u660E\u6587\u5BC6\u7801
|
|
5497
|
+
|
|
5498
|
+
\u26A0\uFE0F \u62A4\u7F51\u540E\u4F18\u5316
|
|
5499
|
+
\u25A1 \u9488\u5BF9\u653B\u51FB\u62A5\u544A\u9010\u9879\u5E94\u7B54\u4E0E\u4FEE\u590D
|
|
5500
|
+
\u25A1 \u4E0E\u5B89\u5168\u56E2\u961F\u5EFA\u7ACB\u5468\u671F\u6027\u5B89\u5168\u7EF4\u62A4\u6D41\u7A0B
|
|
5501
|
+
\u25A1 \u6301\u7EED\u8865\u5168\u5B89\u5168\u98CE\u9669
|
|
5502
|
+
|
|
5503
|
+
\u53C2\u8003\uFF1AAWS \u62A4\u7F51\u884C\u52A8 Standard Operation Procedure (Compliance IEM)
|
|
5504
|
+
`;
|
|
5199
5505
|
function summarizeResult(result) {
|
|
5200
5506
|
const { summary } = result;
|
|
5201
5507
|
const lines = [
|
|
@@ -5246,7 +5552,9 @@ function createServer(defaultRegion) {
|
|
|
5246
5552
|
new TrustedAdvisorFindingsScanner(),
|
|
5247
5553
|
new ConfigRulesFindingsScanner(),
|
|
5248
5554
|
new AccessAnalyzerFindingsScanner(),
|
|
5249
|
-
new PatchComplianceFindingsScanner()
|
|
5555
|
+
new PatchComplianceFindingsScanner(),
|
|
5556
|
+
new Imdsv2EnforcementScanner(),
|
|
5557
|
+
new WafCoverageScanner()
|
|
5250
5558
|
];
|
|
5251
5559
|
const scannerMap = /* @__PURE__ */ new Map();
|
|
5252
5560
|
for (const s of allScanners) {
|
|
@@ -5302,7 +5610,9 @@ function createServer(defaultRegion) {
|
|
|
5302
5610
|
{ toolName: "scan_trusted_advisor_findings", moduleName: "trusted_advisor_findings", label: "Trusted Advisor Findings" },
|
|
5303
5611
|
{ toolName: "scan_config_rules_findings", moduleName: "config_rules_findings", label: "Config Rules Findings" },
|
|
5304
5612
|
{ toolName: "scan_access_analyzer_findings", moduleName: "access_analyzer_findings", label: "Access Analyzer Findings" },
|
|
5305
|
-
{ toolName: "scan_patch_compliance_findings", moduleName: "patch_compliance_findings", label: "Patch Compliance Findings" }
|
|
5613
|
+
{ toolName: "scan_patch_compliance_findings", moduleName: "patch_compliance_findings", label: "Patch Compliance Findings" },
|
|
5614
|
+
{ toolName: "scan_imdsv2_enforcement", moduleName: "imdsv2_enforcement", label: "IMDSv2 Enforcement" },
|
|
5615
|
+
{ toolName: "scan_waf_coverage", moduleName: "waf_coverage", label: "WAF Coverage" }
|
|
5306
5616
|
];
|
|
5307
5617
|
for (const { toolName, moduleName, label } of individualScanners) {
|
|
5308
5618
|
server.tool(
|
|
@@ -5425,12 +5735,17 @@ function createServer(defaultRegion) {
|
|
|
5425
5735
|
lines.push("");
|
|
5426
5736
|
lines.push(`Warning: ${missingModules.length} requested module(s) not available: ${missingModules.join(", ")}`);
|
|
5427
5737
|
}
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5738
|
+
const content = [
|
|
5739
|
+
{ type: "text", text: lines.join("\n") },
|
|
5740
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
5741
|
+
];
|
|
5742
|
+
if (group === "hw_defense") {
|
|
5743
|
+
const summaryContent = content[0];
|
|
5744
|
+
if (summaryContent && summaryContent.type === "text") {
|
|
5745
|
+
summaryContent.text += "\n\n" + HW_DEFENSE_CHECKLIST;
|
|
5746
|
+
}
|
|
5747
|
+
}
|
|
5748
|
+
return { content };
|
|
5434
5749
|
} catch (err) {
|
|
5435
5750
|
return { content: [{ type: "text", text: `Error: ${err instanceof Error ? err.message : String(err)}` }], isError: true };
|
|
5436
5751
|
}
|
|
@@ -5734,7 +6049,7 @@ Deploy this as a StackSet from your Management Account to all member accounts.`
|
|
|
5734
6049
|
server.resource(
|
|
5735
6050
|
"security-rules",
|
|
5736
6051
|
"security://rules",
|
|
5737
|
-
{ description: "Describes all
|
|
6052
|
+
{ description: "Describes all 19 scan modules and their check rules", mimeType: "text/markdown" },
|
|
5738
6053
|
async () => ({
|
|
5739
6054
|
contents: [{ uri: "security://rules", text: SECURITY_RULES_CONTENT, mimeType: "text/markdown" }]
|
|
5740
6055
|
})
|
|
@@ -5781,6 +6096,25 @@ ${finding}`
|
|
|
5781
6096
|
]
|
|
5782
6097
|
})
|
|
5783
6098
|
);
|
|
6099
|
+
server.prompt(
|
|
6100
|
+
"hw_defense_checklist",
|
|
6101
|
+
"\u62A4\u7F51\u884C\u52A8\u5B8C\u6574\u68C0\u67E5\u6E05\u5355 \u2014 \u5305\u542B\u81EA\u52A8\u5316\u626B\u63CF\u9879\u548C\u4EBA\u5DE5\u68C0\u67E5\u9879",
|
|
6102
|
+
async () => ({
|
|
6103
|
+
messages: [
|
|
6104
|
+
{
|
|
6105
|
+
role: "user",
|
|
6106
|
+
content: {
|
|
6107
|
+
type: "text",
|
|
6108
|
+
text: `\u8BF7\u57FA\u4E8E\u4EE5\u4E0B\u62A4\u7F51\u884C\u52A8\u68C0\u67E5\u6E05\u5355\uFF0C\u5E2E\u52A9\u6211\u5236\u5B9A\u62A4\u7F51\u51C6\u5907\u8BA1\u5212\uFF1A
|
|
6109
|
+
|
|
6110
|
+
${HW_DEFENSE_CHECKLIST}
|
|
6111
|
+
|
|
6112
|
+
\u81EA\u52A8\u5316\u626B\u63CF\u90E8\u5206\u8BF7\u4F7F\u7528 scan_group hw_defense \u6267\u884C\u3002\u4EE5\u4E0A\u4EBA\u5DE5\u68C0\u67E5\u9879\u8BF7\u9010\u9879\u786E\u8BA4\u5E76\u63D0\u4F9B\u5177\u4F53\u5EFA\u8BAE\u3002`
|
|
6113
|
+
}
|
|
6114
|
+
}
|
|
6115
|
+
]
|
|
6116
|
+
})
|
|
6117
|
+
);
|
|
5784
6118
|
return server;
|
|
5785
6119
|
}
|
|
5786
6120
|
async function startServer(defaultRegion) {
|