ai_root_shield 0.4.0 → 1.0.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,172 @@
1
+ {
2
+ "platform": "ios",
3
+ "timestamp": 1640995200,
4
+ "device_info": {
5
+ "model": "iPhone 13 Pro",
6
+ "manufacturer": "Apple",
7
+ "os_version": "15.6.1",
8
+ "device_identifier": "iPhone14,3"
9
+ },
10
+ "code_signing": {
11
+ "mainBundleSigned": false,
12
+ "embeddedProvisioning": true,
13
+ "teamIdentifier": "ABCD123456",
14
+ "codeDirectoryHash": "sha256:1234567890abcdef...",
15
+ "entitlementsValid": false,
16
+ "signatureVersion": 2,
17
+ "certificateChainValid": false,
18
+ "certificate": {
19
+ "isDevelopment": true,
20
+ "isDistribution": false,
21
+ "isEnterprise": false,
22
+ "isAdhoc": false,
23
+ "expirationDate": "2024-12-31T23:59:59Z",
24
+ "issuer": "Apple Development"
25
+ }
26
+ },
27
+ "sandbox": {
28
+ "containerIntegrity": false,
29
+ "fileAccessViolations": [
30
+ "/private/var/mobile/Library/Preferences",
31
+ "/Applications/Cydia.app"
32
+ ],
33
+ "networkAccessViolations": [],
34
+ "ipcViolations": ["com.apple.springboard"],
35
+ "entitlementViolations": ["get-task-allow"],
36
+ "sandboxProfileValid": false
37
+ },
38
+ "dyld": {
39
+ "loadedLibraries": [
40
+ "/usr/lib/libSystem.B.dylib",
41
+ "/Library/MobileSubstrate/MobileSubstrate.dylib",
42
+ "/Library/MobileSubstrate/DynamicLibraries/PreferenceLoader.dylib",
43
+ "/usr/lib/substitute-inserter.dylib"
44
+ ],
45
+ "injectedLibraries": [
46
+ "/Library/MobileSubstrate/MobileSubstrate.dylib",
47
+ "/usr/lib/substitute-inserter.dylib"
48
+ ],
49
+ "runtimeModifications": [
50
+ {
51
+ "library": "MobileSubstrate",
52
+ "function": "MSHookFunction",
53
+ "target": "objc_msgSend"
54
+ }
55
+ ],
56
+ "methodSwizzling": {
57
+ "detected": true,
58
+ "swizzledMethods": [
59
+ "UIApplication.openURL:",
60
+ "NSFileManager.fileExistsAtPath:"
61
+ ]
62
+ }
63
+ },
64
+ "hardware_security": {
65
+ "secureEnclaveAvailable": true,
66
+ "touchIdAvailable": true,
67
+ "faceIdAvailable": false,
68
+ "processorType": "A15 Bionic",
69
+ "secureBootChain": true,
70
+ "uidAvailable": true,
71
+ "gidAvailable": true,
72
+ "biometricKeysProtected": true,
73
+ "keychainHardwareProtection": true,
74
+ "sepFirmwareVersion": "4.0.0",
75
+ "biometrics": {
76
+ "touchIdEnrolled": true,
77
+ "faceIdEnrolled": false,
78
+ "biometricChangesDetected": false,
79
+ "hardwareTamperDetected": false
80
+ }
81
+ },
82
+ "system_integrity": {
83
+ "systemVersionAuthentic": false,
84
+ "kernelIntegrity": false,
85
+ "amfiEnabled": false,
86
+ "sipEnabled": false,
87
+ "codeInjectionProtection": false,
88
+ "libraryValidation": false,
89
+ "runtimeProtections": []
90
+ },
91
+ "file_system": {
92
+ "files": [
93
+ {
94
+ "path": "/Applications/Cydia.app",
95
+ "exists": true,
96
+ "permissions": "755"
97
+ },
98
+ {
99
+ "path": "/Library/MobileSubstrate/MobileSubstrate.dylib",
100
+ "exists": true,
101
+ "permissions": "755"
102
+ },
103
+ {
104
+ "path": "/usr/bin/ssh",
105
+ "exists": true,
106
+ "permissions": "755"
107
+ },
108
+ {
109
+ "path": "/private/var/lib/cydia",
110
+ "exists": true,
111
+ "permissions": "755"
112
+ },
113
+ {
114
+ "path": "/bin/bash",
115
+ "exists": true,
116
+ "permissions": "755"
117
+ }
118
+ ]
119
+ },
120
+ "url_schemes": [
121
+ "cydia://",
122
+ "sileo://",
123
+ "zbra://",
124
+ "filza://",
125
+ "activator://"
126
+ ],
127
+ "symbolic_links": [
128
+ {
129
+ "source": "/Applications",
130
+ "target": "/var/stash/Applications"
131
+ },
132
+ {
133
+ "source": "/usr/include",
134
+ "target": "/var/stash/usr/include"
135
+ }
136
+ ],
137
+ "fork_test": {
138
+ "forkAllowed": true
139
+ },
140
+ "system_calls": {
141
+ "ptraceDetected": true,
142
+ "sysctlBypass": true,
143
+ "dlopenHooking": true
144
+ },
145
+ "runtime_manipulation": {
146
+ "methodSwizzlingDetected": true,
147
+ "classDumpDetected": true,
148
+ "runtimeInjection": true
149
+ },
150
+ "network": {
151
+ "proxy_enabled": false,
152
+ "vpn_active": false,
153
+ "custom_certificates": [],
154
+ "tls_version": "1.3"
155
+ },
156
+ "risk_score": 85,
157
+ "factors": [
158
+ "IOS_JAILBREAK_FILES_DETECTED",
159
+ "IOS_JAILBREAK_URL_SCHEMES_DETECTED",
160
+ "IOS_JAILBREAK_LIBRARIES_DETECTED",
161
+ "IOS_SANDBOX_VIOLATIONS_DETECTED",
162
+ "IOS_FORK_RESTRICTIONS_BYPASSED",
163
+ "IOS_MAIN_BUNDLE_NOT_SIGNED",
164
+ "IOS_INVALID_CERTIFICATE_CHAIN",
165
+ "IOS_DEVELOPMENT_CERTIFICATE",
166
+ "IOS_DYLD_INJECTION_DETECTED",
167
+ "IOS_HOOKING_FRAMEWORKS_DETECTED",
168
+ "IOS_AMFI_DISABLED",
169
+ "IOS_SIP_DISABLED",
170
+ "IOS_LIBRARY_VALIDATION_DISABLED"
171
+ ]
172
+ }
data/exe/ai_root_shield CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  require "optparse"
5
5
  require "json"
