ai_root_shield 0.2.0 → 0.4.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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AiRootShield
4
- VERSION = "0.2.0"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -8,25 +8,153 @@ 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
10
  require_relative "ai_root_shield/ai_behavioral_analyzer"
11
+ require_relative "ai_root_shield/rasp_protection"
11
12
  require_relative "ai_root_shield/risk_calculator"
12
13
  require_relative "ai_root_shield/device_log_parser"
14
+ require_relative "ai_root_shield/certificate_pinning_helper"
15
+ require_relative "ai_root_shield/advanced_proxy_detector"
16
+ require_relative "ai_root_shield/enterprise_policy_manager"
13
17
 
14
18
  module AiRootShield
15
19
  class Error < StandardError; end
16
20
 
21
+ # Global instances
22
+ @rasp_protection = nil
23
+ @policy_manager = nil
24
+ @certificate_pinning = nil
25
+ @proxy_detector = nil
26
+
17
27
  # Main entry point for device scanning
18
28
  # @param device_logs_path [String] Path to device logs JSON file
19
29
  # @return [Hash] Risk assessment result with score and factors
20
30
  def self.scan_device(device_logs_path)
21
- Detector.new.scan(device_logs_path)
31
+ scan_device_with_config(device_logs_path)
22
32
  end
23
33
 
24
- # Scan device with custom configuration
34
+ # Scan device with custom configuration and policy validation
25
35
  # @param device_logs_path [String] Path to device logs JSON file
26
36
  # @param config [Hash] Configuration options
27
- # @return [Hash] Risk assessment result with score and factors
37
+ # @return [Hash] Risk assessment result with score, factors, and compliance
28
38
  def self.scan_device_with_config(device_logs_path, config = {})
29
- Detector.new(config).scan(device_logs_path)
39
+ detector = Detector.new(config)
40
+ scan_result = detector.scan(device_logs_path)
41
+
42
+ # Add network security analysis if enabled
43
+ if config[:enable_network_analysis]
44
+ scan_result = enhance_with_network_analysis(scan_result, config)
45
+ end
46
+
47
+ # Add policy compliance validation if policy manager is configured
48
+ if @policy_manager
49
+ compliance_result = @policy_manager.validate_compliance(scan_result)
50
+ scan_result[:compliance] = compliance_result
51
+ end
52
+
53
+ scan_result
54
+ end
55
+
56
+ # Start RASP protection
57
+ # @param config [Hash] RASP configuration options
58
+ # @return [RaspProtection] RASP protection instance
59
+ def self.start_rasp_protection(config = {})
60
+ @rasp_protection = RaspProtection.new(config)
61
+ @rasp_protection.start_protection
62
+ @rasp_protection
63
+ end
64
+
65
+ # Stop RASP protection
66
+ def self.stop_rasp_protection
67
+ @rasp_protection&.stop_protection
68
+ @rasp_protection = nil
69
+ end
70
+
71
+ # Configure enterprise policy
72
+ # @param policy_config [String, Hash] Policy file path or configuration hash
73
+ # @return [EnterprisePolicyManager] Policy manager instance
74
+ def self.configure_policy(policy_config)
75
+ @policy_manager = EnterprisePolicyManager.new(policy_config)
76
+ end
77
+
78
+ # Configure certificate pinning
79
+ # @param config [Hash] Certificate pinning configuration
80
+ # @return [CertificatePinningHelper] Certificate pinning helper instance
81
+ def self.configure_certificate_pinning(config = {})
82
+ @certificate_pinning = CertificatePinningHelper.new(config)
83
+ end
84
+
85
+ # Configure proxy detection
86
+ # @param config [Hash] Proxy detection configuration
87
+ # @return [AdvancedProxyDetector] Proxy detector instance
88
+ def self.configure_proxy_detection(config = {})
89
+ @proxy_detector = AdvancedProxyDetector.new(config)
90
+ end
91
+
92
+ # Validate certificate pinning for a URL
93
+ # @param url [String] URL to validate
94
+ # @return [Hash] Validation result
95
+ def self.validate_certificate_pinning(url)
96
+ return { error: "Certificate pinning not configured" } unless @certificate_pinning
97
+
98
+ cert_chain = @certificate_pinning.get_certificate_chain(url)
99
+ @certificate_pinning.validate_pin(url, cert_chain)
100
+ end
101
+
102
+ # Detect proxy usage for an IP address
103
+ # @param ip_address [String] IP address to analyze
104
+ # @param additional_data [Hash] Additional network data
105
+ # @return [Hash] Proxy detection result
106
+ def self.detect_proxy(ip_address, additional_data = {})
107
+ return { error: "Proxy detection not configured" } unless @proxy_detector
108
+
109
+ @proxy_detector.detect_proxy(ip_address, additional_data)
110
+ end
111
+
112
+ # Get current RASP protection instance
113
+ # @return [RaspProtection, nil] Current RASP protection instance
114
+ def self.rasp_protection
115
+ @rasp_protection
116
+ end
117
+
118
+ # Get current policy manager instance
119
+ # @return [EnterprisePolicyManager, nil] Current policy manager instance
120
+ def self.policy_manager
121
+ @policy_manager
122
+ end
123
+
124
+ # Get current certificate pinning helper instance
125
+ # @return [CertificatePinningHelper, nil] Current certificate pinning helper instance
126
+ def self.certificate_pinning
127
+ @certificate_pinning
128
+ end
129
+
130
+ # Get current proxy detector instance
131
+ # @return [AdvancedProxyDetector, nil] Current proxy detector instance
132
+ def self.proxy_detector
133
+ @proxy_detector
134
+ end
135
+
136
+ # Check if RASP protection is active
137
+ # @return [Boolean] True if RASP protection is active
138
+ def self.rasp_active?
139
+ @rasp_protection&.protection_status&.dig(:active) || false
140
+ end
141
+
142
+ # Get comprehensive security status
143
+ # @return [Hash] Security status across all components
144
+ def self.security_status
145
+ {
146
+ version: VERSION,
147
+ rasp_active: rasp_active?,
148
+ policy_configured: !@policy_manager.nil?,
149
+ certificate_pinning_configured: !@certificate_pinning.nil?,
150
+ proxy_detection_configured: !@proxy_detector.nil?,
151
+ components: {
152
+ rasp: @rasp_protection&.protection_status,
153
+ policy: @policy_manager&.policy_statistics,
154
+ certificate_pinning: @certificate_pinning&.pinning_status,
155
+ proxy_detection: @proxy_detector&.detection_statistics
156
+ }
157
+ }
30
158
  end
