Skip to content

Commit 08cc81e

Browse files
committed
[Shodan] Update custom query contract
1 parent a1aceed commit 08cc81e

File tree

4 files changed

+13
-33
lines changed

4 files changed

+13
-33
lines changed

shodan/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,13 @@ Direct values separated by commas or spaces between IP addresses or hostnames ar
266266
| Hostname | Yes | / |
267267
| Organization | No | If empty, the hostname value is used. |
268268

269-
- Custom Query (Endpoint: `your custom endpoint`)
270-
- See the Shodan documentation: https://developer.shodan.io/api
269+
- Custom Query (Search Shodan Endpoint: `/shodan/host/search` + your custom query)
270+
- You can find all available filters here: https://beta.shodan.io/search/filters
271+
- Note that spaces and commas are important. You must use the same formatting as in the Shodan search bar.
272+
- `Spaces = AND` / `Commas = OR`
271273

272274
| Field | Mandatory | Default / Notes |
273275
|--------------|-----------|-----------------------------------------|
274-
| HTTP Method | Yes | `GET` (choices: GET, POST, PUT, DELETE) |
275276
| Custom Query | Yes | / |
276277

277278
- CVE Enumeration (Search Shodan Endpoint: `/shodan/host/search`)

shodan/shodan/contracts/custom_query/contract.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,6 @@ def contract_with_specific_fields(
131131
manual_target_selector = [target_selector_field.MANUAL.key]
132132

133133
specific_fields = [
134-
ContractSelect(
135-
key="http_method",
136-
label="HTTP Method",
137-
defaultValue=["get"],
138-
choices={
139-
"get": "GET",
140-
"post": "POST",
141-
"put": "PUT",
142-
"delete": "DELETE",
143-
},
144-
**cls._build_conditions(
145-
source_selector=source_selector_key,
146-
target_selector=manual_target_selector,
147-
),
148-
),
149134
ContractText(
150135
key="custom_query",
151136
label="Custom Query",

shodan/shodan/models/normalize_input_data.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ def parse_vulnerability(cls, values):
5454

5555
class CustomQuery(InjectContent):
5656
contract: Literal["custom_query"]
57-
http_method: str
5857
custom_query: str
5958

6059

shodan/shodan/services/client_api.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ def _process_request(
133133
request_api: ShodanRestAPI | None,
134134
filters_template: dict[str, FilterDefinition] | None = None,
135135
is_custom_query: bool = False,
136-
http_method_custom_query: str | None = None,
137136
) -> Union[dict[str, Any], Any]:
138137
"""Sends a request to Shodan for the given targets and filters, handling retries and errors.
139138
This method constructs the query URL, applies optional filters, encodes it, and calls "_request_data".
@@ -143,26 +142,22 @@ def _process_request(
143142
request_api (ShodanRestAPI | None): The API endpoint definition to use.
144143
filters_template (dict[str, FilterDefinition] | None): Optional filters to apply to the query.
145144
is_custom_query (bool): Whether this is a custom query bypassing standard contract endpoints.
146-
http_method_custom_query (str | None): HTTP method to use for a custom query.
147145
148146
Returns:
149147
Union[dict[str, Any], Any]: Either a structured dictionary with targets and results, or the raw API
150148
response for special queries.
151149
"""
152150

153-
targets = [raw_input] if is_custom_query else raw_input
154-
http_method = (
155-
http_method_custom_query
156-
if is_custom_query
157-
else request_api.value.http_method
158-
)
159-
endpoint_template = raw_input if is_custom_query else request_api.value.endpoint
151+
targets = raw_input
152+
http_method = request_api.value.http_method
153+
154+
endpoint_template = request_api.value.endpoint
160155

161156
result = None
162157
results = []
163158
for target in targets:
164159
new_endpoint = endpoint_template
165-
query_params = None
160+
query_params = target if is_custom_query else None
166161
encoded_for_shodan = None
167162

168163
if filters_template:
@@ -305,12 +300,12 @@ def _execute_contract(
305300
resolved_targets = getattr(inject_content, target_field, None)
306301

307302
if inject_content.contract == "custom_query":
303+
resolved_targets = [f"query={inject_content.custom_query}"]
304+
308305
return self._process_request(
309-
raw_input=inject_content.custom_query,
310-
request_api=None,
311-
filters_template=None,
306+
raw_input=resolved_targets,
307+
request_api=ShodanRestAPI.SEARCH_SHODAN,
312308
is_custom_query=True,
313-
http_method_custom_query=inject_content.http_method,
314309
)
315310
else:
316311
target_property_selector = inject_content.target_property_selector

0 commit comments

Comments
 (0)