6
+ require "fileutils"
6
7
  require_relative "../lib/ai_root_shield"
7
8
 
8
9
  # Command line interface for AI Root Shield
@@ -24,13 +25,37 @@ class AiRootShieldCLI
24
25
  enable_certificate_pinning: false,
25
26
  enable_proxy_detection: false,
26
27
  target_ip: nil,
27
- target_url: nil
28
+ target_url: nil,
29
+ # v0.5.0 new options
30
+ platform: nil,
31
+ safetynet_api_key: nil,
32
+ package_name: nil,
33
+ ci_mode: false,
34
+ artifacts_path: './security_test_artifacts',
35
+ siem_platform: nil,
36
+ siem_endpoint: nil,
37
+ siem_token: nil,
38
+ start_dashboard: false,
39
+ dashboard_port: 4567,
40
+ generate_ci_config: nil,
41
+ enable_unified_reporting: false
28
42
  }
29
43
  end
30
44
 
31
45
  def run(args)
32
46
  parse_options(args)
33
47
 
48
+ # Handle special commands first
49
+ if @options[:start_dashboard]
50
+ start_dashboard
51
+ return
52
+ end
53
+
54
+ if @options[:generate_ci_config]
55
+ generate_ci_config
56
+ return
57
+ end
58
+
34
59
  if args.empty?
35
60
  puts "Error: Please provide a device logs file path"
36
61
  puts "Usage: ai_root_shield [options] <device_logs.json>"
@@ -45,6 +70,15 @@ class AiRootShieldCLI
45
70
  end
46
71
 
47
72
  begin
73
+ # Configure SIEM if provided
74
+ if @options[:siem_platform] && @options[:siem_endpoint] && @options[:siem_token]
75
+ puts "Configuring SIEM integration (#{@options[:siem_platform]})..." if @options[:verbose]
76
+ AiRootShield.configure_siem(@options[:siem_platform].to_sym, {
77
+ api_endpoint: @options[:siem_endpoint],
78
+ api_key: @options[:siem_token]
79
+ })
80
+ end
81
+
48
82
  # Configure enterprise policy if provided
49
83
  if @options[:policy_file]
50
84
  puts "Loading enterprise policy from #{@options[:policy_file]}..." if @options[:verbose]
@@ -83,7 +117,23 @@ class AiRootShieldCLI
83
117
  sleep(@options[:rasp_monitoring_time])
84
118
  end
85
119
 
