idb 2.9.0 → 2.9.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 +4 -4
- data/.rubocop.yml +30 -0
- data/Gemfile.lock +5 -0
- data/idb.gemspec +1 -0
- data/lib/gui/app_binary_tab_widget.rb +7 -14
- data/lib/gui/app_details_group_box.rb +63 -88
- data/lib/gui/app_list_dialog.rb +29 -35
- data/lib/gui/app_list_widget_item.rb +1 -5
- data/lib/gui/app_tab_widget.rb +17 -22
- data/lib/gui/binary_strings_widget.rb +7 -15
- data/lib/gui/ca_manager_dialog.rb +32 -54
- data/lib/gui/cache_db_widget.rb +21 -26
- data/lib/gui/certificate_item.rb +2 -2
- data/lib/gui/default_protection_class_group_widget.rb +7 -12
- data/lib/gui/device_info_group_box.rb +26 -23
- data/lib/gui/main_tab_widget.rb +2 -21
- data/lib/gui/shared_libraries_widget.rb +1 -1
- data/lib/gui/sqlite_widget.rb +1 -3
- data/lib/gui/weak_class_dump_widget.rb +1 -1
- data/lib/idb.rb +3 -3
- data/lib/idb/version.rb +1 -1
- data/lib/lib/abstract_device.rb +7 -11
- data/lib/lib/app.rb +49 -59
- data/lib/lib/app_binary.rb +18 -29
- data/lib/lib/ca_interface.rb +46 -59
- data/lib/lib/device.rb +68 -155
- data/lib/lib/device_ca_interface.rb +7 -13
- data/lib/lib/host_file_wrapper.rb +6 -8
- data/lib/lib/ios8_last_launch_services_map_wrapper.rb +11 -18
- data/lib/lib/local_operations.rb +24 -32
- data/lib/lib/otool_wrapper.rb +30 -33
- data/lib/lib/rsync_git_manager.rb +26 -22
- data/lib/lib/screen_shot_util.rb +20 -28
- data/lib/lib/settings.rb +14 -17
- data/lib/lib/simulator.rb +11 -16
- data/lib/lib/simulator_ca_interface.rb +1 -3
- data/lib/lib/ssh_operations.rb +49 -65
- data/lib/lib/ssh_port_forwarder.rb +9 -13
- data/lib/lib/tools.rb +3 -3
- data/lib/lib/url_scheme_fuzzer.rb +41 -49
- data/lib/lib/usb_muxd_wrapper.rb +6 -8
- data/lib/lib/weak_class_dump_wrapper.rb +15 -16
- metadata +19 -9
- data/lib/gui/console_widget.rb +0 -163
- data/lib/gui/cycript_console_widget.rb +0 -68
- data/lib/gui/cycript_thread.rb +0 -81
- data/lib/lib/console_launcher.rb +0 -24
- data/lib/lib/i_device_diagnostics_wrapper.rb +0 -90
- data/lib/lib/snoop_it_wrapper.rb +0 -80
data/lib/lib/tools.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
def which(cmd)
|
3
3
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
4
4
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
5
|
-
exts.each
|
5
|
+
exts.each do |ext|
|
6
6
|
exe = File.join(path, "#{cmd}#{ext}")
|
7
7
|
return exe if File.executable? exe
|
8
|
-
|
8
|
+
end
|
9
9
|
end
|
10
|
-
|
10
|
+
nil
|
11
11
|
end
|
@@ -4,56 +4,52 @@ module Idb
|
|
4
4
|
class URLSchemeFuzzer
|
5
5
|
def initialize
|
6
6
|
@crash_report_folder = "/var/mobile/Library/Logs/CrashReporter"
|
7
|
-
|
8
7
|
end
|
9
8
|
|
10
|
-
|
11
9
|
def default_fuzz_strings
|
12
10
|
fuzz_inputs = [
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
11
|
+
"A" * 10,
|
12
|
+
"A" * 101,
|
13
|
+
"A" * 1001,
|
14
|
+
"\x0",
|
15
|
+
"'",
|
16
|
+
"%",
|
17
|
+
"%n",
|
18
|
+
"%@" * 20,
|
19
|
+
"%n%d" * 20,
|
20
|
+
"%s%p%x%d",
|
21
|
+
"%x%x%x%x",
|
22
|
+
"%#0123456x%08x%x%s%p%d%n%o%u%c%h%l%q%j%z%Z%t%i%e%g%f%a%C%S%08x%%",
|
23
|
+
# "100",
|
24
|
+
# "1000",
|
25
|
+
# "3fffffff",
|
26
|
+
# "7ffffffe",
|
27
|
+
# "7fffffff",
|
28
|
+
# "80000000",
|
29
|
+
# "fffffffe",
|
30
|
+
# "ffffffff",
|
31
|
+
# "10000",
|
32
|
+
# "100000",
|
33
|
+
"0",
|
34
|
+
"-1",
|
35
|
+
"1"
|
38
36
|
]
|
39
37
|
fuzz_inputs
|
40
38
|
end
|
41
39
|
|
42
40
|
def delete_old_reports
|
43
|
-
#remove old crash reports
|
41
|
+
# remove old crash reports
|
44
42
|
crashes = $device.ops.dir_glob @crash_report_folder, "*"
|
45
|
-
crashes.each
|
43
|
+
crashes.each do |x|
|
46
44
|
if x.include? $selected_app.binary_name
|
47
45
|
$log.info "Deleting old log #{x}"
|
48
|
-
$device.ops.execute
|
46
|
+
$device.ops.execute "rm -f '#{x}' "
|
49
47
|
end
|
50
|
-
|
51
|
-
|
48
|
+
end
|
52
49
|
end
|
53
50
|
|
54
|
-
|
55
|
-
|
56
|
-
inputs = Array.new
|
51
|
+
def generate_inputs(url, fuzz_inputs)
|
52
|
+
inputs = []
|
57
53
|
|
58
54
|
# count fuzz locations
|
59
55
|
locs = url.scan(/\$@\$/)
|
@@ -62,15 +58,16 @@ module Idb
|
|
62
58
|
combs = fuzz_inputs.combination(locs.size).to_a
|
63
59
|
|
64
60
|
# generate test instance for each combination
|
65
|
-
|
66
|
-
inputs << url.dup.gsub!(/\$@\$/)
|
67
|
-
|
61
|
+
combs.each do |c|
|
62
|
+
inputs << url.dup.gsub!(/\$@\$/) do
|
63
|
+
URI.encode(c.pop)
|
64
|
+
end
|
68
65
|
end
|
69
66
|
|
70
|
-
|
67
|
+
inputs
|
71
68
|
end
|
72
69
|
|
73
|
-
def execute
|
70
|
+
def execute(url)
|
74
71
|
$log.info "Fuzzing: #{url}"
|
75
72
|
$device.open_url url
|
76
73
|
sleep 2
|
@@ -84,15 +81,10 @@ module Idb
|
|
84
81
|
def crashed?
|
85
82
|
crashes = $device.ops.dir_glob @crash_report_folder, "*"
|
86
83
|
crashed = false
|
87
|
-
crashes.each
|
88
|
-
if x.include? $selected_app.binary_name
|
89
|
-
|
90
|
-
end
|
91
|
-
}
|
84
|
+
crashes.each do |x|
|
85
|
+
crashed = true if x.include? $selected_app.binary_name
|
86
|
+
end
|
92
87
|
crashed
|
93
88
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
89
|
end
|
98
|
-
end
|
90
|
+
end
|
data/lib/lib/usb_muxd_wrapper.rb
CHANGED
@@ -4,29 +4,27 @@ require 'awesome_print'
|
|
4
4
|
module Idb
|
5
5
|
class USBMuxdWrapper
|
6
6
|
def initialize
|
7
|
-
@proxy_pids =
|
7
|
+
@proxy_pids = []
|
8
8
|
end
|
9
9
|
|
10
10
|
def find_available_port
|
11
|
-
x = TCPServer.new("127.0.0.1",0)
|
12
|
-
@port= x.addr[1]
|
11
|
+
x = TCPServer.new("127.0.0.1", 0)
|
12
|
+
@port = x.addr[1]
|
13
13
|
x.close
|
14
14
|
@port
|
15
15
|
end
|
16
16
|
|
17
|
-
def proxy
|
17
|
+
def proxy(local_port, remote_port)
|
18
18
|
$log.info "Launching SSH proxy on port #{local_port}"
|
19
19
|
@proxy_pids << Process.spawn("iproxy #{local_port} #{remote_port}")
|
20
20
|
@proxy_pids.last
|
21
21
|
end
|
22
22
|
|
23
23
|
def stop_all
|
24
|
-
@proxy_pids.each
|
24
|
+
@proxy_pids.each do |pid|
|
25
25
|
$log.info "Terminating proxy with pid #{pid}"
|
26
26
|
Process.kill("INT", pid)
|
27
|
-
|
27
|
+
end
|
28
28
|
end
|
29
|
-
|
30
|
-
|
31
29
|
end
|
32
30
|
end
|
@@ -1,16 +1,13 @@
|
|
1
1
|
module Idb
|
2
2
|
class WeakClassDumpWrapper
|
3
|
-
|
4
|
-
def initialize local_header_dir
|
5
|
-
|
3
|
+
def initialize(local_header_dir)
|
6
4
|
@remote_header_dir_base = "/tmp/weak_class_dump_"
|
7
5
|
@remote_header_dir = @remote_header_dir_base + $selected_app.uuid
|
8
6
|
|
9
7
|
@local_header_dir = local_header_dir
|
10
|
-
|
11
8
|
end
|
12
9
|
|
13
|
-
def
|
10
|
+
def setup_cycript
|
14
11
|
unless $device.cycript_installed?
|
15
12
|
$log.error "Cycript not found, aborting."
|
16
13
|
return
|
@@ -20,18 +17,24 @@ module Idb
|
|
20
17
|
# originally from: https://github.com/limneos/weak_classdump
|
21
18
|
|
22
19
|
wc_file = "/var/root/weak_classdump.cy"
|
23
|
-
unless $device.ops.file_exists?
|
20
|
+
unless $device.ops.file_exists? wc_file
|
24
21
|
$log.info "weak_classdump not found, Installing onto device."
|
25
|
-
|
22
|
+
path = File.dirname(File.expand_path(__FILE__))
|
23
|
+
path += "/../utils/weak_class_dump/weak_classdump.cy"
|
24
|
+
$device.ops.upload(path, wc_file)
|
26
25
|
end
|
27
26
|
|
28
27
|
local_instructions_file = "#{$tmp_path}/weak_classdump_instructions.cy"
|
29
28
|
remote_instructions_file = "/var/root/weak_classdump_instructions.cy"
|
30
|
-
File.open(local_instructions_file,"w")
|
29
|
+
File.open(local_instructions_file, "w") do |x|
|
31
30
|
x.puts("weak_classdump_bundle([NSBundle mainBundle],\"#{@remote_header_dir}\")")
|
32
|
-
|
31
|
+
end
|
33
32
|
|
34
33
|
$device.ops.upload local_instructions_file, remote_instructions_file
|
34
|
+
end
|
35
|
+
|
36
|
+
def execute_cycript
|
37
|
+
setup_cycript
|
35
38
|
|
36
39
|
$log.info "Launching app..."
|
37
40
|
$selected_app.launch
|
@@ -44,19 +47,15 @@ module Idb
|
|
44
47
|
cmd = "cycript -p '#{$selected_app.binary_name}' #{remote_instructions_file}"
|
45
48
|
$log.info "Running: #{cmd}"
|
46
49
|
$device.ops.execute cmd
|
47
|
-
|
48
50
|
end
|
49
51
|
|
50
|
-
def
|
51
|
-
Dir.entries(@local_header_dir).reject{|entry| entry == "." || entry == ".."}
|
52
|
+
def header_files
|
53
|
+
Dir.entries(@local_header_dir).reject { |entry| entry == "." || entry == ".." }
|
52
54
|
end
|
53
55
|
|
54
56
|
def pull_header_files
|
55
57
|
$log.info "Downloading header files from #{@remote_header_dir} to #{@local_header_dir}"
|
56
58
|
$device.ops.download_recursive(@remote_header_dir, @local_header_dir)
|
57
59
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
61
60
|
end
|
62
|
-
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: idb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.9.
|
4
|
+
version: 2.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel A. Mayer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: launchy
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -272,6 +286,7 @@ extensions: []
|
|
272
286
|
extra_rdoc_files: []
|
273
287
|
files:
|
274
288
|
- ".gitignore"
|
289
|
+
- ".rubocop.yml"
|
275
290
|
- Gemfile
|
276
291
|
- Gemfile.lock
|
277
292
|
- LICENSE.txt
|
@@ -290,9 +305,6 @@ files:
|
|
290
305
|
- lib/gui/ca_manager_dialog.rb
|
291
306
|
- lib/gui/cache_db_widget.rb
|
292
307
|
- lib/gui/certificate_item.rb
|
293
|
-
- lib/gui/console_widget.rb
|
294
|
-
- lib/gui/cycript_console_widget.rb
|
295
|
-
- lib/gui/cycript_thread.rb
|
296
308
|
- lib/gui/default_protection_class_group_widget.rb
|
297
309
|
- lib/gui/device_info_group_box.rb
|
298
310
|
- lib/gui/device_status_dialog.rb
|
@@ -343,11 +355,9 @@ files:
|
|
343
355
|
- lib/lib/app_binary.rb
|
344
356
|
- lib/lib/ca_interface.rb
|
345
357
|
- lib/lib/configuration.rb
|
346
|
-
- lib/lib/console_launcher.rb
|
347
358
|
- lib/lib/device.rb
|
348
359
|
- lib/lib/device_ca_interface.rb
|
349
360
|
- lib/lib/host_file_wrapper.rb
|
350
|
-
- lib/lib/i_device_diagnostics_wrapper.rb
|
351
361
|
- lib/lib/ios8_last_launch_services_map_wrapper.rb
|
352
362
|
- lib/lib/keychain_wrapper.rb
|
353
363
|
- lib/lib/local_operations.rb
|
@@ -359,7 +369,6 @@ files:
|
|
359
369
|
- lib/lib/settings.rb
|
360
370
|
- lib/lib/simulator.rb
|
361
371
|
- lib/lib/simulator_ca_interface.rb
|
362
|
-
- lib/lib/snoop_it_wrapper.rb
|
363
372
|
- lib/lib/ssh_operations.rb
|
364
373
|
- lib/lib/ssh_port_forwarder.rb
|
365
374
|
- lib/lib/tools.rb
|
@@ -397,8 +406,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
397
406
|
version: '0'
|
398
407
|
requirements: []
|
399
408
|
rubyforge_project:
|
400
|
-
rubygems_version: 2.
|
409
|
+
rubygems_version: 2.2.2
|
401
410
|
signing_key:
|
402
411
|
specification_version: 4
|
403
412
|
summary: idb is a tool to simplify some common tasks for iOS pentesting and research.
|
404
413
|
test_files: []
|
414
|
+
has_rdoc:
|
data/lib/gui/console_widget.rb
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
module Idb
|
2
|
-
class ConsoleWidget < Qt::PlainTextEdit
|
3
|
-
|
4
|
-
signals "command(QString)"
|
5
|
-
|
6
|
-
def initialize *args
|
7
|
-
super *args
|
8
|
-
setPrompt("> ")
|
9
|
-
@locked = false
|
10
|
-
@history_down = Array.new
|
11
|
-
@history_up = Array.new
|
12
|
-
end
|
13
|
-
|
14
|
-
def keyPressEvent e, callSuper=false
|
15
|
-
if callSuper
|
16
|
-
super e
|
17
|
-
end
|
18
|
-
if @locked
|
19
|
-
return
|
20
|
-
end
|
21
|
-
|
22
|
-
case e.key
|
23
|
-
when Qt::Key_Return
|
24
|
-
handleEnter
|
25
|
-
|
26
|
-
when Qt::Key_Backspace
|
27
|
-
handleLeft e
|
28
|
-
|
29
|
-
when Qt::Key_Up
|
30
|
-
handleHistoryUp
|
31
|
-
|
32
|
-
when Qt::Key_Down
|
33
|
-
handleHistoryDown
|
34
|
-
|
35
|
-
when Qt::Key_Left
|
36
|
-
handleLeft e
|
37
|
-
|
38
|
-
when Qt::Key_Home
|
39
|
-
handleHome
|
40
|
-
else
|
41
|
-
super e
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def handleEnter
|
46
|
-
cmd = getCommand
|
47
|
-
|
48
|
-
if 0 < cmd.length
|
49
|
-
while @history_down.count > 0
|
50
|
-
@history_up.push(@history_down.pop)
|
51
|
-
end
|
52
|
-
@history_up.push cmd
|
53
|
-
end
|
54
|
-
|
55
|
-
moveToEndOfLine
|
56
|
-
|
57
|
-
if cmd.length > 0
|
58
|
-
@locked = true
|
59
|
-
setFocus
|
60
|
-
insertPlainText("\n")
|
61
|
-
emit command(cmd)
|
62
|
-
else
|
63
|
-
insertPlainText("\n")
|
64
|
-
insertPlainText(@userPrompt)
|
65
|
-
ensureCursorVisible
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def result result
|
70
|
-
insertPlainText(result)
|
71
|
-
insertPlainText("\n")
|
72
|
-
insertPlainText(@userPrompt)
|
73
|
-
ensureCursorVisible
|
74
|
-
@locked = false
|
75
|
-
end
|
76
|
-
|
77
|
-
def append text
|
78
|
-
insertPlainText(text)
|
79
|
-
insertPlainText("\n")
|
80
|
-
ensureCursorVisible
|
81
|
-
end
|
82
|
-
|
83
|
-
def handleHistoryUp
|
84
|
-
if 0 < @history_up.count
|
85
|
-
cmd = @history_up.pop
|
86
|
-
@history_down.push(cmd)
|
87
|
-
|
88
|
-
clearLine
|
89
|
-
insertPlainText(cmd)
|
90
|
-
end
|
91
|
-
|
92
|
-
historySkip = true
|
93
|
-
end
|
94
|
-
|
95
|
-
def handleHistoryDown
|
96
|
-
if 0 < @history_down.count && historySkip
|
97
|
-
@history_up.push(@history_down.pop)
|
98
|
-
historySkip = false
|
99
|
-
end
|
100
|
-
|
101
|
-
if 0 < @history_down.count
|
102
|
-
cmd = @history_down.pop()
|
103
|
-
@history_up.push(cmd)
|
104
|
-
|
105
|
-
clearLine()
|
106
|
-
insertPlainText(cmd)
|
107
|
-
else
|
108
|
-
clearLine()
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
def clearLine
|
114
|
-
c = textCursor()
|
115
|
-
c.select(Qt::TextCursor::LineUnderCursor)
|
116
|
-
c.removeSelectedText()
|
117
|
-
insertPlainText(@userPrompt)
|
118
|
-
end
|
119
|
-
|
120
|
-
def getCommand
|
121
|
-
c = textCursor()
|
122
|
-
c.select(Qt::TextCursor::LineUnderCursor)
|
123
|
-
|
124
|
-
text = c.selectedText()
|
125
|
-
text = text[@userPrompt.length,text.length]
|
126
|
-
puts text
|
127
|
-
text
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
def moveToEndOfLine
|
132
|
-
moveCursor(Qt::TextCursor::EndOfLine);
|
133
|
-
end
|
134
|
-
|
135
|
-
def handleLeft event
|
136
|
-
if getIndex(textCursor) > @userPrompt.length
|
137
|
-
keyPressEvent(event, true)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def handleHome
|
142
|
-
c = textCursor
|
143
|
-
c.movePosition(Qt::TextCursor::StartOfLine)
|
144
|
-
c.movePosition(Qt::TextCursor::Right, Qt::TextCursor::MoveAnchor, @userPrompt.length)
|
145
|
-
setTextCursor(c)
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
def getIndex crQTextCursor
|
150
|
-
column = 1
|
151
|
-
b = crQTextCursor.block()
|
152
|
-
column = crQTextCursor.position - b.position
|
153
|
-
column
|
154
|
-
end
|
155
|
-
|
156
|
-
def setPrompt prompt
|
157
|
-
@userPrompt = prompt
|
158
|
-
clearLine()
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
end
|
163
|
-
end
|