3030import requests
3131
3232_VULN_DESCRIPTION = (
33- "The BentoML framework is vulnerable to an insecure deserialization issue that can "
34- "be exploited by sending a single POST request to any valid endpoint of the runner server."
33+ "The BentoML framework is vulnerable to an insecure "
34+ "deserialization issue that can be exploited by sending a single POST "
35+ "request to any valid endpoint of the runner server."
3536 "The impact of this is remote code execution."
3637)
3738_SLEEP_TIME_SEC = 20
4041class Cve202532375Detector (tsunami_plugin .VulnDetector ):
4142 """A TsunamiPlugin that detects RCE on the BentoML target."""
4243
43- def __init__ (self , http_client : HttpClient , payload_generator : PayloadGenerator ):
44+ def __init__ (
45+ self , http_client : HttpClient , payload_generator : PayloadGenerator
46+ ):
4447 self .http_client = http_client
4548 self .payload_generator = payload_generator
4649
4750 def GetPluginDefinition (self ) -> tsunami_plugin .PluginDefinition :
4851 """Defines the PluginDefinition for Cve202532375Detector.
4952
5053 Returns:
51- The PluginDefinition used for the Tsunami engine to identify this plugin.
54+ The PluginDefinition used for the Tsunami engine
55+ to identify this plugin.
5256 """
5357 return tsunami_plugin .PluginDefinition (
5458 info = plugin_representation_pb2 .PluginInfo (
@@ -69,18 +73,20 @@ def Detect(
6973
7074 Args:
7175 target: TargetInfo about BentoML Insecure Deserialization.
72- matched_services: A list of network services whose vulnerabilities could
73- be detected by this plugin. "ppp" for example would be on this list.
76+ matched_services: A list of network services whose vulnerabilities
77+ could be detected by this plugin.
78+ "ppp" for example would be on this list.
7479
7580 Returns:
76- A tsunami_plugin.DetectionReportList for all the vulnerabilities of the
77- scanning target.
81+ A tsunami_plugin.DetectionReportList for all the vulnerabilities
82+ of the scanning target.
7883 """
7984 logging .info ("Cve202532375Detector starts detecting." )
8085 vulnerable_services = [
8186 service
8287 for service in matched_services
83- if self ._IsSupportedService (service ) and self ._IsBentoMlWebService (service )
88+ if self ._IsSupportedService (service )
89+ and self ._IsBentoMlWebService (service )
8490 ]
8591
8692 return detection_pb2 .DetectionReportList (
@@ -98,7 +104,8 @@ def _IsSupportedService(
98104 return (
99105 not network_service .service_name
100106 or network_service_utils .is_web_service (network_service )
101- or network_service_utils .get_service_name (network_service ) == "unknown"
107+ or network_service_utils .get_service_name (network_service )
108+ == "unknown"
102109 or network_service_utils .get_service_name (network_service ) == "ppp"
103110 )
104111
@@ -121,9 +128,20 @@ def _IsServiceVulnerable(
121128 """Check if network service may result in RCE."""
122129
123130 config = pg .PayloadGeneratorConfig (
124- vulnerability_type = pg .PayloadGeneratorConfig .VulnerabilityType .BLIND_RCE ,
125- interpretation_environment = pg .PayloadGeneratorConfig .InterpretationEnvironment .LINUX_SHELL ,
126- execution_environment = pg .PayloadGeneratorConfig .ExecutionEnvironment .EXEC_INTERPRETATION_ENVIRONMENT ,
131+ vulnerability_type = (
132+ pg .PayloadGeneratorConfig .VulnerabilityType .BLIND_RCE
133+ ),
134+ interpretation_environment = (
135+ pg .PayloadGeneratorConfig .InterpretationEnvironment .LINUX_SHELL
136+ ),
137+ execution_environment = (
138+ (
139+ pg
140+ .PayloadGeneratorConfig
141+ .ExecutionEnvironment
142+ .EXEC_INTERPRETATION_ENVIRONMENT
143+ )
144+ ),
127145 )
128146 payload = self .payload_generator .generate (config )
129147 if not payload .get_payload_attributes ().uses_callback_server :
@@ -174,13 +192,14 @@ def _BuildUrl(
174192 ) -> str :
175193 """Build the vulnerable target path for RCE injection."""
176194 if network_service_utils .is_web_service (network_service ):
177- url = network_service_utils .build_web_application_root_url (network_service )
178- else :
179- url = "http://{}/" .format (
180- network_endpoint_utils .to_uri_authority (
181- network_service .network_endpoint
182- ).strip ("/" )
195+ url = network_service_utils .build_web_application_root_url (
196+ network_service
183197 )
198+ else :
199+ authority = network_endpoint_utils .to_uri_authority (
200+ network_service .network_endpoint
201+ ).strip ("/" )
202+ url = f"http://{ authority } /"
184203 return url + vulnerable_path .strip ("/" )
185204
186205 def _BuildDetectionReport (
@@ -193,17 +212,21 @@ def _BuildDetectionReport(
193212 target_info = target ,
194213 network_service = vulnerable_service ,
195214 detection_timestamp = timestamp_pb2 .Timestamp ().GetCurrentTime (),
196- detection_status = detection_pb2 .DetectionStatus .VULNERABILITY_VERIFIED ,
215+ detection_status = (
216+ detection_pb2 .DetectionStatus .VULNERABILITY_VERIFIED
217+ ),
197218 vulnerability = vulnerability_pb2 .Vulnerability (
198219 main_id = vulnerability_pb2 .VulnerabilityId (
199220 publisher = "TSUNAMI_COMMUNITY" , value = "CVE_2025_32375"
200221 ),
201222 severity = vulnerability_pb2 .Severity .CRITICAL ,
202223 title = (
203- "BentoML Insecure Deserialization RCE (CVE-2025-32375) for Runner Server"
224+ "BentoML Insecure Deserialization RCE (CVE-2025-32375) "
225+ "for Runner Server"
204226 ),
205227 recommendation = (
206- "Users should not expose the bentoml Runner Server endpoints to untrusted environments."
228+ "Users should not expose the bentoml Runner Server "
229+ "endpoints to untrusted environments."
207230 ),
208231 description = _VULN_DESCRIPTION ,
209232 ),
0 commit comments