ai_root_shield 0.1.0 → 0.3.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.
@@ -0,0 +1,359 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+ require "fiddle"
5
+
6
+ module AiRootShield
7
+ # Runtime Application Self-Protection (RASP) system
8
+ # Provides real-time protection against debugging, tampering, and injection attacks
9
+ class RaspProtection
10
+ # RASP event types for real-time reporting
11
+ RASP_EVENTS = {
12
+ debug_attempt: "DEBUG_ATTEMPT_DETECTED",
13
+ tamper_detected: "CODE_TAMPER_DETECTED",
14
+ injection_blocked: "INJECTION_ATTEMPT_BLOCKED",
15
+ integrity_violation: "INTEGRITY_VIOLATION_DETECTED",
16
+ memory_patch: "MEMORY_PATCH_DETECTED"
17
+ }.freeze
18
+
19
+ def initialize(config = {})
20
+ @config = {
21
+ enable_anti_debug: true,
22
+ enable_anti_tamper: true,
23
+ enable_memory_protection: true,
24
+ enable_integrity_monitor: true,
25
+ enable_real_time_alerts: true,
26
+ alert_callback: nil,
27
+ critical_functions: [],
28
+ protection_interval: 1.0
29
+ }.merge(config)
30
+
31
+ @event_callbacks = []
32
+ @protection_active = false
33
+ @integrity_hashes = {}
34
+ @original_memory_maps = {}
35
+ @protection_thread = nil
36
+ @last_check_time = Time.now
37
+
38
+ initialize_protection if @config[:enable_real_time_alerts]
39
+ end
40
+
41
+ # Start RASP protection monitoring
42
+ def start_protection
43
+ return if @protection_active
44
+
45
+ @protection_active = true
46
+
47
+ # Initialize anti-debug protection
48
+ setup_anti_debug_protection if @config[:enable_anti_debug]
49
+
50
+ # Initialize anti-tamper protection
51
+ setup_anti_tamper_protection if @config[:enable_anti_tamper]
52
+
53
+ # Initialize memory protection
54
+ setup_memory_protection if @config[:enable_memory_protection]
55
+
56
+ # Initialize integrity monitoring
57
+ setup_integrity_monitoring if @config[:enable_integrity_monitor]
58
+
59
+ # Start real-time monitoring thread
60
+ start_monitoring_thread
61
+
62
+ report_rasp_event(:protection_started, "RASP protection activated")
63
+ end
64
+
65
+ # Stop RASP protection monitoring
66
+ def stop_protection
67
+ @protection_active = false
68
+ @protection_thread&.kill
69
+ @protection_thread = nil
70
+
71
+ report_rasp_event(:protection_stopped, "RASP protection deactivated")
72
+ end
73
+
74
+ # Register callback for RASP events
75
+ def on_rasp_event(&block)
76
+ @event_callbacks << block if block_given?
77
+ end
78
+
79
+ # Check current protection status
80
+ def protection_status
81
+ {
82
+ active: @protection_active,
83
+ anti_debug_enabled: @config[:enable_anti_debug],
84
+ anti_tamper_enabled: @config[:enable_anti_tamper],
85
+ memory_protection_enabled: @config[:enable_memory_protection],
86
+ integrity_monitor_enabled: @config[:enable_integrity_monitor],
87
+ events_detected: @events_detected || 0,
88
+ last_check: @last_check_time
89
+ }
90
+ end
91
+
92
+ private
93
+
94
+ def initialize_protection
95
+ @events_detected = 0
96
+ @last_check_time = Time.now
97
+ end
98
+
99
+ # Anti-Debug Protection Implementation
100
+ def setup_anti_debug_protection
101
+ # Check for ptrace attachment
102
+ check_ptrace_protection
103
+
104
+ # Check for debugger processes
105
+ check_debugger_processes
106
+
107
+ # Check for debug environment variables
108
+ check_debug_environment
109
+ end
110
+
111
+ def check_ptrace_protection
112
+ # Attempt to detect ptrace attachment
113
+ if ptrace_detected?
114
+ report_rasp_event(:debug_attempt, "Ptrace debugger attachment detected")
115
+ take_protection_action(:debug_attempt)
116
+ end
117
+ end
118
+
119
+ def ptrace_detected?
120
+ # Check /proc/self/status for TracerPid on Linux
121
+ return false unless File.exist?("/proc/self/status")
122
+
123
+ status_content = File.read("/proc/self/status")
124
+ tracer_line = status_content.lines.find { |line| line.start_with?("TracerPid:") }
125
+
126
+ if tracer_line
127
+ tracer_pid = tracer_line.split(":")[1].strip.to_i
128
+ return tracer_pid != 0
129
+ end
130
+
131
+ false
132
+ rescue
133
+ false
134
+ end
135
+
136
+ def check_debugger_processes
137
+ debugger_processes = ["gdb", "lldb", "strace", "ltrace", "frida-server", "frida"]
138
+
139
+ debugger_processes.each do |debugger|
140
+ if process_running?(debugger)
141
+ report_rasp_event(:debug_attempt, "Debugger process detected: #{debugger}")
142
+ take_protection_action(:debug_attempt)
143
+ end
144
+ end
145
+ end
146
+
147
+ def process_running?(process_name)
148
+ `pgrep #{process_name}`.strip.length > 0
149
+ rescue
150
+ false
151
+ end
152
+
153
+ def check_debug_environment
154
+ debug_vars = ["DEBUG", "LLDB_DEBUGSERVER_PATH", "DYLD_INSERT_LIBRARIES"]
155
+
156
+ debug_vars.each do |var|
157
+ if ENV[var]
158
+ report_rasp_event(:debug_attempt, "Debug environment variable detected: #{var}")
159
+ take_protection_action(:debug_attempt)
160
+ end
161
+ end
162
+ end
163
+
164
+ # Anti-Tamper Protection Implementation
165
+ def setup_anti_tamper_protection
166
+ # Calculate initial code integrity hashes
167
+ calculate_code_integrity_hashes
168
+
169
+ # Monitor for code modifications
170
+ monitor_code_integrity
171
+ end
172
+
173
+ def calculate_code_integrity_hashes
174
+ # Hash critical Ruby files and libraries
175
+ critical_files = [
176
+ __FILE__,
177
+ File.join(__dir__, "detector.rb"),
178
+ File.join(__dir__, "ai_behavioral_analyzer.rb")
179
+ ]
180
+
181
+ critical_files.each do |file|
182
+ next unless File.exist?(file)
183
+
184
+ content = File.read(file)
185
+ @integrity_hashes[file] = Digest::SHA256.hexdigest(content)
186
+ end
187
+ end
188
+
189
+ def monitor_code_integrity
190
+ @integrity_hashes.each do |file, original_hash|
191
+ next unless File.exist?(file)
192
+
193
+ current_content = File.read(file)
194
+ current_hash = Digest::SHA256.hexdigest(current_content)
195
+
196
+ if current_hash != original_hash
197
+ report_rasp_event(:tamper_detected, "Code integrity violation: #{file}")
198
+ take_protection_action(:tamper_detected)
199
+ end
200
+ end
201
+ rescue
202
+ # File access errors might indicate tampering
203
+ report_rasp_event(:tamper_detected, "File access anomaly detected")
204
+ end
205
+
206
+ # Memory Protection Implementation
207
+ def setup_memory_protection
208
+ # Monitor for Frida injection signatures
209
+ check_frida_injection
210
+
211
+ # Monitor memory patches
212
+ monitor_memory_patches
213
+ end
214
+
215
+ def check_frida_injection
216
+ frida_indicators = [
217
+ "frida",
218
+ "gum-js-loop",
219
+ "gmain",
220
+ "glib-",
221
+ "FridaGadget"
222
+ ]
223
+
224
+ # Check loaded libraries for Frida signatures
225
+ if maps_content = read_proc_maps
226
+ frida_indicators.each do |indicator|
227
+ if maps_content.include?(indicator)
228
+ report_rasp_event(:injection_blocked, "Frida injection detected: #{indicator}")
229
+ take_protection_action(:injection_blocked)
230
+ end
231
+ end
232
+ end
233
+ end
234
+
235
+ def read_proc_maps
236
+ File.read("/proc/self/maps") if File.exist?("/proc/self/maps")
237
+ rescue
238
+ nil
239
+ end
240
+
241
+ def monitor_memory_patches
242
+ # Check for suspicious memory modifications
243
+ if maps_content = read_proc_maps
244
+ # Look for executable memory regions that shouldn't be there
245
+ suspicious_regions = maps_content.lines.select do |line|
246
+ line.include?("rwxp") && !line.include?("[stack]") && !line.include?("[heap]")
247
+ end
248
+
249
+ unless suspicious_regions.empty?
250
+ report_rasp_event(:memory_patch, "Suspicious executable memory regions detected")
251
+ take_protection_action(:memory_patch)
252
+ end
253
+ end
254
+ end
255
+
256
+ # Runtime Integrity Monitor Implementation
257
+ def setup_integrity_monitoring
258
+ # Monitor critical function integrity
259
+ monitor_critical_functions
260
+ end
261
+
262
+ def monitor_critical_functions
263
+ @config[:critical_functions].each do |function_info|
264
+ validate_function_integrity(function_info)
265
+ end
266
+ end
267
+
268
+ def validate_function_integrity(function_info)
269
+ # Validate function hash if provided
270
+ if function_info[:hash] && function_info[:method]
271
+ current_hash = calculate_method_hash(function_info[:method])
272
+
273
+ if current_hash != function_info[:hash]
274
+ report_rasp_event(:integrity_violation,
275
+ "Critical function integrity violation: #{function_info[:method]}")
276
+ take_protection_action(:integrity_violation)
277
+ end
278
+ end
279
+ end
280
+
281
+ def calculate_method_hash(method_obj)
282
+ # Calculate hash of method source if available
283
+ if method_obj.respond_to?(:source)
284
+ Digest::SHA256.hexdigest(method_obj.source)
285
+ else
286
+ # Fallback to method object hash
287
+ Digest::SHA256.hexdigest(method_obj.to_s)
288
+ end
289
+ rescue
290
+ nil
291
+ end
292
+
293
+ # Real-time Monitoring Thread
294
+ def start_monitoring_thread
295
+ @protection_thread = Thread.new do
296
+ while @protection_active
297
+ perform_protection_checks
298
+ sleep(@config[:protection_interval])
299
+ end
300
+ end
301
+ end
302
+
303
+ def perform_protection_checks
304
+ @last_check_time = Time.now
305
+
306
+ # Perform all protection checks
307
+ check_ptrace_protection if @config[:enable_anti_debug]
308
+ check_debugger_processes if @config[:enable_anti_debug]
309
+ monitor_code_integrity if @config[:enable_anti_tamper]
310
+ check_frida_injection if @config[:enable_memory_protection]
311
+ monitor_memory_patches if @config[:enable_memory_protection]
312
+ monitor_critical_functions if @config[:enable_integrity_monitor]
313
+ end
314
+
315
+ # Event Reporting System
316
+ def report_rasp_event(event_type, message, details = {})
317
+ return unless @config[:enable_real_time_alerts]
318
+
319
+ @events_detected = (@events_detected || 0) + 1
320
+
321
+ event_data = {
322
+ type: RASP_EVENTS[event_type] || event_type.to_s.upcase,
323
+ message: message,
324
+ timestamp: Time.now.to_f,
325
+ details: details,
326
+ protection_status: protection_status
327
+ }
328
+
329
+ # Call registered callbacks
330
+ @event_callbacks.each do |callback|
331
+ callback.call(event_data) rescue nil
332
+ end
333
+
334
+ # Call configured alert callback
335
+ @config[:alert_callback]&.call(event_data) rescue nil
336
+
337
+ # Log to stderr for immediate visibility
338
+ warn "[RASP] #{event_data[:type]}: #{message}" if @config[:enable_real_time_alerts]
339
+ end
340
+
341
+ # Protection Actions
342
+ def take_protection_action(threat_type)
343
+ case threat_type
344
+ when :debug_attempt
345
+ # Could implement process termination, obfuscation, etc.
346
+ report_rasp_event(:protection_action, "Anti-debug countermeasure activated")
347
+ when :tamper_detected
348
+ # Could implement integrity restoration, alerts, etc.
349
+ report_rasp_event(:protection_action, "Anti-tamper countermeasure activated")
350
+ when :injection_blocked
351
+ # Could implement injection blocking, process isolation, etc.
352
+ report_rasp_event(:protection_action, "Injection blocking countermeasure activated")
353
+ when :integrity_violation
354
+ # Could implement function restoration, alerts, etc.
355
+ report_rasp_event(:protection_action, "Integrity protection countermeasure activated")
356
+ end
357
+ end
358
+ end
359
+ end
@@ -43,8 +43,9 @@ module AiRootShield
43
43
  # Calculate overall risk score from individual analyzer results
