Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
184 commits
Select commit Hold shift + click to select a range
fefc52a
waf_bypass initial
liquidsec Aug 1, 2025
466a2ad
fixing source event bug
liquidsec Aug 4, 2025
7049bff
continued development
liquidsec Aug 6, 2025
2041483
Merge branch 'dev' into waf-bypass
liquidsec Aug 6, 2025
f68de32
adding asn helper test, fixing report
liquidsec Aug 6, 2025
b1e175a
normalizing nomenclature, adding tests
liquidsec Aug 7, 2025
3cd55a6
add meta
liquidsec Aug 11, 2025
c228095
Merge branch 'dev' into waf-bypass
liquidsec Aug 11, 2025
163ea09
output modifications
liquidsec Aug 15, 2025
dee9079
fix debug messages and add ip filter to ip check
liquidsec Aug 15, 2025
9626f28
add preset
liquidsec Aug 15, 2025
cae129d
fix bug when no subnets in asn
liquidsec Aug 18, 2025
53ea0b3
virtualhost overhaul initial
liquidsec Aug 27, 2025
3bf032a
tweak
liquidsec Aug 27, 2025
38d4d2e
virtualhost update major refactor
liquidsec Aug 30, 2025
454d7d1
virtual host another major refactor
liquidsec Sep 2, 2025
f04c486
changes to as_completed
liquidsec Sep 2, 2025
1d16b49
pinned curl
liquidsec Sep 2, 2025
7c32cb1
fix missing arg
liquidsec Sep 2, 2025
3447866
finish rename
liquidsec Sep 2, 2025
0d98531
small refactor
liquidsec Sep 2, 2025
eb93201
fix async handling
liquidsec Sep 3, 2025
84c0f8e
presets and other adjustments
liquidsec Sep 3, 2025
ef1674f
change as_completed to only accept coros
liquidsec Sep 3, 2025
bd51281
starting to back out of debug, more tweaks
liquidsec Sep 4, 2025
d160941
special virtual host only ignore strings
liquidsec Sep 4, 2025
d19f324
add module test
liquidsec Sep 4, 2025
a5847c5
Merge branch 'dev' into virtualhost-upgrade
liquidsec Sep 4, 2025
ba9fcae
typo
liquidsec Sep 4, 2025
951ca41
fix virtual_host event test fixtures
liquidsec Sep 4, 2025
9940355
lint
liquidsec Sep 4, 2025
525481e
yanking debug stuff, polishing
liquidsec Sep 4, 2025
b3757ec
make curl command message debug only
liquidsec Sep 4, 2025
3082880
Merge branch 'dev' into virtualhost-upgrade
liquidsec Sep 4, 2025
f160f00
finish() scan bug fix
liquidsec Sep 4, 2025
978b5cd
go mariners
liquidsec Sep 5, 2025
7def332
as_completed error handling, tests
liquidsec Sep 5, 2025
2ba8318
yet another major refactor
liquidsec Sep 5, 2025
824d35d
i let the clanker try to alphabetize
liquidsec Sep 5, 2025
9fdf579
lint
liquidsec Sep 5, 2025
53512df
fixing test
liquidsec Sep 6, 2025
fbeadc0
adjustments
liquidsec Sep 7, 2025
cbe372d
more refactoring
liquidsec Sep 8, 2025
716652e
error message adjustments
liquidsec Sep 8, 2025
bf978b9
error handling
liquidsec Sep 9, 2025
05505d8
add web.response_similarity web helper
liquidsec Sep 10, 2025
7a24d16
use new response_similarity helper
liquidsec Sep 10, 2025
7f4c445
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Sep 10, 2025
c926393
initial change from merge
liquidsec Sep 10, 2025
6d4c88b
further generalizing comparison helper
liquidsec Sep 10, 2025
f957f5e
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Sep 10, 2025
41aa18c
real asn db url
liquidsec Sep 11, 2025
b147ae5
rework comparison logic to use helper
liquidsec Sep 11, 2025
2ed2296
correct ASN expansion, bug fixes, tests
liquidsec Sep 19, 2025
fafdad1
bugfix
liquidsec Sep 19, 2025
b6aa2a5
fixing tests
liquidsec Sep 19, 2025
bff0b7e
lint
liquidsec Sep 19, 2025
2aa0685
fixing bug
liquidsec Sep 20, 2025
5f01007
fix tests
liquidsec Sep 20, 2025
d5fbae3
fix more tests
liquidsec Sep 20, 2025
30624c6
fixing test
liquidsec Sep 20, 2025
ce16a80
more test fixes, adjustments to prep
liquidsec Sep 20, 2025
4f65a46
fixing slop
liquidsec Sep 22, 2025
d8a5a64
more reworking around the prep() change
liquidsec Sep 22, 2025
3507d00
more test fixing
liquidsec Sep 22, 2025
06b8de5
more test fixes
liquidsec Sep 22, 2025
32efd2e
rate-limit use retry-after
liquidsec Sep 22, 2025
0c43022
more test fixes
liquidsec Sep 22, 2025
ee844c6
use correct method
liquidsec Sep 22, 2025
1b12214
change to new function name
liquidsec Sep 22, 2025
6effa6b
fix asn helper access
liquidsec Sep 22, 2025
80789b0
yet more test fixes
liquidsec Sep 22, 2025
c0f9467
Merge branch 'dev' into virtualhost-upgrade
liquidsec Sep 22, 2025
7a2bc99
yet even still more test fixes
liquidsec Sep 22, 2025
d483997
slightly change waf_bypass detection criteria
liquidsec Sep 22, 2025
8915855
massive test fixes (from prep() changes)
liquidsec Sep 23, 2025
183a6f0
yet even more test fixes still
liquidsec Sep 23, 2025
2d5498e
ruff format
liquidsec Sep 23, 2025
9555205
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Sep 23, 2025
ee03e61
fix even yet more additional tests
liquidsec Sep 23, 2025
aab237a
ugggggggggggggggggggggggggggggg tests
liquidsec Sep 23, 2025
11710ea
test initialize order
liquidsec Sep 23, 2025
40a35c1
another test fix
liquidsec Sep 23, 2025
86b3f03
more test stuff again the sequel
liquidsec Sep 23, 2025
20ef830
even more :(
liquidsec Sep 24, 2025
391155f
test fix
liquidsec Sep 24, 2025
3dec03a
asdf
liquidsec Sep 24, 2025
d455b7c
better large ip_range behavior
liquidsec Sep 24, 2025
df66c25
fixing unknown asn system
liquidsec Sep 25, 2025
eb7f570
change to simhash for comparison
liquidsec Sep 26, 2025
33ef6db
remove debug messages
liquidsec Sep 26, 2025
9576232
debug junk
liquidsec Sep 26, 2025
323284e
add simhash helper
liquidsec Sep 26, 2025
d3a68d5
fixing inefficient seed event class sorting
liquidsec Sep 26, 2025
39bc9fe
remove unnecessary warning
liquidsec Sep 26, 2025
ddc0a9c
DRY
liquidsec Sep 26, 2025
3faf36f
refactor for correct api format
liquidsec Sep 26, 2025
bdce02d
LRU cache, fix rate limiting
liquidsec Sep 26, 2025
db741fb
Merge branch 'waf-bypass' into better-text-compare
liquidsec Sep 26, 2025
5a1a66d
remove debug
liquidsec Sep 26, 2025
a66b012
comments
TheTechromancer Sep 26, 2025
4da27b8
remove per host only
liquidsec Sep 26, 2025
12bf1f9
simhash helper update
liquidsec Sep 27, 2025
f446117
major waf_bypass refactor
liquidsec Sep 27, 2025
321c259
format
liquidsec Sep 27, 2025
6231157
Merge branch 'waf-bypass' into better-text-compare
liquidsec Sep 27, 2025
35bc4b7
Merge pull request #2713 from blacklanternsecurity/better-text-compare
liquidsec Sep 27, 2025
49e724b
Merge branch 'dev' into virtualhost-upgrade
liquidsec Sep 29, 2025
0173e2a
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Sep 29, 2025
cd0c3f9
Merge branch 'dev' into virtualhost-upgrade
liquidsec Oct 9, 2025
635aa4d
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Oct 9, 2025
0cc459d
add virtualhost http_response emittal
liquidsec Oct 15, 2025
ca64515
fix header extraction curl helper
liquidsec Oct 16, 2025
7bb3989
Merge pull request #2738 from blacklanternsecurity/virtualhost-httpre…
liquidsec Oct 16, 2025
15e5eb5
Merge branch 'dev' into virtualhost-upgrade
liquidsec Oct 16, 2025
cf9ae83
Merge branch 'virtualhost-upgrade' into waf-bypass
liquidsec Oct 16, 2025
02129b0
remove unnecessary cache
liquidsec Oct 16, 2025
5147d68
forklifting asn human output code
liquidsec Oct 16, 2025
2863934
clean up duplicate
liquidsec Oct 16, 2025
5cd05d0
more efficient asn report (using helper)
liquidsec Oct 16, 2025
1de5db2
some cleanup
liquidsec Oct 17, 2025
3e03865
Merge pull request #2553 from blacklanternsecurity/waf-bypass
liquidsec Oct 17, 2025
2191c72
temporarility removing new modules
liquidsec Oct 17, 2025
2686341
temporarily remove presets
liquidsec Oct 17, 2025
31c3e12
temp removal
liquidsec Oct 17, 2025
4da2319
Restore virtualhost and WAF bypass modules and tests
liquidsec Oct 17, 2025
5f49ae3
Restore virtualhost/WAF bypass modules and revert web helpers to pre-…
liquidsec Oct 17, 2025
56f5d53
ruff format
liquidsec Oct 17, 2025
1740a28
temporarily revert
liquidsec Oct 17, 2025
05f1cab
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Oct 17, 2025
a7ce13a
just fixing stuff
liquidsec Oct 17, 2025
e8e50e0
more merge stuff
liquidsec Oct 17, 2025
04206e2
fix test again
liquidsec Oct 17, 2025
a94ca10
oops
liquidsec Oct 17, 2025
96658b6
fixing test
liquidsec Oct 17, 2025
6ce1295
temp removal
liquidsec Oct 17, 2025
9f0ab3d
Restore virtualhost and WAF bypass modules and tests
liquidsec Oct 17, 2025
582f4de
rebase
liquidsec Oct 17, 2025
fb20516
just fixing stuff
liquidsec Oct 17, 2025
d634166
oops
liquidsec Oct 17, 2025
80fa122
Merge remote-tracking branch 'refs/remotes/origin/virtualhost-upgrade…
liquidsec Oct 17, 2025
6a1698f
fixing
liquidsec Oct 17, 2025
e7165e8
Merge branch 'dev' into asn-as-targets
liquidsec Nov 21, 2025
b5bcec8
Merge branch 'dev' into asn-as-targets
liquidsec Dec 3, 2025
7e7f76f
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Dec 3, 2025
e8f01da
fix test
liquidsec Dec 3, 2025
2954d4e
add pyopenssl dep
liquidsec Dec 3, 2025
d06a385
fixing next() bug
liquidsec Dec 4, 2025
7c4a91d
untangle cli arg issues
liquidsec Dec 5, 2025
2720cae
ensure a description exists
liquidsec Dec 5, 2025
6554bd9
more adjustments to scan initialization
liquidsec Dec 5, 2025
48f76ba
lint
liquidsec Dec 5, 2025
c2052a4
more early preset handling changes
liquidsec Dec 5, 2025
6b9af37
Merge branch 'dev' into asn-as-targets
liquidsec Dec 5, 2025
b749538
Merge pull request #2810 from blacklanternsecurity/untangle-cli-args
liquidsec Dec 5, 2025
61fc201
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Dec 5, 2025
703d9cb
fixing dev sync merge
liquidsec Jan 19, 2026
e8a8bc4
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Jan 19, 2026
e974572
Merge remote-tracking branch 'origin/dev' into asn-as-targets
liquidsec Feb 18, 2026
d01079d
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Feb 18, 2026
509da46
fix tests
liquidsec Feb 18, 2026
8a1823c
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Feb 18, 2026
a75d639
Merge branch 'dev' into asn-as-targets
liquidsec Feb 19, 2026
741ff20
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Feb 19, 2026
4dcc8ba
Merge branch 'dev' into asn-as-targets
liquidsec Feb 25, 2026
536831c
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Feb 25, 2026
c66d86c
Merge asn-as-targets into virtualhost-upgrade
liquidsec Feb 28, 2026
879eb51
Merge latest asn-as-targets with community.general fix
liquidsec Feb 28, 2026
55850c5
Remove stale test_event_confidence (numeric confidence was removed in…
liquidsec Feb 28, 2026
820b94c
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Mar 2, 2026
f6a8d43
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Mar 3, 2026
fd39c2f
Merge asn-as-targets, fix waf_bypass for radixtarget 4.x and asndb
liquidsec Mar 6, 2026
1ffcfff
Merge branch 'asn-as-targets' into virtualhost-upgrade
liquidsec Mar 20, 2026
ba1e38c
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 20, 2026
6456ff3
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 20, 2026
6bd6e55
Fix await outside async function in test_python_api_validation
liquidsec Mar 20, 2026
9029102
Fix asndb singleton not being reset after cleanup
liquidsec Mar 22, 2026
36c7834
Fix invalid confidence level MODERATE -> MEDIUM in generic_ssrf
liquidsec Mar 22, 2026
98d00ff
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 22, 2026
d453e6b
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 23, 2026
035aacd
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 23, 2026
db03fd1
Merge remote-tracking branch 'origin/3.0' into virtualhost-upgrade
liquidsec Mar 26, 2026
8cc494c
Fix test failures: update modules for naming standardization and Dict…
liquidsec Mar 27, 2026
98abfef
Merge branch '3.0' into virtualhost-upgrade
liquidsec Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bbot/core/helpers/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ def __init__(self, preset):
self.simhash = SimHashHelper()
self._dns = None
self._web = None
self._asn = None
self._cloudcheck = None
self._asn = None
self.config_aware_validators = self.validators.Validators(self)
Expand Down
134 changes: 125 additions & 9 deletions bbot/core/helpers/web/web.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import json
import logging
import re
import warnings
from pathlib import Path
from bs4 import BeautifulSoup
import ipaddress

from bbot.core.engine import EngineClient
from bbot.core.helpers.misc import truncate_filename
Expand Down Expand Up @@ -317,12 +320,12 @@ async def curl(self, *args, **kwargs):
method (str, optional): The HTTP method to use for the request (e.g., 'GET', 'POST').
cookies (dict, optional): A dictionary of cookies to include in the request.
path_override (str, optional): Overrides the request-target to use in the HTTP request line.
head_mode (bool, optional): If True, includes '-I' to fetch headers only. Defaults to None.
raw_body (str, optional): Raw string to be sent in the body of the request.
resolve (dict, optional): Host resolution override as dict with 'host', 'port', 'ip' keys for curl --resolve.
**kwargs: Arbitrary keyword arguments that will be forwarded to the HTTP request function.

Returns:
str: The output of the cURL command.
dict: JSON object with response data and metadata.

Raises:
CurlError: If 'url' is not supplied.
Expand All @@ -336,7 +339,11 @@ async def curl(self, *args, **kwargs):
if not url:
raise CurlError("No URL supplied to CURL helper")

curl_command = ["curl", url, "-s"]
# Use BBOT-specific curl binary
bbot_curl = self.parent_helper.tools_dir / "curl"
if not bbot_curl.exists():
raise CurlError(f"BBOT curl binary not found at {bbot_curl}. Run dependency installation.")
curl_command = [str(bbot_curl), url, "-s"]

raw_path = kwargs.get("raw_path", False)
if raw_path:
Expand Down Expand Up @@ -380,6 +387,12 @@ async def curl(self, *args, **kwargs):
curl_command.append("-m")
curl_command.append(str(timeout))

# mirror the web helper behavior
retries = self.parent_helper.web_config.get("http_retries", 1)
if retries > 0:
curl_command.extend(["--retry", str(retries)])
curl_command.append("--retry-all-errors")

for k, v in headers.items():
if isinstance(v, list):
for x in v:
Expand Down Expand Up @@ -416,17 +429,120 @@ async def curl(self, *args, **kwargs):
curl_command.append("--request-target")
curl_command.append(f"{path_override}")

head_mode = kwargs.get("head_mode", None)
if head_mode:
curl_command.append("-I")

raw_body = kwargs.get("raw_body", None)
if raw_body:
curl_command.append("-d")
curl_command.append(raw_body)
log.verbose(f"Running curl command: {curl_command}")

# --resolve <host>:<port>:<ip>
resolve_dict = kwargs.get("resolve", None)

if resolve_dict is not None:
# Validate "resolve" is a dict
if not isinstance(resolve_dict, dict):
raise CurlError("'resolve' must be a dictionary containing 'host', 'port', and 'ip' keys")

# Extract and validate IP (required)
ip = resolve_dict.get("ip")
if not ip:
raise CurlError("'resolve' dictionary requires an 'ip' value")
try:
ipaddress.ip_address(ip)
except ValueError:
raise CurlError(f"Invalid IP address supplied to 'resolve': {ip}")

# Host, port, and ip must ALL be supplied explicitly
host = resolve_dict.get("host")
if not host:
raise CurlError("'resolve' dictionary requires a 'host' value")

if "port" not in resolve_dict:
raise CurlError("'resolve' dictionary requires a 'port' value")
port = resolve_dict["port"]

try:
port = int(port)
except (TypeError, ValueError):
raise CurlError("'port' supplied to resolve must be an integer")
if port < 1 or port > 65535:
raise CurlError("'port' supplied to resolve must be between 1 and 65535")

# Append the --resolve directive
curl_command.append("--resolve")
curl_command.append(f"{host}:{port}:{ip}")

# Always add JSON --write-out format with separator and capture headers
curl_command.extend(["-D", "-", "-w", "\\n---CURL_METADATA---\\n%{json}"])

log.debug(f"Running curl command: {curl_command}")
output = (await self.parent_helper.run(curl_command)).stdout
return output

# Parse the output to separate headers, content, and metadata
parts = output.split("\n---CURL_METADATA---\n")

# Raise CurlError if separator not found - this indicates a problem with our curl implementation
if len(parts) < 2:
raise CurlError(f"Curl output missing expected separator. Got: {output[:200]}...")

# Headers and content are in the first part, JSON metadata is in the last part
header_content = parts[0]
json_data = parts[-1].strip()

# Split headers from content
header_lines = []
content_lines = []
in_headers = True

for line in header_content.split("\n"):
if in_headers:
if line.strip() == "":
in_headers = False
else:
header_lines.append(line)
else:
content_lines.append(line)

# Parse headers into dictionary
headers_dict = {}
raw_headers = "\n".join(header_lines)

for line in header_lines:
if ":" in line:
key, value = line.split(":", 1)
key = key.strip().lower()
value = value.strip()

# Convert hyphens to underscores to match httpx (projectdiscovery) format
# This ensures consistency with how other modules expect headers
normalized_key = key.replace("-", "_")

if normalized_key in headers_dict:
if isinstance(headers_dict[normalized_key], list):
headers_dict[normalized_key].append(value)
else:
headers_dict[normalized_key] = [headers_dict[normalized_key], value]
else:
headers_dict[normalized_key] = value

response_data = "\n".join(content_lines)

# Raise CurlError if JSON parsing fails - this indicates a problem with curl's %{json} output
try:
metadata = json.loads(json_data)
except json.JSONDecodeError as e:
# Try to fix common malformed JSON issues from curl output
try:
# Fix empty values like "certs":, -> "certs":null,
fixed_json = re.sub(r':"?\s*,', ":null,", json_data)
# Fix trailing commas before closing braces
fixed_json = re.sub(r",\s*}", "}", fixed_json)
metadata = json.loads(fixed_json)
log.debug(f"Fixed malformed JSON from curl: {json_data[:100]}... -> {fixed_json[:100]}...")
except json.JSONDecodeError:
raise CurlError(f"Failed to parse curl JSON metadata: {e}. JSON data: {json_data[:200]}...")

# Combine into final JSON structure
return {"response_data": response_data, "headers": headers_dict, "raw_headers": raw_headers, **metadata}

def beautifulsoup(
self,
Expand Down
25 changes: 25 additions & 0 deletions bbot/core/shared_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,31 @@
},
]

DEP_CURL = [
{
"name": "Download static curl binary (v8.11.0)",
"get_url": {
"url": "https://github.com/moparisthebest/static-curl/releases/download/v8.11.0/curl-amd64",
"dest": "#{BBOT_TOOLS}/curl",
"mode": "0755",
"force": True,
},
},
{
"name": "Ensure curl binary is executable",
"file": {
"path": "#{BBOT_TOOLS}/curl",
"mode": "0755",
},
},
{
"name": "Verify curl binary works",
"command": "#{BBOT_TOOLS}/curl --version",
"register": "curl_version_output",
"changed_when": False,
},
]

DEP_MASSCAN = [
{
"name": "install os deps (Debian)",
Expand Down
Loading
Loading