ai_root_shield 0.1.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,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module AiRootShield
6
+ # Main detector class that orchestrates all security checks
7
+ class Detector
8
+ DEFAULT_CONFIG = {
9
+ enable_root_detection: true,
10
+ enable_emulator_detection: true,
11
+ enable_hooking_detection: true,
12
+ enable_integrity_checks: true,
13
+ enable_network_analysis: true,
14
+ risk_threshold: 50
15
+ }.freeze
16
+
17
+ def initialize(config = {})
18
+ @config = DEFAULT_CONFIG.merge(config)
19
+ @analyzers = initialize_analyzers
20
+ end
21
+
22
+ # Perform comprehensive device security scan
23
+ # @param device_logs_path [String] Path to device logs JSON file
24
+ # @return [Hash] Scan results with risk score and detected factors
25
+ def scan(device_logs_path)
26
+ device_data = DeviceLogParser.parse(device_logs_path)
27
+
28
+ detected_factors = []
29
+ risk_scores = []
30
+
31
+ @analyzers.each do |analyzer|
32
+ next unless analyzer_enabled?(analyzer)
33
+
34
+ result = analyzer.analyze(device_data)
35
+ detected_factors.concat(result[:factors])
36
+ risk_scores << result[:risk_score]
37
+ end
38
+
39
+ overall_risk = RiskCalculator.calculate_overall_risk(risk_scores, detected_factors)
40
+
41
+ {
42
+ risk_score: overall_risk,
43
+ factors: detected_factors.uniq,
44
+ timestamp: Time.now.to_i,
45
+ version: AiRootShield::VERSION
46
+ }
47
+ end
48
+
49
+ private
50
+
51
+ def initialize_analyzers
52
+ [
53
+ Analyzers::RootDetector.new,
54
+ Analyzers::EmulatorDetector.new,
55
+ Analyzers::HookingDetector.new,
56
+ Analyzers::IntegrityChecker.new,
57
+ Analyzers::NetworkAnalyzer.new
58
+ ]
59
+ end
60
+
61
+ def analyzer_enabled?(analyzer)
62
+ case analyzer.class.name.split("::").last
63
+ when "RootDetector"
64
+ @config[:enable_root_detection]
65
+ when "EmulatorDetector"
66
+ @config[:enable_emulator_detection]
67
+ when "HookingDetector"
68
+ @config[:enable_hooking_detection]
69
+ when "IntegrityChecker"
70
+ @config[:enable_integrity_checks]
71
+ when "NetworkAnalyzer"
72
+ @config[:enable_network_analysis]
73
+ else
74
+ true
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module AiRootShield
6
+ # Parses device logs and extracts relevant security information
7
+ class DeviceLogParser
8
+ class << self
9
+ # Parse device logs from JSON file
10
+ # @param file_path [String] Path to the device logs JSON file
11
+ # @return [Hash] Parsed device data
12
+ def parse(file_path)
13
+ raise Error, "Device logs file not found: #{file_path}" unless File.exist?(file_path)
14
+
15
+ raw_data = JSON.parse(File.read(file_path))
16
+ normalize_device_data(raw_data)
17
+ rescue JSON::ParserError => e
18
+ raise Error, "Invalid JSON format in device logs: #{e.message}"
19
+ end
20
+
21
+ private
22
+
23
+ # Normalize device data into a consistent format
24
+ # @param raw_data [Hash] Raw device data from JSON
25
+ # @return [Hash] Normalized device data
26
+ def normalize_device_data(raw_data)
27
+ {
28
+ platform: detect_platform(raw_data),
29
+ system_info: extract_system_info(raw_data),
30
+ installed_packages: extract_packages(raw_data),
31
+ file_system: extract_file_system_info(raw_data),
32
+ processes: extract_processes(raw_data),
33
+ network_config: extract_network_config(raw_data),
34
+ security_settings: extract_security_settings(raw_data),
35
+ hardware_info: extract_hardware_info(raw_data),
36
+ certificates: extract_certificates(raw_data),
37
+ logs: extract_system_logs(raw_data)
38
+ }
39
+ end
40
+
41
+ def detect_platform(data)
42
+ return "android" if data.key?("android") || data.key?("selinux_status")
43
+ return "ios" if data.key?("ios") || data.key?("dyld_info")
44
+
45
+ "unknown"
46
+ end
47
+
48
+ def extract_system_info(data)
49
+ system_info = data["system_info"] || {}
50
+ {
51
+ os_version: system_info["os_version"],
52
+ kernel_version: system_info["kernel_version"],
53
+ build_fingerprint: system_info["build_fingerprint"],
54
+ bootloader_status: system_info["bootloader_status"],
55
+ selinux_status: system_info["selinux_status"],
56
+ developer_options: system_info["developer_options"]
57
+ }
58
+ end
59
+
60
+ def extract_packages(data)
61
+ data["installed_packages"] || data["apps"] || []
62
+ end
63
+
64
+ def extract_file_system_info(data)
65
+ fs_info = data["file_system"] || {}
66
+ {
67
+ mounted_partitions: fs_info["mounted_partitions"] || [],
68
+ suspicious_files: fs_info["suspicious_files"] || [],
69
+ system_binaries: fs_info["system_binaries"] || [],
70
+ writable_system_dirs: fs_info["writable_system_dirs"] || []
71
+ }
72
+ end
73
+
74
+ def extract_processes(data)
75
+ data["running_processes"] || data["processes"] || []
76
+ end
77
+
78
+ def extract_network_config(data)
79
+ network = data["network"] || {}
80
+ {
81
+ proxy_settings: network["proxy_settings"],
82
+ vpn_active: network["vpn_active"],
83
+ certificates: network["certificates"] || [],
84
+ tls_config: network["tls_config"]
85
+ }
86
+ end
87
+
88
+ def extract_security_settings(data)
89
+ security = data["security"] || {}
90
+ {
91
+ screen_lock_enabled: security["screen_lock_enabled"],
92
+ encryption_enabled: security["encryption_enabled"],
93
+ unknown_sources: security["unknown_sources"],
94
+ usb_debugging: security["usb_debugging"]
95
+ }
96
+ end
97
+
98
+ def extract_hardware_info(data)
99
+ hardware = data["hardware"] || {}
100
+ {
101
+ device_model: hardware["device_model"],
102
+ manufacturer: hardware["manufacturer"],
103
+ sensors: hardware["sensors"] || [],
104
+ baseband_version: hardware["baseband_version"],
105
+ serial_number: hardware["serial_number"]
106
+ }
107
+ end
108
+
109
+ def extract_certificates(data)
110
+ data["certificates"] || []
111
+ end
112
+
113
+ def extract_system_logs(data)
114
+ data["system_logs"] || data["logs"] || []
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AiRootShield
4
+ # Calculates overall risk scores based on detected security factors
5
+ class RiskCalculator
6
+ # Risk factor weights for different types of threats
7
+ RISK_WEIGHTS = {
8
+ # Root/Jailbreak factors (high risk)
9
+ "ROOT_SU_FOUND" => 25,
10
+ "ROOT_SUPERUSER_APK" => 20,
11
+ "JAILBREAK_CYDIA" => 25,
12
+ "BOOTLOADER_UNLOCKED" => 15,
13
+ "SELINUX_PERMISSIVE" => 20,
14
+
15
+ # Emulator factors (medium-high risk)
16
+ "EMULATOR_QEMU" => 20,
17
+ "EMULATOR_GENYMOTION" => 18,
18
+ "SIMULATOR_IOS" => 15,
19
+ "MISSING_BASEBAND" => 12,
20
+ "VIRTUAL_SENSORS" => 10,
21
+
22
+ # Hooking/Instrumentation factors (high risk)
23
+ "FRIDA_GADGET" => 25,
24
+ "XPOSED_FRAMEWORK" => 22,
25
+ "MAGISK_MODULES" => 20,
26
+ "SUBSTRATE_INJECTION" => 18,
27
+ "DEBUGGER_ATTACHED" => 15,
28
+
29
+ # Integrity factors (medium risk)
30
+ "REPACKAGED_APP" => 18,
31
+ "SIGNATURE_MISMATCH" => 15,
32
+ "DEX_TAMPERED" => 12,
33
+ "BUNDLE_MODIFIED" => 10,
34
+
35
+ # Network security factors (medium risk)
36
+ "TLS_UNPINNED" => 12,
37
+ "CUSTOM_CA_INSTALLED" => 15,
38
+ "MITM_PROXY_DETECTED" => 18,
39
+ "VPN_SUSPICIOUS" => 8
40
+ }.freeze
41
+
42
+ class << self
43
+ # Calculate overall risk score from individual analyzer results
44
+ # @param risk_scores [Array<Integer>] Individual risk scores from analyzers
45
+ # @param factors [Array<String>] Detected risk factors
46
+ # @return [Integer] Overall risk score (0-100)
47
+ def calculate_overall_risk(risk_scores, factors)
48
+ return 0 if factors.empty?
49
+
50
+ # Calculate weighted score based on detected factors
51
+ weighted_score = calculate_weighted_factor_score(factors)
52
+
53
+ # Calculate average analyzer score
54
+ avg_analyzer_score = risk_scores.empty? ? 0 : (risk_scores.sum.to_f / risk_scores.length)
55
+
56
+ # Combine weighted factor score (70%) and analyzer average (30%)
57
+ combined_score = (weighted_score * 0.7) + (avg_analyzer_score * 0.3)
58
+
59
+ # Apply risk amplification for multiple high-risk factors
60
+ amplified_score = apply_risk_amplification(combined_score, factors)
61
+
62
+ # Ensure score is within bounds
63
+ [amplified_score.round, 100].min
64
+ end
65
+
66
+ # Get risk level description based on score
67
+ # @param score [Integer] Risk score (0-100)
68
+ # @return [String] Risk level description
69
+ def risk_level_description(score)
70
+ case score
71
+ when 0..20
72
+ "LOW"
73
+ when 21..40
74
+ "MEDIUM"
75
+ when 41..70
76
+ "HIGH"
77
+ when 71..100
78
+ "CRITICAL"
79
+ else
80
+ "UNKNOWN"
81
+ end
82
+ end
83
+
84
+ # Get recommended actions based on risk factors
85
+ # @param factors [Array<String>] Detected risk factors
86
+ # @return [Array<String>] Recommended security actions
87
+ def recommended_actions(factors)
88
+ actions = []
89
+
90
+ if has_root_factors?(factors)
91
+ actions << "Block app execution on rooted/jailbroken devices"
92
+ end
93
+
94
+ if has_emulator_factors?(factors)
95
+ actions << "Implement additional emulator detection measures"
96
+ end
97
+
98
+ if has_hooking_factors?(factors)
99
+ actions << "Enable anti-tampering and runtime protection"
100
+ end
101
+
102
+ if has_network_factors?(factors)
103
+ actions << "Enforce certificate pinning and secure communications"
104
+ end
105
+
106
+ actions << "Monitor device for ongoing security threats" if actions.any?
107
+ actions
108
+ end
109
+
110
+ private
111
+
112
+ def calculate_weighted_factor_score(factors)
113
+ total_weight = factors.sum { |factor| RISK_WEIGHTS[factor] || 5 }
114
+
115
+ # Normalize to 0-100 scale (assuming max possible weight around 150)
116
+ normalized_score = (total_weight.to_f / 150) * 100
117
+ [normalized_score, 100].min
118
+ end
119
+
120
+ def apply_risk_amplification(base_score, factors)
121
+ high_risk_factors = count_high_risk_factors(factors)
122
+
123
+ # Amplify risk if multiple high-risk factors are present
124
+ amplification_factor = case high_risk_factors
125
+ when 0..1
126
+ 1.0
127
+ when 2..3
128
+ 1.15
129
+ when 4..5
130
+ 1.3
131
+ else
132
+ 1.5
133
+ end
134
+
135
+ base_score * amplification_factor
136
+ end
137
+
138
+ def count_high_risk_factors(factors)
139
+ high_risk_patterns = %w[ROOT JAILBREAK FRIDA XPOSED MAGISK DEBUGGER]
140
+ factors.count { |factor| high_risk_patterns.any? { |pattern| factor.include?(pattern) } }
141
+ end
142
+
143
+ def has_root_factors?(factors)
144
+ factors.any? { |f| f.start_with?("ROOT_", "JAILBREAK_") }
145
+ end
146
+
147
+ def has_emulator_factors?(factors)
148
+ factors.any? { |f| f.start_with?("EMULATOR_", "SIMULATOR_") }
149
+ end
150
+
151
+ def has_hooking_factors?(factors)
152
+ hooking_patterns = %w[FRIDA XPOSED MAGISK SUBSTRATE DEBUGGER]
153
+ factors.any? { |f| hooking_patterns.any? { |pattern| f.include?(pattern) } }
154
+ end
155
+
156
+ def has_network_factors?(factors)
157
+ factors.any? { |f| f.include?("TLS_") || f.include?("MITM_") || f.include?("CA_") }
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AiRootShield
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ai_root_shield/version"
4
+ require_relative "ai_root_shield/detector"
5
+ require_relative "ai_root_shield/analyzers/root_detector"
6
+ require_relative "ai_root_shield/analyzers/emulator_detector"
7
+ require_relative "ai_root_shield/analyzers/hooking_detector"
8
+ require_relative "ai_root_shield/analyzers/integrity_checker"
9
+ require_relative "ai_root_shield/analyzers/network_analyzer"
10
+ require_relative "ai_root_shield/risk_calculator"
11
+ require_relative "ai_root_shield/device_log_parser"
12
+
13
+ module AiRootShield
14
+ class Error < StandardError; end
15
+
16
+ # Main entry point for device scanning
17
+ # @param device_logs_path [String] Path to device logs JSON file
18
+ # @return [Hash] Risk assessment result with score and factors
19
+ def self.scan_device(device_logs_path)
20
+ Detector.new.scan(device_logs_path)
21
+ end
22
+
23
+ # Scan device with custom configuration
24
+ # @param device_logs_path [String] Path to device logs JSON file
25
+ # @param config [Hash] Configuration options
26
+ # @return [Hash] Risk assessment result with score and factors
27
+ def self.scan_device_with_config(device_logs_path, config = {})
28
+ Detector.new(config).scan(device_logs_path)
29
+ end
30
+
31
+ # Get version information
32
+ # @return [String] Current version
33
+ def self.version
34
+ VERSION
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ai_root_shield
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ahmet KAHRAMAN
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.6'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.6'
26
+ - !ruby/object:Gem::Dependency
27
+ name: digest
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.1'
40
+ - !ruby/object:Gem::Dependency
41
+ name: openssl
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: bundler
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '13.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubocop
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.21'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.21'
110
+ - !ruby/object:Gem::Dependency
111
+ name: yard
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.9'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.9'
124
+ description: An AI-powered Ruby library that performs on-device compromise detection
125
+ for mobile applications without requiring a backend. Detects root/jailbreak, emulators,
126
+ hooking frameworks, and provides behavioral risk analysis.
127
+ email:
128
+ - ahmetxhero@gmail.com
129
+ executables:
130
+ - ai_root_shield
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".rspec"
135
+ - CHANGELOG.md
136
+ - Gemfile
137
+ - Gemfile.lock
138
+ - LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - examples/device_logs/clean_device.json
142
+ - examples/device_logs/rooted_android.json
143
+ - exe/ai_root_shield
144
+ - lib/ai_root_shield.rb
145
+ - lib/ai_root_shield/analyzers/emulator_detector.rb
146
+ - lib/ai_root_shield/analyzers/hooking_detector.rb
147
+ - lib/ai_root_shield/analyzers/integrity_checker.rb
148
+ - lib/ai_root_shield/analyzers/network_analyzer.rb
149
+ - lib/ai_root_shield/analyzers/root_detector.rb
150
+ - lib/ai_root_shield/detector.rb
151
+ - lib/ai_root_shield/device_log_parser.rb
152
+ - lib/ai_root_shield/risk_calculator.rb
153
+ - lib/ai_root_shield/version.rb
154
+ homepage: https://github.com/ahmetxhero/ai-root-shield
155
+ licenses:
156
+ - MIT
157
+ metadata:
158
+ allowed_push_host: https://rubygems.org
159
+ homepage_uri: https://github.com/ahmetxhero/ai-root-shield
160
+ source_code_uri: https://github.com/ahmetxhero/ai-root-shield
161
+ changelog_uri: https://github.com/ahmetxhero/ai-root-shield/blob/main/CHANGELOG.md
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: 2.7.0
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubygems_version: 3.6.9
177
+ specification_version: 4
178
+ summary: AI-powered mobile device compromise detection library
179
+ test_files: []