31
159
 
32
160
  # Get version information
@@ -34,4 +162,43 @@ module AiRootShield
34
162
  def self.version
35
163
  VERSION
36
164
  end
165
+
166
+ private
167
+
168
+ # Enhance scan result with network security analysis
169
+ # @param scan_result [Hash] Original scan result
170
+ # @param config [Hash] Configuration options
171
+ # @return [Hash] Enhanced scan result
172
+ def self.enhance_with_network_analysis(scan_result, config)
173
+ network_analysis = {}
174
+
175
+ # Add proxy detection if configured
176
+ if @proxy_detector && config[:target_ip]
177
+ proxy_result = @proxy_detector.detect_proxy(config[:target_ip], config[:network_data] || {})
178
+ network_analysis[:proxy_detection] = proxy_result
179
+
180
+ # Add proxy indicators to risk factors if detected
181
+ if proxy_result[:proxy_detected]
182
+ scan_result[:factors] ||= []
183
+ proxy_result[:proxy_types].each do |type|
184
+ scan_result[:factors] << "NETWORK_#{type.upcase}_DETECTED"
185
+ end
186
+ end
187
+ end
188
+
189
+ # Add certificate pinning validation if configured
190
+ if @certificate_pinning && config[:target_url]
191
+ pinning_result = validate_certificate_pinning(config[:target_url])
192
+ network_analysis[:certificate_pinning] = pinning_result
193
+
194
+ # Add certificate pinning failure to risk factors if invalid
195
+ unless pinning_result[:valid]
196
+ scan_result[:factors] ||= []
197
+ scan_result[:factors] << "CERTIFICATE_PINNING_FAILED"
198
+ end
199
+ end
200
+
201
+ scan_result[:network_analysis] = network_analysis unless network_analysis.empty?
202
+ scan_result
203
+ end
37
204
  end
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.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ahmet KAHRAMAN
@@ -149,9 +149,12 @@ dependencies:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
151
  version: '0.9'
152
- description: An AI-powered Ruby library that performs on-device compromise detection
153
- for mobile applications without requiring a backend. Detects root/jailbreak, emulators,
154
- hooking frameworks, and provides behavioral risk analysis.
152
+ description: An AI-powered Ruby library that performs comprehensive on-device compromise
153
+ detection for mobile applications. Features include root/jailbreak detection, emulator
154
+ detection, hooking framework detection, application integrity checks, advanced network
155
+ security analysis with certificate pinning and proxy detection, enterprise policy
156
+ management, AI behavioral analysis, and RASP protection - all without requiring
157
+ a backend.
155
158
  email:
156
159
  - ahmetxhero@gmail.com
157
160
  executables:
@@ -168,16 +171,23 @@ files:
168
171
  - Rakefile
169
172
  - examples/device_logs/clean_device.json
170
173
  - examples/device_logs/rooted_android.json
174
+ - examples/policies/banking_policy.json
175
+ - examples/policies/development_policy.json
176
+ - examples/policies/enterprise_policy.json
171
177
  - exe/ai_root_shield
172
178
  - lib/ai_root_shield.rb
179
+ - lib/ai_root_shield/advanced_proxy_detector.rb
173
180
  - lib/ai_root_shield/ai_behavioral_analyzer.rb
174
181
  - lib/ai_root_shield/analyzers/emulator_detector.rb
175
182
  - lib/ai_root_shield/analyzers/hooking_detector.rb
176
183
  - lib/ai_root_shield/analyzers/integrity_checker.rb
177
184
  - lib/ai_root_shield/analyzers/network_analyzer.rb
178
185
  - lib/ai_root_shield/analyzers/root_detector.rb
186
+ - lib/ai_root_shield/certificate_pinning_helper.rb
179
187
  - lib/ai_root_shield/detector.rb
180
188
  - lib/ai_root_shield/device_log_parser.rb
189
+ - lib/ai_root_shield/enterprise_policy_manager.rb
190
+ - lib/ai_root_shield/rasp_protection.rb
181
191
  - lib/ai_root_shield/risk_calculator.rb
182
192
  - lib/ai_root_shield/version.rb
183
193
  - models/README.md
@@ -205,5 +215,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
215
  requirements: []
206
216
  rubygems_version: 3.6.9
207
217
  specification_version: 4
208
- summary: AI-powered mobile device compromise detection library
218
+ summary: AI-powered mobile security library with advanced network security and enterprise
219
+ policy management
209
220
  test_files: []