44
44
  # @param risk_scores [Array<Integer>] Individual risk scores from analyzers
45
45
  # @param factors [Array<String>] Detected risk factors
46
+ # @param ai_confidence [Float, nil] AI confidence score (0.0-1.0)
46
47
  # @return [Integer] Overall risk score (0-100)
47
- def calculate_overall_risk(risk_scores, factors)
48
+ def calculate_overall_risk(risk_scores, factors, ai_confidence: nil)
48
49
  return 0 if factors.empty?
49
50
 
50
51
  # Calculate weighted score based on detected factors
@@ -59,6 +60,12 @@ module AiRootShield
59
60
  # Apply risk amplification for multiple high-risk factors
60
61
  amplified_score = apply_risk_amplification(combined_score, factors)
61
62
 
63
+ # Apply AI confidence weighting if available
64
+ if ai_confidence && ai_confidence > 0.5
65
+ ai_weight = (ai_confidence - 0.5) * 2 # Scale 0.5-1.0 to 0.0-1.0
66
+ amplified_score *= (1.0 + ai_weight * 0.2) # Up to 20% boost for high confidence
67
+ end
68
+
62
69
  # Ensure score is within bounds
63
70
  [amplified_score.round, 100].min
64
71
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AiRootShield
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -7,17 +7,22 @@ require_relative "ai_root_shield/analyzers/emulator_detector"
7
7
  require_relative "ai_root_shield/analyzers/hooking_detector"