86
- result = AiRootShield.scan_device_with_config(device_logs_path, @options)
120
+ # Run analysis based on mode
121
+ if @options[:ci_mode]
122
+ result = run_ci_cd_analysis(device_logs_path)
123
+ elsif @options[:platform]
124
+ result = run_platform_specific_analysis(device_logs_path)
125
+ else
126
+ result = AiRootShield.scan_device_with_config(device_logs_path, @options)
127
+ end
128
+
129
+ # Send to SIEM if configured
130
+ if @options[:siem_platform]
131
+ puts "Sending results to SIEM..." if @options[:verbose]
132
+ AiRootShield.send_to_siem(result, {
133
+ cli_version: AiRootShield::VERSION,
134
+ scan_timestamp: Time.now.utc.iso8601
135
+ })
136
+ end
87
137
 
88
138
  # Add RASP status to result if enabled
89
139
  if @options[:enable_rasp_protection] && AiRootShield.rasp_active?
@@ -184,6 +234,70 @@ class AiRootShieldCLI
184
234
  @options[:target_url] = url
185
235
  end
186
236
 
237
+ # v0.5.0 Platform-specific options
238
+ opts.separator ""
239
+ opts.separator "Platform-specific Analysis (v0.5.0):"
240
+
241
+ opts.on("--platform PLATFORM", ["android", "ios"], "Platform-specific analysis (android, ios)") do |platform|
242
+ @options[:platform] = platform
243
+ end
244
+
245
+ opts.on("--safetynet-key KEY", "Google SafetyNet API key for Android analysis") do |key|
246
+ @options[:safetynet_api_key] = key
247
+ end
248
+
249
+ opts.on("--package-name NAME", "Android package name for analysis") do |name|
250
+ @options[:package_name] = name
251
+ end
252
+
253
+ opts.on("--unified-report", "Generate unified cross-platform report") do
254
+ @options[:enable_unified_reporting] = true
255
+ end
256
+
257
+ # CI/CD Integration options
258
+ opts.separator ""
259
+ opts.separator "CI/CD Integration (v0.5.0):"
260
+
261
+ opts.on("--ci-mode", "Run in CI/CD mode with test artifacts") do
262
+ @options[:ci_mode] = true
263
+ end
264
+
265
+ opts.on("--artifacts-path PATH", "Path for CI/CD test artifacts (default: ./security_test_artifacts)") do |path|
266
+ @options[:artifacts_path] = path
267
+ end
268
+
269
+ opts.on("--generate-ci-config PLATFORM", ["github", "gitlab", "jenkins", "azure"], "Generate CI config for platform") do |platform|
270
+ @options[:generate_ci_config] = platform
271
+ end
272
+
273
+ # SIEM Integration options
274
+ opts.separator ""
275
+ opts.separator "SIEM Integration (v0.5.0):"
276
+
277
+ opts.on("--siem-platform PLATFORM", ["splunk", "elastic", "qradar", "sentinel", "datadog", "chronicle", "arcsight"], "SIEM platform") do |platform|
278
+ @options[:siem_platform] = platform
279
+ end
280
+
281
+ opts.on("--siem-endpoint URL", "SIEM API endpoint URL") do |url|
282
+ @options[:siem_endpoint] = url
283
+ end
284
+
285
+ opts.on("--siem-token TOKEN", "SIEM API authentication token") do |token|
286
+ @options[:siem_token] = token
287
+ end
288
+
289
+ # Dashboard options
290
+ opts.separator ""
291
+ opts.separator "Dashboard (v0.5.0):"
292
+
293
+ opts.on("--start-dashboard", "Start web dashboard server") do
294
+ @options[:start_dashboard] = true
295
+ end
296
+
297
+ opts.on("--dashboard-port PORT", Integer, "Dashboard port (default: 4567)") do |port|
298
+ @options[:dashboard_port] = port
299
+ end
300
+
187
301
  opts.on("-h", "--help", "Show this help message") do
188
302
  puts opts
189
303
  exit
@@ -280,14 +394,113 @@ class AiRootShieldCLI
280
394
  end
281
395
 
282
396
  def output_summary_format(result)
