idb 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +19 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +65 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +2 -0
  9. data/bin/idb +5 -0
  10. data/idb.gemspec +41 -0
  11. data/lib/LICENSE +20 -0
  12. data/lib/README.md +54 -0
  13. data/lib/config/.dummy +0 -0
  14. data/lib/config/settings.yml +8 -0
  15. data/lib/gui/app_binary_tab_widget.rb +45 -0
  16. data/lib/gui/app_details_group_box.rb +213 -0
  17. data/lib/gui/app_list_dialog.rb +67 -0
  18. data/lib/gui/app_list_widget_item.rb +9 -0
  19. data/lib/gui/binary_strings_widget.rb +33 -0
  20. data/lib/gui/browse_filesystem_widget.rb +4 -0
  21. data/lib/gui/ca_manager_dialog.rb +137 -0
  22. data/lib/gui/cache_db_widget.rb +61 -0
  23. data/lib/gui/certificate_item.rb +5 -0
  24. data/lib/gui/console_widget.rb +163 -0
  25. data/lib/gui/cycript_console_widget.rb +68 -0
  26. data/lib/gui/cycript_thread.rb +81 -0
  27. data/lib/gui/device_info_group_box.rb +55 -0
  28. data/lib/gui/device_status_dialog.rb +351 -0
  29. data/lib/gui/file_system_events_widget.rb +4 -0
  30. data/lib/gui/fs_viewer_tab_widget.rb +245 -0
  31. data/lib/gui/i_device_syslog_thread.rb +47 -0
  32. data/lib/gui/images/check.png +0 -0
  33. data/lib/gui/images/folder.ico +0 -0
  34. data/lib/gui/images/iphone.ico +0 -0
  35. data/lib/gui/images/screenshot.png +0 -0
  36. data/lib/gui/key_chain_widget.rb +86 -0
  37. data/lib/gui/local_storage_tab_widget.rb +37 -0
  38. data/lib/gui/log_plain_text_edit.rb +18 -0
  39. data/lib/gui/log_widget.rb +71 -0
  40. data/lib/gui/main_tab_widget.rb +179 -0
  41. data/lib/gui/pasteboard_monitor_widget.rb +116 -0
  42. data/lib/gui/path_list_widget_item.rb +5 -0
  43. data/lib/gui/pb_watcher_thread.rb +63 -0
  44. data/lib/gui/plist_file_widget.rb +66 -0
  45. data/lib/gui/qt_ruby_variant.rb +16 -0
  46. data/lib/gui/screenshot_wizard.rb +169 -0
  47. data/lib/gui/settings_dialog.rb +69 -0
  48. data/lib/gui/settings_tab_widget.rb +149 -0
  49. data/lib/gui/shared_libraries_widget.rb +47 -0
  50. data/lib/gui/snoop_it_fs_events_widget.rb +150 -0
  51. data/lib/gui/snoop_it_keychain_widget.rb +172 -0
  52. data/lib/gui/snoop_it_sensitive_api_widget.rb +128 -0
  53. data/lib/gui/snoop_it_tab_widget.rb +27 -0
  54. data/lib/gui/snoop_it_update_thread.rb +48 -0
  55. data/lib/gui/sqlite_widget.rb +73 -0
  56. data/lib/gui/ssh_port_forward_tab_widget.rb +209 -0
  57. data/lib/gui/tool_widget.rb +94 -0
  58. data/lib/gui/url_handler_widget.rb +26 -0
  59. data/lib/gui/url_scheme_fuzz_widget.rb +103 -0
  60. data/lib/gui/url_scheme_widget.rb +60 -0
  61. data/lib/gui/weak_class_dump_widget.rb +89 -0
  62. data/lib/helper/ssh_port_forwarder.rb +72 -0
  63. data/lib/idb.rb +295 -0
  64. data/lib/idb/version.rb +3 -0
  65. data/lib/lib/CgBI.rb +153 -0
  66. data/lib/lib/abstract_device.rb +31 -0
  67. data/lib/lib/app.rb +286 -0
  68. data/lib/lib/app_binary.rb +57 -0
  69. data/lib/lib/ca_interface.rb +151 -0
  70. data/lib/lib/configuration.rb +0 -0
  71. data/lib/lib/console_launcher.rb +24 -0
  72. data/lib/lib/device.rb +438 -0
  73. data/lib/lib/device_ca_interface.rb +36 -0
  74. data/lib/lib/host_file_wrapper.rb +27 -0
  75. data/lib/lib/i_device_diagnostics_wrapper.rb +90 -0
  76. data/lib/lib/keychain_plist_parser.rb +15 -0
  77. data/lib/lib/local_operations.rb +67 -0
  78. data/lib/lib/otool_wrapper.rb +116 -0
  79. data/lib/lib/plist_util.rb +72 -0
  80. data/lib/lib/qt_thread_fix.rb +29 -0
  81. data/lib/lib/rsync_git_manager.rb +81 -0
  82. data/lib/lib/screen_shot_util.rb +59 -0
  83. data/lib/lib/settings.rb +67 -0
  84. data/lib/lib/simulator.rb +60 -0
  85. data/lib/lib/simulator_ca_interface.rb +16 -0
  86. data/lib/lib/snoop_it_wrapper.rb +80 -0
  87. data/lib/lib/ssh_operations.rb +136 -0
  88. data/lib/lib/ssh_port_forwarder.rb +43 -0
  89. data/lib/lib/tools.rb +11 -0
  90. data/lib/lib/url_scheme_fuzzer.rb +98 -0
  91. data/lib/lib/usb_muxd_wrapper.rb +32 -0
  92. data/lib/lib/weak_class_dump_wrapper.rb +62 -0
  93. data/lib/utils/dumpdecrypted/README +4 -0
  94. data/lib/utils/dumpdecrypted/dumpdecrypted_armv6.dylib +0 -0
  95. data/lib/utils/dumpdecrypted/dumpdecrypted_armv7.dylib +0 -0
  96. data/lib/utils/ios-ssl-kill-switch/com.isecpartners.nabla.sslkillswitch_v0.5-iOS_6.1.deb +0 -0
  97. data/lib/utils/keychain_dump/README +2 -0
  98. data/lib/utils/keychain_dump/keychain_dump +0 -0
  99. data/lib/utils/pbwatcher/pbwatcher +0 -0
  100. data/lib/utils/pcviewer/protectionclassviewer +0 -0
  101. data/lib/utils/weak_class_dump/README +5 -0
  102. data/lib/utils/weak_class_dump/weak_classdump.cy +726 -0
  103. metadata +412 -0