8
8
  require_relative "ai_root_shield/analyzers/integrity_checker"
9
9
  require_relative "ai_root_shield/analyzers/network_analyzer"
10
+ require_relative "ai_root_shield/ai_behavioral_analyzer"
11
+ require_relative "ai_root_shield/rasp_protection"
10
12
  require_relative "ai_root_shield/risk_calculator"
11
13
  require_relative "ai_root_shield/device_log_parser"
12
14
 
13
15
  module AiRootShield
14
16
  class Error < StandardError; end
15
17
 
18
+ # Global RASP protection instance
19
+ @rasp_protection = nil
20
+
16
21
  # Main entry point for device scanning
17
22
  # @param device_logs_path [String] Path to device logs JSON file
18
23
  # @return [Hash] Risk assessment result with score and factors
19
24
  def self.scan_device(device_logs_path)
20
- Detector.new.scan(device_logs_path)
25
+ scan_device_with_config(device_logs_path)
21
26
  end
22
27
 
23
28
  # Scan device with custom configuration
@@ -25,7 +30,35 @@ module AiRootShield
25
30
  # @param config [Hash] Configuration options
26
31
  # @return [Hash] Risk assessment result with score and factors
27
32
  def self.scan_device_with_config(device_logs_path, config = {})
28
- Detector.new(config).scan(device_logs_path)
33
+ detector = Detector.new(config)
34
+ detector.scan(device_logs_path)
35
+ end
36
+
37
+ # Start RASP protection
38
+ # @param config [Hash] RASP configuration options
39
+ # @return [RaspProtection] RASP protection instance
40
+ def self.start_rasp_protection(config = {})
41
+ @rasp_protection = RaspProtection.new(config)
42
+ @rasp_protection.start_protection
43
+ @rasp_protection
44
+ end
45
+
46
+ # Stop RASP protection
47
+ def self.stop_rasp_protection
48
+ @rasp_protection&.stop_protection
49
+ @rasp_protection = nil
50
+ end
51
+
52
+ # Get current RASP protection instance
53
+ # @return [RaspProtection, nil] Current RASP protection instance
54
+ def self.rasp_protection
55
+ @rasp_protection
56
+ end
57
+
58
+ # Check if RASP protection is active
59
+ # @return [Boolean] True if RASP protection is active
60
+ def self.rasp_active?
61
+ @rasp_protection&.protection_status&.dig(:active) || false
29
62
  end