283
- risk_level = AiRootShield::RiskCalculator.risk_level_description(result[:risk_score])
397
+ # Handle unified report format
398
+ if result[:executive_summary]
399
+ risk_level = result[:executive_summary][:overall_risk_level]
400
+ security_score = result[:executive_summary][:security_posture_score]
401
+ threat_count = result[:executive_summary][:critical_findings]&.length || 0
402
+
403
+ puts "Risk Level: #{risk_level} (Security Score: #{security_score}/100)"
404
+ puts "Threats: #{threat_count} critical findings detected"
405
+
406
+ if result[:executive_summary][:key_recommendations]&.any?
407
+ puts "Primary Concerns: #{result[:executive_summary][:key_recommendations].first(3).join(', ')}"
408
+ end
409
+ else
410
+ # Handle regular analysis format
411
+ risk_level = AiRootShield::RiskCalculator.risk_level_description(result[:risk_score])
412
+
413
+ puts "Risk Level: #{risk_level} (#{result[:risk_score]}/100)"
414
+ puts "Threats: #{result[:factors]&.length || 0} detected"
415
+
416
+ if result[:factors]&.any?
417
+ puts "Primary Concerns: #{result[:factors].first(3).join(', ')}"
418
+ end
419
+ end
420
+ end
421
+
422
+ # v0.5.0 New Methods
423
+ def run_platform_specific_analysis(device_logs_path)
424
+ puts "Running #{@options[:platform]} platform-specific analysis..." if @options[:verbose]
284
425
 
285
- puts "Risk Level: #{risk_level} (#{result[:risk_score]}/100)"
286
- puts "Threats: #{result[:factors].length} detected"
426
+ case @options[:platform]
427
+ when 'android'
428
+ config = {}
429
+ config[:safetynet_api_key] = @options[:safetynet_api_key] if @options[:safetynet_api_key]
430
+ config[:package_name] = @options[:package_name] if @options[:package_name]
431
+
432
+ result = AiRootShield.analyze_android_device(device_logs_path, config)
433
+ when 'ios'
434
+ result = AiRootShield.analyze_ios_device(device_logs_path)
435
+ else
436
+ raise "Unsupported platform: #{@options[:platform]}"
437
+ end
287
438
 
288
- if result[:factors].any?
289
- puts "Primary Concerns: #{result[:factors].first(3).join(', ')}"
439
+ if @options[:enable_unified_reporting]
440
+ puts "Generating unified cross-platform report..." if @options[:verbose]
441
+ case @options[:platform]
442
+ when 'android'
443
+ unified_result = AiRootShield.generate_unified_report(android_results: result)
444
+ when 'ios'
445
+ unified_result = AiRootShield.generate_unified_report(ios_results: result)
446
+ end
447
+ return unified_result
290
448
  end
449
+
450
+ result
451
+ end
452
+
453
+ def run_ci_cd_analysis(device_logs_path)
454
+ puts "Running CI/CD security analysis..." if @options[:verbose]
455
+
456
+ # Create artifacts directory
457
+ Dir.mkdir(@options[:artifacts_path]) unless Dir.exist?(@options[:artifacts_path])
458
+
459
+ # Run CI/CD tests
460
+ result = AiRootShield.run_ci_cd_tests(device_logs_path, {
461
+ artifacts_path: @options[:artifacts_path],
462
+ verbose: @options[:verbose]
463
+ })
464
+
465
+ puts "CI/CD test artifacts saved to: #{@options[:artifacts_path]}" if @options[:verbose]
466
+ result
467
+ end
468
+
469
+ def start_dashboard
470
+ puts "Starting AI Root Shield Dashboard on port #{@options[:dashboard_port]}..."
471
+ puts "Dashboard will be available at: http://localhost:#{@options[:dashboard_port]}"
472
+ puts "Press Ctrl+C to stop the dashboard"
473
+
474
+ begin
475
+ AiRootShield.start_dashboard(@options[:dashboard_port])
476
+ rescue Interrupt
477
+ puts "\nDashboard stopped."
478
+ end
479
+ end
480
+
481
+ def generate_ci_config
482
+ puts "Generating CI/CD configuration for #{@options[:generate_ci_config]}..."
483
+
484
+ config_content = AiRootShield.generate_ci_config(@options[:generate_ci_config].to_sym)
485
+
486
+ filename = case @options[:generate_ci_config]
487
+ when 'github'
488
+ '.github/workflows/security-scan.yml'
489
+ when 'gitlab'
490
+ '.gitlab-ci.yml'
491
+ when 'jenkins'
492
+ 'Jenkinsfile'
493
+ when 'azure'
494
+ 'azure-pipelines.yml'
495
+ end
496
+
497
+ # Create directory if needed
498
+ dir = File.dirname(filename)
499
+ FileUtils.mkdir_p(dir) unless Dir.exist?(dir) || dir == '.'
500
+
501
+ File.write(filename, config_content)
502
+ puts "CI/CD configuration saved to: #{filename}"
503
+ puts "Please review and customize the configuration as needed."
291
504
  end
292
505
  end
293
506