idb 1.3.1
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.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +65 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bin/idb +5 -0
- data/idb.gemspec +41 -0
- data/lib/LICENSE +20 -0
- data/lib/README.md +54 -0
- data/lib/config/.dummy +0 -0
- data/lib/config/settings.yml +8 -0
- data/lib/gui/app_binary_tab_widget.rb +45 -0
- data/lib/gui/app_details_group_box.rb +213 -0
- data/lib/gui/app_list_dialog.rb +67 -0
- data/lib/gui/app_list_widget_item.rb +9 -0
- data/lib/gui/binary_strings_widget.rb +33 -0
- data/lib/gui/browse_filesystem_widget.rb +4 -0
- data/lib/gui/ca_manager_dialog.rb +137 -0
- data/lib/gui/cache_db_widget.rb +61 -0
- data/lib/gui/certificate_item.rb +5 -0
- data/lib/gui/console_widget.rb +163 -0
- data/lib/gui/cycript_console_widget.rb +68 -0
- data/lib/gui/cycript_thread.rb +81 -0
- data/lib/gui/device_info_group_box.rb +55 -0
- data/lib/gui/device_status_dialog.rb +351 -0
- data/lib/gui/file_system_events_widget.rb +4 -0
- data/lib/gui/fs_viewer_tab_widget.rb +245 -0
- data/lib/gui/i_device_syslog_thread.rb +47 -0
- data/lib/gui/images/check.png +0 -0
- data/lib/gui/images/folder.ico +0 -0
- data/lib/gui/images/iphone.ico +0 -0
- data/lib/gui/images/screenshot.png +0 -0
- data/lib/gui/key_chain_widget.rb +86 -0
- data/lib/gui/local_storage_tab_widget.rb +37 -0
- data/lib/gui/log_plain_text_edit.rb +18 -0
- data/lib/gui/log_widget.rb +71 -0
- data/lib/gui/main_tab_widget.rb +179 -0
- data/lib/gui/pasteboard_monitor_widget.rb +116 -0
- data/lib/gui/path_list_widget_item.rb +5 -0
- data/lib/gui/pb_watcher_thread.rb +63 -0
- data/lib/gui/plist_file_widget.rb +66 -0
- data/lib/gui/qt_ruby_variant.rb +16 -0
- data/lib/gui/screenshot_wizard.rb +169 -0
- data/lib/gui/settings_dialog.rb +69 -0
- data/lib/gui/settings_tab_widget.rb +149 -0
- data/lib/gui/shared_libraries_widget.rb +47 -0
- data/lib/gui/snoop_it_fs_events_widget.rb +150 -0
- data/lib/gui/snoop_it_keychain_widget.rb +172 -0
- data/lib/gui/snoop_it_sensitive_api_widget.rb +128 -0
- data/lib/gui/snoop_it_tab_widget.rb +27 -0
- data/lib/gui/snoop_it_update_thread.rb +48 -0
- data/lib/gui/sqlite_widget.rb +73 -0
- data/lib/gui/ssh_port_forward_tab_widget.rb +209 -0
- data/lib/gui/tool_widget.rb +94 -0
- data/lib/gui/url_handler_widget.rb +26 -0
- data/lib/gui/url_scheme_fuzz_widget.rb +103 -0
- data/lib/gui/url_scheme_widget.rb +60 -0
- data/lib/gui/weak_class_dump_widget.rb +89 -0
- data/lib/helper/ssh_port_forwarder.rb +72 -0
- data/lib/idb.rb +295 -0
- data/lib/idb/version.rb +3 -0
- data/lib/lib/CgBI.rb +153 -0
- data/lib/lib/abstract_device.rb +31 -0
- data/lib/lib/app.rb +286 -0
- data/lib/lib/app_binary.rb +57 -0
- data/lib/lib/ca_interface.rb +151 -0
- data/lib/lib/configuration.rb +0 -0
- data/lib/lib/console_launcher.rb +24 -0
- data/lib/lib/device.rb +438 -0
- data/lib/lib/device_ca_interface.rb +36 -0
- data/lib/lib/host_file_wrapper.rb +27 -0
- data/lib/lib/i_device_diagnostics_wrapper.rb +90 -0
- data/lib/lib/keychain_plist_parser.rb +15 -0
- data/lib/lib/local_operations.rb +67 -0
- data/lib/lib/otool_wrapper.rb +116 -0
- data/lib/lib/plist_util.rb +72 -0
- data/lib/lib/qt_thread_fix.rb +29 -0
- data/lib/lib/rsync_git_manager.rb +81 -0
- data/lib/lib/screen_shot_util.rb +59 -0
- data/lib/lib/settings.rb +67 -0
- data/lib/lib/simulator.rb +60 -0
- data/lib/lib/simulator_ca_interface.rb +16 -0
- data/lib/lib/snoop_it_wrapper.rb +80 -0
- data/lib/lib/ssh_operations.rb +136 -0
- data/lib/lib/ssh_port_forwarder.rb +43 -0
- data/lib/lib/tools.rb +11 -0
- data/lib/lib/url_scheme_fuzzer.rb +98 -0
- data/lib/lib/usb_muxd_wrapper.rb +32 -0
- data/lib/lib/weak_class_dump_wrapper.rb +62 -0
- data/lib/utils/dumpdecrypted/README +4 -0
- data/lib/utils/dumpdecrypted/dumpdecrypted_armv6.dylib +0 -0
- data/lib/utils/dumpdecrypted/dumpdecrypted_armv7.dylib +0 -0
- data/lib/utils/ios-ssl-kill-switch/com.isecpartners.nabla.sslkillswitch_v0.5-iOS_6.1.deb +0 -0
- data/lib/utils/keychain_dump/README +2 -0
- data/lib/utils/keychain_dump/keychain_dump +0 -0
- data/lib/utils/pbwatcher/pbwatcher +0 -0
- data/lib/utils/pcviewer/protectionclassviewer +0 -0
- data/lib/utils/weak_class_dump/README +5 -0
- data/lib/utils/weak_class_dump/weak_classdump.cy +726 -0
- metadata +412 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require_relative 'otool_wrapper'
|
|
2
|
+
require_relative 'app'
|
|
3
|
+
|
|
4
|
+
module Idb
|
|
5
|
+
class AppBinary
|
|
6
|
+
|
|
7
|
+
def initialize app_binary
|
|
8
|
+
@otool = OtoolWrapper.new app_binary
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def get_shared_libraries
|
|
12
|
+
@otool.shared_libraries
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def setDecryptedPath path
|
|
16
|
+
@decrypted_path = path
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def is_pie?
|
|
20
|
+
@otool.pie
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def is_stack_protected?
|
|
25
|
+
@otool.canaries
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def uses_arc?
|
|
29
|
+
@otool.arc
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def is_encrypted?
|
|
33
|
+
encrypted = false
|
|
34
|
+
if @otool.load_commands.nil?
|
|
35
|
+
return "Error"
|
|
36
|
+
end
|
|
37
|
+
@otool.load_commands.each {|key, val|
|
|
38
|
+
if val['cmd'].strip.start_with?('LC_ENCRYPTION_INFO') and val['cryptid'].strip == 1.to_s
|
|
39
|
+
encrypted = true
|
|
40
|
+
end
|
|
41
|
+
}
|
|
42
|
+
return encrypted
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_cryptid
|
|
46
|
+
if @otool.load_commands.nil?
|
|
47
|
+
return "Error"
|
|
48
|
+
end
|
|
49
|
+
@otool.load_commands.each {|key, val|
|
|
50
|
+
if val['cmd'] == 'LC_ENCRYPTION_INFO'
|
|
51
|
+
return val['cryptid']
|
|
52
|
+
end
|
|
53
|
+
}
|
|
54
|
+
return nil
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'digest/sha1'
|
|
3
|
+
require 'sqlite3'
|
|
4
|
+
require "webrick"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
module Idb
|
|
9
|
+
class CAInterface
|
|
10
|
+
|
|
11
|
+
# performs uninstall based on sha1 hash provided in certfile
|
|
12
|
+
def remove_cert cert
|
|
13
|
+
der = cert.to_der
|
|
14
|
+
|
|
15
|
+
query = %Q|DELETE FROM "tsettings" WHERE sha1 = #{blobify(sha1_from_der der)};|
|
|
16
|
+
begin
|
|
17
|
+
db = SQLite3::Database.new(@db_path)
|
|
18
|
+
db.execute(query)
|
|
19
|
+
db.close
|
|
20
|
+
rescue Exception => e
|
|
21
|
+
raise "[*] Error writing to SQLite database at #{@db_path}: #{e.message}"
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
puts "[*] Operation complete"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def server_cert cert_file
|
|
28
|
+
FileUtils.mkpath "#{$tmp_path}/CAs"
|
|
29
|
+
cert_file_cache = "#{$tmp_path}/CAs/CA.pem"
|
|
30
|
+
|
|
31
|
+
FileUtils.copy cert_file, cert_file_cache
|
|
32
|
+
#copy cert file to tmp
|
|
33
|
+
@server_thread = Thread.new {
|
|
34
|
+
@server = WEBrick::HTTPServer.new(:Port => $settings['idb_utility_port'])
|
|
35
|
+
@server.mount "/", WEBrick::HTTPServlet::FileHandler, "#{$tmp_path}/CAs/"
|
|
36
|
+
@server.start
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
sleep 0.5
|
|
40
|
+
$device.open_url "http://localhost:#{$settings['idb_utility_port']}/CA.pem"
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def stop_cert_server
|
|
45
|
+
@server.stop unless @server.nil?
|
|
46
|
+
@server_thread.terminate unless @server_thread.nil?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def add_cert cert_file
|
|
51
|
+
cert_file = File.expand_path(cert_file)
|
|
52
|
+
if not File.exist? cert_file
|
|
53
|
+
raise "File #{cert_file} does not exist."
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
cert = parse_certificate cert_file
|
|
57
|
+
|
|
58
|
+
# create plist file
|
|
59
|
+
#TODO might want to use the plist library instead
|
|
60
|
+
tset = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array/>\n</plist>\n"
|
|
61
|
+
data = cert[:cert].to_der
|
|
62
|
+
|
|
63
|
+
puts "[*] Inserting certificate into trust store..."
|
|
64
|
+
|
|
65
|
+
query = %Q|INSERT INTO "tsettings" VALUES(#{blobify(cert[:fprint])},#{blobify(cert[:subject])},#{blobify(tset)},#{blobify(data)});|
|
|
66
|
+
begin
|
|
67
|
+
db = SQLite3::Database.new(@db_path)
|
|
68
|
+
db.execute(query)
|
|
69
|
+
db.close
|
|
70
|
+
rescue Exception => e
|
|
71
|
+
if e.message.include? "column sha1 is not unique"
|
|
72
|
+
raise "The same certificate is installed already."
|
|
73
|
+
else
|
|
74
|
+
raise "Error writing to SQLite database at #{@db_path}: #{e.message}"
|
|
75
|
+
end
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def get_certs
|
|
81
|
+
query = %Q|SELECT * FROM "tsettings";|
|
|
82
|
+
begin
|
|
83
|
+
db = SQLite3::Database.new(@db_path)
|
|
84
|
+
result = db.execute(query)
|
|
85
|
+
db.close
|
|
86
|
+
rescue Exception => e
|
|
87
|
+
raise "Error reading from SQLite database at #{@db_path}: #{e.message}"
|
|
88
|
+
end
|
|
89
|
+
result.map { |x|
|
|
90
|
+
OpenSSL::X509::Certificate.new(x[3])
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def sha1_from_der der
|
|
96
|
+
Digest::SHA1.digest(der)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def string_to_hex(s)
|
|
102
|
+
s.unpack('H*')[0]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def blobify(bin)
|
|
106
|
+
"X'#{string_to_hex bin}'"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def parse_certificate cert_file
|
|
110
|
+
puts "[*] Reading and converting certificate..."
|
|
111
|
+
# Open and convert certificate
|
|
112
|
+
cert = OpenSSL::X509::Certificate.new(File.read(cert_file))
|
|
113
|
+
fprint = sha1_from_der cert.to_der
|
|
114
|
+
subj = cert.subject.to_der
|
|
115
|
+
puts subj.inspect
|
|
116
|
+
# Thanks Andy Schmitz
|
|
117
|
+
#toSkip = (subj[1].ord & 0x80) == 0 ? 2 : ((subj[2].ord & 0x7f) + 2)
|
|
118
|
+
toSkip = 3
|
|
119
|
+
subj = subj[toSkip..-1]
|
|
120
|
+
# subj = subj.gsub("PortSwigger","PORTSWIGGER")
|
|
121
|
+
#subj = "1\v0\t\x06\x03U\x04\x06\x13\x02US1\v0\t\x06\x03U\x04\b\x13\x02IL1\x100\x0E\x06\x03U\x04\a\x13\aCHICAGO1\x1A0\x18\x06\x03U\x04\n\x13\x11MATASANO SECURITY1\e0\x19\x06\x03U\x04\v\x13\x12PENTESTING MADNESS1\x1F0\x1D\x06\x03U\x04\x03\x13\x16CA.DANIEL.MATASANO.COM"
|
|
122
|
+
puts subj.inspect
|
|
123
|
+
|
|
124
|
+
#subj = "1\x140\x12\x06\x03U\x04\x06\x13\vPORTSWIGGER1\x140\x12\x06\x03U\x04\b\x13\vPORTSWIGGER1\x140\x12\x06\x03U\x04\a\x13\vPORTSWIGGER1\x140\x12\x06\x03U\x04\n\x13\vPORTSWIGGER1\x170\x15\x06\x03U\x04\v\x13\x0EPORTSWIGGER CA1\x170\x15\x06\x03U\x04\x03\x13\x0EPORTSWIGGER CA"
|
|
125
|
+
|
|
126
|
+
return {:cert => cert, :fprint => fprint, :subject => subj}
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def validate? cert_file
|
|
131
|
+
if not File.exist? cert_file
|
|
132
|
+
puts "File #{cert_file} does not exist."
|
|
133
|
+
return false
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if not File.file? cert_file
|
|
137
|
+
puts "#{cert_file} is not a file."
|
|
138
|
+
return false
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
return true
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
class CAServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
146
|
+
def do_GET (request, response)
|
|
147
|
+
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Idb
|
|
2
|
+
class ConsoleLauncher
|
|
3
|
+
|
|
4
|
+
def initialize
|
|
5
|
+
# if os x
|
|
6
|
+
#'/Applications/iTerm.app'
|
|
7
|
+
# '/Applications/Utilities/Terminal.app/ '
|
|
8
|
+
#if linux
|
|
9
|
+
# terminator, gnome-terminal, Konsole(?), xterm
|
|
10
|
+
@term = "terminator"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def run cmd
|
|
15
|
+
command = "#{@term} -x sh -c '#{cmd}'"
|
|
16
|
+
puts command
|
|
17
|
+
Process.spawn command
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/lib/device.rb
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require_relative 'abstract_device'
|
|
4
|
+
require_relative 'ssh_port_forwarder'
|
|
5
|
+
require_relative 'device_ca_interface'
|
|
6
|
+
require_relative 'usb_muxd_wrapper'
|
|
7
|
+
|
|
8
|
+
module Idb
|
|
9
|
+
class Device < AbstractDevice
|
|
10
|
+
attr_accessor :usb_ssh_port, :mode, :tool_port
|
|
11
|
+
|
|
12
|
+
def initialize username, password, hostname, port
|
|
13
|
+
@apps_dir = '/private/var/mobile/Applications'
|
|
14
|
+
@username = username
|
|
15
|
+
@password = password
|
|
16
|
+
@hostname = hostname
|
|
17
|
+
@port = port
|
|
18
|
+
|
|
19
|
+
@app = nil
|
|
20
|
+
|
|
21
|
+
@device_app_paths = Hash.new
|
|
22
|
+
@device_app_paths[:cycript] = [ "/usr/bin/cycript" ]
|
|
23
|
+
@device_app_paths[:rsync] = [ "/usr/bin/rsync" ]
|
|
24
|
+
@device_app_paths[:open] = ["/usr/bin/open"]
|
|
25
|
+
@device_app_paths[:openurl] = ["/usr/bin/uiopen", "/usr/bin/openurl", "/usr/bin/openURL"]
|
|
26
|
+
@device_app_paths[:aptget] = ["/usr/bin/apt-get", "/usr/bin/aptitude"]
|
|
27
|
+
@device_app_paths[:keychaindump] = [ "/var/root/keychain_dump"]
|
|
28
|
+
@device_app_paths[:pcviewer] = ["/var/root/protectionclassviewer"]
|
|
29
|
+
@device_app_paths[:pbwatcher] = ["/var/root/pbwatcher"]
|
|
30
|
+
@device_app_paths[:dumpdecrypted_armv7] = ["/var/root/dumpdecrypted_armv7.dylib"]
|
|
31
|
+
@device_app_paths[:dumpdecrypted_armv6] = ["/var/root/dumpdecrypted_armv6.dylib"]
|
|
32
|
+
@device_app_paths[:clutch] = ["/usr/bin/Clutch"]
|
|
33
|
+
|
|
34
|
+
if $settings['device_connection_mode'] == "ssh"
|
|
35
|
+
$log.debug "Connecting via SSH"
|
|
36
|
+
@mode = 'ssh'
|
|
37
|
+
@ops = SSHOperations.new username, password, hostname, port
|
|
38
|
+
else
|
|
39
|
+
$log.debug "Connecting via USB"
|
|
40
|
+
@mode = 'usb'
|
|
41
|
+
@usbmuxd = USBMuxdWrapper.new
|
|
42
|
+
proxy_port = @usbmuxd.find_available_port
|
|
43
|
+
$log.debug "Using port #{proxy_port} for SSH forwarding"
|
|
44
|
+
|
|
45
|
+
@usbmuxd.proxy proxy_port, $settings['ssh_port']
|
|
46
|
+
sleep 1
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@ops = SSHOperations.new username, password, 'localhost', proxy_port
|
|
52
|
+
|
|
53
|
+
@usb_ssh_port = $settings['manual_ssh_port']
|
|
54
|
+
$log.debug "opening port #{proxy_port} for manual ssh connection"
|
|
55
|
+
@usbmuxd.proxy @usb_ssh_port, $settings['ssh_port']
|
|
56
|
+
|
|
57
|
+
@tool_port = @usbmuxd.find_available_port
|
|
58
|
+
$log.debug "opening tool port #{@tool_port} for internal ssh connection"
|
|
59
|
+
@usbmuxd.proxy @tool_port, $settings['ssh_port']
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
start_port_forwarding
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def ssh
|
|
67
|
+
@ops.ssh
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def disconnect
|
|
72
|
+
@ops.disconnect
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def device?
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def arch
|
|
80
|
+
"armv7"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def start_port_forwarding
|
|
84
|
+
@port_forward_pid = Process.spawn("#{RbConfig.ruby} lib/helper/ssh_port_forwarder.rb" )
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def restart_port_forwarding
|
|
88
|
+
$log.info "Restarting SSH port forwarding"
|
|
89
|
+
Process.kill("INT", @port_forward_pid)
|
|
90
|
+
start_port_forwarding
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def protection_class file
|
|
94
|
+
@ops.execute "#{pcviewer_path} '#{file}'"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def simulator?
|
|
98
|
+
false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def app_launch app
|
|
102
|
+
@ops.launch_app(open_path, app.bundle_id)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def dump_keychain
|
|
107
|
+
device_store_path = "/var/root/genp.plist"
|
|
108
|
+
local_dir = "#{$tmp_path}/device/"
|
|
109
|
+
local_path = "#{local_dir}/genp.plist"
|
|
110
|
+
FileUtils.mkdir_p local_dir unless Dir.exist? local_dir
|
|
111
|
+
|
|
112
|
+
$log.info "Dumping keychain..."
|
|
113
|
+
@ops.execute "#{keychain_dump_path}"
|
|
114
|
+
$log.info "Downloading dumped keychain..."
|
|
115
|
+
@ops.download device_store_path, local_path
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def is_installed? tool
|
|
122
|
+
$log.info "Checking if #{tool} is installed..."
|
|
123
|
+
if path_for(tool).nil?
|
|
124
|
+
$log.warn "#{tool} not found."
|
|
125
|
+
false
|
|
126
|
+
else
|
|
127
|
+
$log.info "#{tool} found at #{path_for(tool)}."
|
|
128
|
+
true
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def path_for tool
|
|
133
|
+
@device_app_paths[tool].each { |x|
|
|
134
|
+
if @ops.file_exists? x
|
|
135
|
+
return x
|
|
136
|
+
end
|
|
137
|
+
}
|
|
138
|
+
return nil
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def install_dumpdecrypted
|
|
143
|
+
upload_dumpdecrypted
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def install_dumpdecrypted_old
|
|
147
|
+
unless File.exist? "utils/dumpdecrypted/dumpdecrypted.dylib"
|
|
148
|
+
puts "[**] Warning: dumpdecrypted not compiled."
|
|
149
|
+
puts "[**] Due to licensing issue we cannot ship the compiled library with this tool."
|
|
150
|
+
puts "[**] Attempting compilation (requires a valid iOS SDK installation)..."
|
|
151
|
+
compile_dumpdecrypted
|
|
152
|
+
|
|
153
|
+
if File.exist? "utils/dumpdecrypted/dumpdecrypted.dylib"
|
|
154
|
+
puts "[**] Compilation successful."
|
|
155
|
+
upload_dumpdecryted
|
|
156
|
+
else
|
|
157
|
+
puts "[**] Error: Compilation failed."
|
|
158
|
+
puts "[**] Change into the utils/dumpdecrypted directory, adjust the makefile, and compile."
|
|
159
|
+
end
|
|
160
|
+
else
|
|
161
|
+
upload_dumpdecryted
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def compile_dumpdecrypted
|
|
167
|
+
base_dir = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer'
|
|
168
|
+
unless Dir.exist? base_dir
|
|
169
|
+
puts "[**] Error, iOS Platform tools not found at #{base_dir}"
|
|
170
|
+
return
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
bin_dir = "#{base_dir}/usr/bin"
|
|
175
|
+
sdk_dir = Dir.glob("#{base_dir}/SDKs/iPhoneOS*.sdk/").first
|
|
176
|
+
puts "[*] Found SDK dir: #{sdk_dir}"
|
|
177
|
+
|
|
178
|
+
library_name = "dumpdecrypted.dylib"
|
|
179
|
+
gcc = "#{bin_dir}/gcc"
|
|
180
|
+
|
|
181
|
+
unless File.exist? gcc
|
|
182
|
+
puts "[**] Error: gcc not found at #{gcc}"
|
|
183
|
+
puts "[**] Ensure that the Command Line Utilities are installed in XCode 4."
|
|
184
|
+
puts "[**] XCode 5 does not ship with llvm-gcc anymore."
|
|
185
|
+
return
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
params = ["-arch armv7", # adjust if necessary
|
|
191
|
+
"-wimplicit",
|
|
192
|
+
"-isysroot #{sdk_dir}",
|
|
193
|
+
"-F#{sdk_dir}System/Library/Frameworks",
|
|
194
|
+
"-F#{sdk_dir}System/Library/PrivateFrameworks",
|
|
195
|
+
"-dynamiclib",
|
|
196
|
+
"-o #{library_name}"].join(' ')
|
|
197
|
+
|
|
198
|
+
compile_cmd = "#{gcc} #{params} dumpdecrypted.c"
|
|
199
|
+
puts "Running #{compile_cmd}"
|
|
200
|
+
|
|
201
|
+
Dir.chdir("utils/dumpdecrypted") do
|
|
202
|
+
`#{compile_cmd}`
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def upload_dumpdecrypted
|
|
208
|
+
$log.info "Uploading dumpdecrypted library..."
|
|
209
|
+
@ops.upload("utils/dumpdecrypted/dumpdecrypted_armv6.dylib","/var/root/dumpdecrypted_armv6.dylib")
|
|
210
|
+
@ops.upload("utils/dumpdecrypted/dumpdecrypted_armv7.dylib","/var/root/dumpdecrypted_armv7.dylib")
|
|
211
|
+
$log.info "'dumpdecrypted' installed successfully."
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def install_keychain_dump
|
|
215
|
+
if File.exist? "utils/keychain_dump/keychain_dump"
|
|
216
|
+
upload_keychain_dump
|
|
217
|
+
else
|
|
218
|
+
$log.error "keychain_dump not found at 'utils/keychain_dump/keychain_dump'."
|
|
219
|
+
false
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
def install_pcviewer
|
|
223
|
+
if File.exist? "utils/pcviewer/protectionclassviewer"
|
|
224
|
+
upload_pcviewer
|
|
225
|
+
else
|
|
226
|
+
$log.error "protectionclassviewer not found at 'utils/pcviewer/protectionclassviewer'."
|
|
227
|
+
false
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def install_pbwatcher
|
|
233
|
+
if File.exist? "utils/pbwatcher/pbwatcher"
|
|
234
|
+
upload_pbwatcher
|
|
235
|
+
else
|
|
236
|
+
$log.error "pbwatcher not found at 'utils/pbwatcher/pbwatcher'."
|
|
237
|
+
false
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def upload_pcviewer
|
|
242
|
+
begin
|
|
243
|
+
$log.info "Uploading pcviewer..."
|
|
244
|
+
@ops.upload "utils/pcviewer/protectionclassviewer", "/var/root/protectionclassviewer"
|
|
245
|
+
@ops.chmod "/var/root/protectionclassviewer", 0744
|
|
246
|
+
$log.info "'pcviewer' installed successfully."
|
|
247
|
+
# true
|
|
248
|
+
# rescue
|
|
249
|
+
$log.error "Exception encountered when uploading pcviewer"
|
|
250
|
+
# false
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def upload_keychain_dump
|
|
255
|
+
begin
|
|
256
|
+
$log.info "Uploading keychain_dump..."
|
|
257
|
+
@ops.upload "utils/keychain_dump/keychain_dump", "/var/root/keychain_dump"
|
|
258
|
+
@ops.chmod "/var/root/keychain_dump", 0744
|
|
259
|
+
$log.info "'keychain_dump' installed successfully."
|
|
260
|
+
# true
|
|
261
|
+
# rescue
|
|
262
|
+
$log.error "Exception encountered when uploading keychain_dump"
|
|
263
|
+
# false
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
def upload_pbwatcher
|
|
267
|
+
begin
|
|
268
|
+
$log.info "Uploading pbwatcher..."
|
|
269
|
+
@ops.upload "utils/pbwatcher/pbwatcher", "/var/root/pbwatcher"
|
|
270
|
+
@ops.chmod "/var/root/pbwatcher", 0744
|
|
271
|
+
$log.info "'pbwatcher' installed successfully."
|
|
272
|
+
# true
|
|
273
|
+
# rescue
|
|
274
|
+
$log.error "Exception encountered when uploading pbwatcher"
|
|
275
|
+
# false
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def setup_clutch_sources
|
|
280
|
+
@ops.execute("echo “deb http://cydia.iphonecake.com ./“ > /etc/apt/sources.list.d/idb_clutch.list")
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def install_from_cydia package
|
|
284
|
+
if apt_get_installed?
|
|
285
|
+
$log.info "Updating package repo..."
|
|
286
|
+
@ops.execute("#{apt_get_path} -y update")
|
|
287
|
+
$log.info "Installing #{package}..."
|
|
288
|
+
@ops.execute("#{apt_get_path} -y install #{package}")
|
|
289
|
+
return true
|
|
290
|
+
else
|
|
291
|
+
$log.error "apt-get or aptitude not found on the device"
|
|
292
|
+
return false
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def install_open
|
|
297
|
+
install_from_cydia "com.conradkramer.open"
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def install_clutch
|
|
301
|
+
install_from_cydia "com.iphonecake.clutch"
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def install_rsync
|
|
305
|
+
install_from_cydia "rsync"
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def install_cycript
|
|
309
|
+
install_from_cydia "cycript"
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def close
|
|
313
|
+
$log.info "Terminating port forwarding helper..."
|
|
314
|
+
Process.kill("INT", @port_forward_pid)
|
|
315
|
+
$log.info "Stopping any SSH via USB forwarding"
|
|
316
|
+
@usbmuxd.stop_all
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def open_url url
|
|
320
|
+
$log.info "Executing: #{openurl_path} #{url}"
|
|
321
|
+
@ops.execute "#{openurl_path} #{url}"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def ca_interface
|
|
325
|
+
DeviceCAInterface.new self
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def kill_by_name process_name
|
|
329
|
+
@ops.execute "killall -9 #{process_name}"
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def DEVICE_ID
|
|
333
|
+
$log.error "Not implemented"
|
|
334
|
+
nil
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def configured?
|
|
338
|
+
if $settings['devices'].nil?
|
|
339
|
+
false
|
|
340
|
+
elsif $settings['devices'][device_id].nil?
|
|
341
|
+
false
|
|
342
|
+
else
|
|
343
|
+
true
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def cycript_installed?
|
|
350
|
+
is_installed? :cycript
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def keychain_dump_installed?
|
|
354
|
+
is_installed? :keychaindump
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def pcviewer_installed?
|
|
358
|
+
is_installed? :pcviewer
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def pbwatcher_installed?
|
|
362
|
+
is_installed? :pbwatcher
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def dumpdecrypted_installed?
|
|
366
|
+
is_installed? :dumpdecrypted_armv6 and is_installed? :dumpdecrypted_armv7
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def rsync_installed?
|
|
371
|
+
is_installed? :rsync
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
def open_installed?
|
|
375
|
+
is_installed? :open
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def openurl_installed?
|
|
379
|
+
is_installed? :openurl
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def apt_get_installed?
|
|
383
|
+
is_installed? :aptget
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
def clutch_installed?
|
|
387
|
+
is_installed? :clutch
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def keychain_dump_path
|
|
391
|
+
path_for :keychaindump
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def pcviewer_path
|
|
397
|
+
path_for :pcviewer
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def pbwatcher_path
|
|
402
|
+
path_for :pbwatcher
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def dumpdecrypted_path
|
|
407
|
+
path_for :dumpdecrypted_armv7
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def rsync_path
|
|
411
|
+
path_for :rsync
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def open_path
|
|
416
|
+
path_for :open
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def openurl_path
|
|
421
|
+
path_for :openurl
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def apt_get_path
|
|
426
|
+
path_for :aptget
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def clutch_path
|
|
430
|
+
path_for :clutch
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def cycript_path
|
|
434
|
+
path_for :cycript
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
end
|
|
438
|
+
end
|