30
63
 
31
64
  # Get version information
data/models/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # AI Root Shield - Behavioral Analysis Models
2
+
3
+ This directory contains ONNX models for AI-powered behavioral analysis.
4
+
5
+ ## Model Architecture
6
+
7
+ The behavioral analysis model (`behavioral_model.onnx`) is designed to analyze device behavior patterns and detect anomalies that may indicate compromise or emulation.
8
+
9
+ ### Input Features (8 dimensions)
10
+
11
+ 1. **File Access Entropy** (0.0-1.0): Shannon entropy of file access patterns
12
+ 2. **Sensor Consistency Score** (0.0-1.0): Consistency of sensor data with real device behavior
13
+ 3. **Hardware Fingerprint Score** (0.0-1.0): Hardware characteristics analysis
14
+ 4. **Process Behavior Score** (0.0-1.0): Process execution patterns analysis
15
+ 5. **Network Pattern Score** (0.0-1.0): Network behavior analysis
16
+ 6. **Timing Analysis Score** (0.0-1.0): Event timing pattern analysis
17
+ 7. **System Call Entropy** (0.0-1.0): System call distribution entropy
18
+ 8. **Memory Access Pattern** (0.0-1.0): Memory usage pattern analysis
19
+
20
+ ### Output
21
+
22
+ - **Risk Score** (0.0-1.0): Behavioral risk assessment
23
+ - **Confidence** (0.0-1.0): Model confidence in the prediction
24
+
25
+ ## Model Training
26
+
27
+ The model should be trained on labeled datasets containing:
28
+ - Legitimate device telemetry data
29
+ - Emulator/simulator data
30
+ - Compromised device data
31
+ - Synthetic attack scenarios
32
+
33
+ ## Usage
34
+
35
+ The model is automatically loaded by `AiBehavioralAnalyzer` if present in this directory. If the model file is not available, the analyzer falls back to rule-based analysis.
36
+
37
+ ## Creating Your Own Model
38
+
39
+ To create a custom behavioral analysis model:
40
+
41
+ 1. Collect training data with the 8 input features
42
+ 2. Train using your preferred ML framework (TensorFlow, PyTorch, etc.)
43
+ 3. Export to ONNX format as `behavioral_model.onnx`
44
+ 4. Place in this directory
45
+
46
+ Example Python code for model creation:
47
+
48
+ ```python
49
+ import onnx
50
+ import numpy as np
51
+ from sklearn.ensemble import RandomForestClassifier
52
+ from skl2onnx import convert_sklearn
53
+ from skl2onnx.common.data_types import FloatTensorType
54
+
55
+ # Train your model
56
+ model = RandomForestClassifier(n_estimators=100, random_state=42)
57
+ model.fit(X_train, y_train)
58
+
59
+ # Convert to ONNX
60
+ initial_type = [('input', FloatTensorType([None, 8]))]
61
+ onnx_model = convert_sklearn(model, initial_types=initial_type)
62
+
63
+ # Save model
64
+ with open("behavioral_model.onnx", "wb") as f:
65
+ f.write(onnx_model.SerializeToString())
66
+ ```
67
+
68
+ ## Security Considerations
69
+
70
+ - Models should be validated for adversarial robustness
71
+ - Regular retraining is recommended as attack techniques evolve
72
+ - Consider model versioning for production deployments
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ai_root_shield
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmet KAHRAMAN
@@ -51,6 +51,34 @@ dependencies:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: '3.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: onnxruntime
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.7'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.7'
68
+ - !ruby/object:Gem::Dependency
69
+ name: numo-narray
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.9'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.9'
54
82
  - !ruby/object:Gem::Dependency
55
83
  name: bundler
56
84
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +170,7 @@ files:
142
170
  - examples/device_logs/rooted_android.json
143
171
  - exe/ai_root_shield
144
172
  - lib/ai_root_shield.rb
173
+ - lib/ai_root_shield/ai_behavioral_analyzer.rb
145
174
  - lib/ai_root_shield/analyzers/emulator_detector.rb
146
175
  - lib/ai_root_shield/analyzers/hooking_detector.rb
147
176
  - lib/ai_root_shield/analyzers/integrity_checker.rb
@@ -149,8 +178,10 @@ files:
149
178
  - lib/ai_root_shield/analyzers/root_detector.rb
150
179
  - lib/ai_root_shield/detector.rb
151
180
  - lib/ai_root_shield/device_log_parser.rb
181
+ - lib/ai_root_shield/rasp_protection.rb
152
182
  - lib/ai_root_shield/risk_calculator.rb
153
183
  - lib/ai_root_shield/version.rb
184
+ - models/README.md
154
185
  homepage: https://github.com/ahmetxhero/ai-root-shield
155
186
  licenses:
156
187
  - MIT