@@ -0,0 +1,36 @@
1
+ require_relative 'ca_interface'
2
+
3
+ module Idb
4
+ class DeviceCAInterface < CAInterface
5
+
6
+ def initialize device
7
+ @device = device
8
+ @device_store_path = "/private/var/Keychains/TrustStore.sqlite3"
9
+ base_path = "#{$tmp_path}/device"
10
+ FileUtils.mkdir_p base_path
11
+ @db_path = "#{base_path}/TrustStore.sqlite3"
12
+
13
+
14
+ end
15
+
16
+
17
+ def get_certs
18
+ @device.ops.download @device_store_path, @db_path
19
+ super
20
+ end
21
+
22
+ def remove_cert cert
23
+ FileUtils.copy_file @db_path, "#{@db_path}-#{Time.now.to_s}"
24
+ super cert
25
+ @device.ops.upload @db_path, @device_store_path
26
+ end
27
+
28
+ def add_cert cert_file
29
+ FileUtils.copy_file @db_path, "#{@db_path}-#{Time.now.to_s}"
30
+ super cert_file
31
+ @device.ops.upload @db_path, @device_store_path
32
+ end
33
+
34
+
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module Idb
2
+ class HostFileWrapper
3
+
4
+ def initialize
5
+ @cache_path = "#{$tmp_path}/device/hosts"
6
+ end
7
+
8
+ def content
9
+ FileUtils.mkpath "#{$tmp_path}/device" unless File.directory? "#{$tmp_path}/device"
10
+ $device.ops.download "/etc/hosts", @cache_path
11
+ begin
12
+ File.open(@cache_path,"r").read
13
+ rescue
14
+
15
+ end
16
+ end
17
+
18
+ def save text
19
+ # upload
20
+ File.open(@cache_path,"w") { |f|
21
+ f.puts text
22
+ }
23
+ $device.ops.upload(@cache_path, "/etc/hosts")
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,90 @@
1
+ require 'ffi'
2
+
3
+ module IMobileDevice
4
+ extend FFI::Library
5
+
6
+ ffi_lib 'libimobiledevice'
7
+ IDeviceEventType = enum(
8
+ :idevice_device_added, 1,
9
+ :idevice_device_remove
10
+ )
11
+
12
+ class IDeviceEventT < FFI::Struct
13
+ layout :event, IDeviceEventType,
14
+ :udid, :string,
15
+ :conn_type, :int
16
+ end
17
+
18
+ ConnectionType = enum(
19
+ :connection_usbmuxd, 1
20
+ )
21
+
22
+ class IDevicePrivate < FFI::Struct
23
+ layout :udid, :string,
24
+ :conn_type, ConnectionType,
25
+ :conn_data, :pointer
26
+ end
27
+
28
+
29
+
30
+ attach_function :idevice_get_device_list, [:pointer, :pointer], :int
31
+ attach_function :idevice_event_subscribe, [:pointer, :pointer], :int
32
+ attach_function :idevice_new, [:pointer, :string], :int
33
+ # attach_function :syslog_relay_client_start_service, [IDevicePrivate, :pointer, :string], :int
34
+ # attach_function :syslog_relay_start_capture, [:pointer, :pointer, :pointer], :int
35
+ # attach_function :syslog_relay_client_free, [:pointer], :int
36
+
37
+ def self.startLogging
38
+ ret = idevice_new(IDevicePrivate, @udid)
39
+ if ret != 0
40
+ puts "ERROR"
41
+ end
42
+
43
+
44
+
45
+
46
+ end
47
+ def self.stopLogging
48
+ puts "stopstopstop"
49
+
50
+ end
51
+
52
+ # DeviceEvn :device, [:pointer, :long, :uint8], :void
53
+
54
+ DeviceEventCB = FFI::Function.new(:void, [:pointer, :pointer]) do |event, userdata|
55
+ # cast event to struct
56
+ event_t = IDeviceEventT.new event
57
+ if event_t[:event] == :idevice_device_added
58
+ if @syslog.nil? or @syslog == false
59
+ if @udid.nil? or @udid == false
60
+ @udid = event_t[:udid]
61
+ end
62
+
63
+ if @udid == event_t[:udid]
64
+ #TODO error checking
65
+ puts "[*] Start Logging"
66
+ IMobileDevice.startLogging
67
+ end
68
+ end
69
+ elsif avent_t[:event] == :idevice_device_remove
70
+ if not @syslog.nil? and @udid == event_t[:udid]
71
+ puts "[*] Disconnected"
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ devices = FFI::MemoryPointer.new :pointer
78
+ num = FFI::MemoryPointer.new :int
79
+ x = IMobileDevice.idevice_get_device_list(devices, num)
80
+ device = devices.read_pointer.get_array_of_string(0,num.read_int).first
81
+ puts "Device #{device}"
82
+ IMobileDevice.idevice_event_subscribe(IMobileDevice::DeviceEventCB, nil)
83
+
84
+
85
+
86
+ while true
87
+
88
+ end
89
+
90
+
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require 'nokogiri'
3
+ require 'plist4r'
4
+ require 'awesome_print'
5
+
6
+ module Idb
7
+ class KeychainPlistParser
8
+ attr_accessor :entries
9
+
10
+ def initialize plist_path
11
+ $log.info 'Parsing keychain plist file..'
12
+ @entries = Plist4r.open(plist_path)["Array"]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,67 @@
1
+ module Idb
2
+ class LocalOperations
3
+
4
+
5
+ def file? path
6
+ File.file? path
7
+ end
8
+
9
+
10
+ def download a, b
11
+ FileUtils.copy_file(a,b)
12
+ return true
13
+ end
14
+
15
+
16
+ def directory? path
17
+ File.directory? path
18
+ end
19
+
20
+ def mtime path
21
+ File.mtime path
22
+ end
23
+
24
+ def open path
25
+ begin
26
+ Launchy.open path
27
+ return true
28
+ rescue Exception => e
29
+ $log.error "Could not open file #{path}: #{e.message}"
30
+ $log.error e.backtrace
31
+ return false
32
+ end
33
+ end
34
+
35
+ def list_dir path
36
+ Dir.entries path
37
+ end
38
+
39
+ def list_dir_full path
40
+ Dir.entries path
41
+ end
42
+
43
+ def dir_glob path, pattern
44
+ full_path = "#{path}/#{pattern}"
45
+ Dir.glob(full_path)
46
+ end
47
+
48
+ def file_exists? file
49
+ File.exists? file
50
+ end
51
+
52
+ def execute cmd
53
+ `#{cmd}`
54
+ end
55
+
56
+ def execute_fork cmd
57
+ (pid = fork) ? Process.detach(pid) : exec(cmd)
58
+ end
59
+
60
+ def launch_app command, app
61
+ $log.info "Executing #{command} #{app}"
62
+ self.execute_fork("#{command} \"#{app}\"")
63
+ end
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,116 @@
1
+ require 'awesome_print'
2
+
3
+ module Idb
4
+ class OtoolWrapper
5
+ attr_accessor :load_commands, :shared_libraries, :pie, :arc, :canaries
6
+
7
+ def initialize binary
8
+ @otool_path = "/usr/bin/otool"
9
+ unless File.exist? @otool_path.to_s
10
+ $log.error "otool not available. Some functions will not work properly."
11
+ error = Qt::MessageBox.new
12
+ error.setInformativeText("This feature requires otool to be installed on the host running idb. This is the default on OS X but it may not be available for other platforms.")
13
+ error.setIcon(Qt::MessageBox::Critical)
14
+ error.exec
15
+ @otool_path = nil
16
+
17
+ return
18
+ end
19
+
20
+ @binary = binary
21
+ parse_load_commands
22
+ parse_shared_libraries
23
+ parse_header
24
+ process_symbol_table
25
+ end
26
+
27
+
28
+ private
29
+ def parse_shared_libraries
30
+ if @otool_path.nil?
31
+ @shared_libraries = Array.new
32
+ @shared_libraries << "Error; otool not available"
33
+ return
34
+ end
35
+ @raw_shared_libraries_output = `#{@otool_path} -L '#{@binary}'`
36
+ lines = @raw_shared_libraries_output.split("\n")
37
+ @shared_libraries = lines[1,lines.size].map{ |x| x.strip} unless lines.nil?
38
+ end
39
+
40
+ def process_symbol_table
41
+ if @otool_path.nil?
42
+ @canaries = "Error"
43
+ @arc = "Error"
44
+ return
45
+ end
46
+ symbols = `#{@otool_path} -I -v '#{@binary}'`
47
+ if symbols.include? "stack_chk_fail" or symbols.include? "stack_chk_guard"
48
+ @canaries = true
49
+ else
50
+ @canaries = false
51
+ end
52
+
53
+ if symbols.include? "_objc_release"
54
+ @arc = true
55
+ else
56
+ @arc = false
57
+ end
58
+ end
59
+
60
+
61
+
62
+
63
+ def parse_header
64
+ if @otool_path.nil?
65
+ @pie = "Error"
66
+ return
67
+ end
68
+ pie_flag = 0x00200000
69
+ @raw_load_output = `#{@otool_path} -h '#{@binary}'`
70
+
71
+ # fourth row contains values. then split them up.
72
+ vals = @raw_load_output.split("\n")[3].split(" ")
73
+
74
+ #7th field contains the flags
75
+ flags = vals[7].to_i(16)
76
+
77
+ if flags & pie_flag == pie_flag
78
+ @pie = true
79
+ else
80
+ @pie = false
81
+ end
82
+
83
+
84
+ end
85
+
86
+ def parse_load_commands
87
+ if @otool_path.nil?
88
+ @load_commands = nil
89
+ return
90
+ end
91
+ @raw_load_output = `#{@otool_path} -l '#{@binary}'`
92
+ delim = "Load command"
93
+ regex_cmd = /Load command (\d+)/
94
+ regex_parse_key_vals = /\s*(cmd|cryptid)\s(.+)/
95
+
96
+ @load_commands = Hash.new
97
+
98
+ @raw_load_output.split("\n").each {|line|
99
+
100
+ if match = regex_cmd.match(line)
101
+ @load_commands[@cmd] = @command unless @cmd.nil?
102
+ @cmd = match[1]
103
+ @command = Hash.new
104
+ end
105
+
106
+ if match = regex_parse_key_vals.match(line)
107
+ @command[match[1]] = match[2]
108
+ end
109
+ }
110
+ end
111
+
112
+
113
+
114
+
115
+ end
116
+ end
@@ -0,0 +1,72 @@
1
+ require 'plist4r'
2
+ require 'rbconfig'
3
+ require 'nokogiri'
4
+ require 'coderay'
5
+
6
+ module Idb
7
+ class PlistUtil
8
+
9
+ attr_accessor :schemas, :binary_name, :bundle_identifier, :plist_data, :plist_file
10
+
11
+ def initialize(plist_file)
12
+ @plist_file = plist_file
13
+
14
+ @plutil = Pathname.new("/usr/bin/plutil")
15
+ if(!@plutil.exist?)
16
+ raise "plutil not found at #{@plutil}. aborting."
17
+ end
18
+
19
+ parse_plist_file
20
+ end
21
+
22
+ def parse_info_plist
23
+ extract_binary_name
24
+ extract_url_handlers
25
+ end
26
+
27
+ def dump
28
+ doc = Nokogiri::XML(File.open(@plist_file)) do |config|
29
+ config.nonet.noblanks
30
+ end
31
+ puts CodeRay.scan(doc.to_xml(:indent => 2), :xml).terminal
32
+ end
33
+
34
+ private
35
+ def parse_plist_file
36
+ $log.info 'Parsing plist file..'
37
+
38
+ # Make sure plist file is in xml and not binary
39
+ if RbConfig::CONFIG['host_os'] =~ /linux/
40
+ `#{@plutil.realpath} -i "#{@plist_file}" -o "#{@plist_file}"`
41
+ else
42
+ `#{@plutil.realpath} -convert xml1 "#{@plist_file}"`
43
+ end
44
+
45
+ # @plist_data = Plist::parse_xml(@plist_file)
46
+ @plist_data = Plist4r.open @plist_file
47
+ end
48
+
49
+ def extract_url_handlers
50
+ @schemas = Array.new
51
+
52
+ if @plist_data['CFBundleURLTypes'] != nil
53
+ for type in @plist_data['CFBundleURLTypes']
54
+ if !type.nil? and !type['CFBundleURLSchemes'].nil?
55
+ @schemas += type['CFBundleURLSchemes']
56
+ else
57
+ @schemas += ['None']
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def extract_binary_name
64
+ @binary_name = @plist_data['CFBundleExecutable']
65
+ @bundle_identifier = @plist_data['CFBundleIdentifier']
66
+ end
67
+
68
+
69
+
70
+
71
+ end
72
+ end
@@ -0,0 +1,29 @@
1
+ require 'thread'
2
+
3
+ module Idb
4
+ class QtThreadFix < Qt::Object
5
+ slots 'ruby_thread_timeout()'
6
+ @@ruby_thread_queue = Queue.new
7
+
8
+ def initialize
9
+ super()
10
+ # Enable threading
11
+ @ruby_thread_sleep_period = 0.01
12
+ @ruby_thread_timer = Qt::Timer.new(self)
13
+ connect(@ruby_thread_timer, SIGNAL('timeout()'), SLOT('ruby_thread_timeout()'))
14
+ @ruby_thread_timer.method_missing(:start, 0)
15
+ end
16
+
17
+ def ruby_thread_timeout
18
+ unless @@ruby_thread_queue.empty?
19
+ proc_to_call = @@ruby_thread_queue.pop
20
+ proc_to_call.call
21
+ end
22
+ sleep(@ruby_thread_sleep_period)
23
+ end
24
+
25
+ def self.ruby_thread_queue
26
+ @@ruby_thread_queue
27
+ end
28
+ end
29
+ end