idb 2.7.1 → 2.8
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/Gemfile.lock +3 -1
- data/idb.gemspec +1 -0
- data/lib/gui/device_status_dialog.rb +15 -15
- data/lib/gui/keychain_binary_widget.rb +8 -2
- data/lib/gui/keychain_edit_dialog.rb +43 -0
- data/lib/gui/keychain_tab_widget.rb +26 -3
- data/lib/gui/keychain_widget.rb +117 -26
- data/lib/idb/version.rb +1 -1
- data/lib/lib/device.rb +17 -28
- data/lib/lib/keychain_wrapper.rb +41 -0
- data/lib/lib/plist_util.rb +7 -0
- data/lib/utils/keychain_editor/keychaineditor +0 -0
- metadata +19 -3
- data/lib/lib/keychain_plist_parser.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca757a1a46203f2a8e9d3aa84b23f56967b6869a
|
4
|
+
data.tar.gz: 8ad5422f2b584ed7b69cfa21c502e5e642654136
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 632cd3de5bed5aa80d1dff965fc36b28efb25865b56d0e53b98fb3e58bb74e93c4f32c8a020626875b7f395d3cd64c3519d31f50107833387f778205e17168ba
|
7
|
+
data.tar.gz: 3ab576dc7268127d94610d2b8b7ea65c08307efaa31e22bdc9d43e667ee7271afce1f677ce9827d045cfc185b7136ef7f7f8581d79694295c33dcfc328da7654
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
idb (2.
|
4
|
+
idb (2.8)
|
5
5
|
awesome_print
|
6
6
|
coderay
|
7
7
|
ffi
|
8
8
|
git
|
9
9
|
hexdump
|
10
10
|
htmlentities
|
11
|
+
json
|
11
12
|
launchy
|
12
13
|
log4r
|
13
14
|
net-sftp
|
@@ -29,6 +30,7 @@ GEM
|
|
29
30
|
tilt
|
30
31
|
hexdump (0.2.3)
|
31
32
|
htmlentities (4.3.3)
|
33
|
+
json (1.8.2)
|
32
34
|
launchy (2.4.3)
|
33
35
|
addressable (~> 2.3)
|
34
36
|
libxml-ruby (2.8.0)
|
data/idb.gemspec
CHANGED
@@ -21,8 +21,8 @@ module Idb
|
|
21
21
|
setFixedHeight(sizeHint().height());
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
@
|
24
|
+
def mark_keychain_editor_installed
|
25
|
+
@keychain_editor_label.text = @keychain_editor_label.text + "<br>found: #{$device.keychain_editor_path}"
|
26
26
|
@layout.addWidget installed_check_mark, 6, 1
|
27
27
|
setFixedHeight(sizeHint().height());
|
28
28
|
end
|
@@ -202,24 +202,24 @@ module Idb
|
|
202
202
|
|
203
203
|
end
|
204
204
|
|
205
|
-
def
|
206
|
-
@
|
207
|
-
@layout.addWidget @
|
205
|
+
def keychaineditor_section
|
206
|
+
@keychain_editor_label = Qt::Label.new "<b>keychain_editor</b><br>(provides keychain edit functionality.<br>by Nitin Jami)"
|
207
|
+
@layout.addWidget @keychain_editor_label, 6, 0
|
208
208
|
|
209
|
-
if $device.
|
210
|
-
|
209
|
+
if $device.keychain_editor_installed?
|
210
|
+
mark_keychain_editor_installed
|
211
211
|
else
|
212
|
-
@
|
213
|
-
@
|
214
|
-
$device.
|
215
|
-
if $device.
|
216
|
-
@
|
217
|
-
|
212
|
+
@install_keychain_editor = Qt::PushButton.new "Install"
|
213
|
+
@install_keychain_editor.connect(SIGNAL(:released)) {
|
214
|
+
$device.install_keychain_editor
|
215
|
+
if $device.keychain_editor_installed?
|
216
|
+
@install_keychain_editor.hide
|
217
|
+
mark_keychain_editor_installed
|
218
218
|
end
|
219
219
|
}
|
220
220
|
|
221
221
|
|
222
|
-
@layout.addWidget @
|
222
|
+
@layout.addWidget @install_keychain_editor, 6, 1
|
223
223
|
|
224
224
|
end
|
225
225
|
end
|
@@ -295,7 +295,7 @@ module Idb
|
|
295
295
|
dumpdecrypted_section
|
296
296
|
pbwatcher_section
|
297
297
|
pcviewer_section
|
298
|
-
|
298
|
+
keychaineditor_section
|
299
299
|
rsync_section
|
300
300
|
cycript_section
|
301
301
|
|
@@ -44,8 +44,14 @@ module Idb
|
|
44
44
|
|
45
45
|
def set_data data
|
46
46
|
output = ""
|
47
|
-
|
48
|
-
|
47
|
+
begin
|
48
|
+
Hexdump.dump(data, {:output => output } )
|
49
|
+
@vdata_text.appendPlainText output
|
50
|
+
rescue Exception => e
|
51
|
+
$log.error "Something went wrong with the hexdump: #{e.exception}"
|
52
|
+
$log.error "Tried hexdumping: #{data}"
|
53
|
+
@vdata_text.appendPlainText "Error dumping data."
|
54
|
+
end
|
49
55
|
end
|
50
56
|
|
51
57
|
def clear
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
module Idb
|
3
|
+
class KeychainEditDialog < Qt::Dialog
|
4
|
+
|
5
|
+
def initialize *args
|
6
|
+
super *args
|
7
|
+
|
8
|
+
self.modal = true
|
9
|
+
|
10
|
+
@layout = Qt::GridLayout.new
|
11
|
+
setLayout(@layout)
|
12
|
+
setWindowTitle("Edit Keychain Item")
|
13
|
+
|
14
|
+
@data_text = Qt::PlainTextEdit.new
|
15
|
+
@layout.addWidget @data_text, 0,0,1,2
|
16
|
+
|
17
|
+
@save_button = Qt::PushButton.new "Save"
|
18
|
+
@save_button.setDefault true
|
19
|
+
|
20
|
+
@save_button.connect(SIGNAL(:released)) {|x|
|
21
|
+
accept()
|
22
|
+
}
|
23
|
+
@cancel_button = Qt::PushButton.new "Cancel"
|
24
|
+
@cancel_button.connect(SIGNAL(:released)) {|x|
|
25
|
+
reject()
|
26
|
+
}
|
27
|
+
|
28
|
+
@layout.addWidget @save_button, 1, 1
|
29
|
+
@layout.addWidget @cancel_button, 1, 0
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def setText text
|
35
|
+
@data_text.appendPlainText text
|
36
|
+
end
|
37
|
+
|
38
|
+
def getText
|
39
|
+
@data_text.toPlainText
|
40
|
+
end
|
41
|
+
#
|
42
|
+
end
|
43
|
+
end
|
@@ -11,11 +11,34 @@ module Idb
|
|
11
11
|
@tabs = Hash.new
|
12
12
|
|
13
13
|
@text = KeychainTextWidget.new self
|
14
|
-
@tabs[:text] = addTab(@text, "
|
14
|
+
@tabs[:text] = addTab(@text, "Data")
|
15
15
|
|
16
16
|
@binary = KeychainBinaryWidget.new self
|
17
|
-
@tabs[:binary] = addTab(@binary, "
|
17
|
+
@tabs[:binary] = addTab(@binary, "Hexdump")
|
18
18
|
|
19
|
+
@plist = KeychainTextWidget.new self
|
20
|
+
@tabs[:plist] = addTab(@plist, "View Plist")
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def set_plist text
|
26
|
+
xml = "Not a plist file."
|
27
|
+
if text.start_with? "bplist"
|
28
|
+
begin
|
29
|
+
file = Tempfile.new('plist')
|
30
|
+
file.write text
|
31
|
+
file.close
|
32
|
+
parsed = PlistUtil.new file.path
|
33
|
+
xml = parsed.get_xml
|
34
|
+
rescue
|
35
|
+
xml = "Data could not be parsed as Plist."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@plist.clear
|
40
|
+
@plist.set_data xml
|
41
|
+
file.unlink unless file.nil?
|
19
42
|
end
|
20
43
|
|
21
44
|
def set_data text
|
@@ -23,7 +46,7 @@ module Idb
|
|
23
46
|
@text.set_data text
|
24
47
|
end
|
25
48
|
|
26
|
-
def
|
49
|
+
def set_hexdata text
|
27
50
|
@binary.clear
|
28
51
|
@binary.set_data text
|
29
52
|
end
|
data/lib/gui/keychain_widget.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
require_relative '../lib/
|
1
|
+
require_relative '../lib/keychain_wrapper'
|
2
2
|
require_relative 'keychain_tab_widget'
|
3
|
+
require_relative 'keychain_edit_dialog'
|
4
|
+
require 'base64'
|
3
5
|
|
4
6
|
module Idb
|
5
7
|
|
@@ -15,10 +17,25 @@ module Idb
|
|
15
17
|
|
16
18
|
@selection_model = Qt::ItemSelectionModel.new @model
|
17
19
|
@selection_model.connect(SIGNAL('selectionChanged(QItemSelection,QItemSelection)')) {|x,y|
|
20
|
+
|
21
|
+
if x.indexes.length == 0
|
22
|
+
@delete_button.setEnabled(false)
|
23
|
+
@edit_button.setEnabled(false)
|
24
|
+
@edit64_button.setEnabled(false)
|
25
|
+
else
|
26
|
+
@delete_button.setEnabled(true)
|
27
|
+
@edit_button.setEnabled(true)
|
28
|
+
@edit64_button.setEnabled(true)
|
29
|
+
@selected_row = x.indexes[0].row
|
30
|
+
end
|
31
|
+
|
18
32
|
unless x.indexes.length == 0
|
19
|
-
|
20
|
-
@keychain_tab_widget.set_data @keychain.entries[
|
21
|
-
@keychain_tab_widget.
|
33
|
+
id = @model.item(x.indexes[0].row).text
|
34
|
+
@keychain_tab_widget.set_data Base64.decode64(@keychain.entries[id.to_i]["Data"])
|
35
|
+
@keychain_tab_widget.set_hexdata Base64.decode64(@keychain.entries[id.to_i]["Data"])
|
36
|
+
@keychain_tab_widget.set_plist Base64.decode64(@keychain.entries[id.to_i]["Data"])
|
37
|
+
|
38
|
+
|
22
39
|
end
|
23
40
|
|
24
41
|
}
|
@@ -30,47 +47,121 @@ module Idb
|
|
30
47
|
@keychain_tab.setSelectionBehavior(Qt::AbstractItemView::SelectRows)
|
31
48
|
@keychain_tab.setEditTriggers(Qt::AbstractItemView::NoEditTriggers )
|
32
49
|
|
33
|
-
@layout.addWidget @keychain_tab, 0,0
|
50
|
+
@layout.addWidget @keychain_tab, 0,0,1,3
|
34
51
|
|
35
52
|
|
36
53
|
@dump = Qt::PushButton.new "Dump Keychain"
|
37
|
-
@layout.addWidget @dump, 2, 0
|
38
|
-
|
39
|
-
@keychain_tab_widget = KeychainTabWidget.new
|
40
|
-
@layout.addWidget @keychain_tab_widget, 3, 0
|
54
|
+
@layout.addWidget @dump, 2, 0,1,3
|
41
55
|
|
42
56
|
@dump.connect(SIGNAL :released) {
|
43
|
-
$device.dump_keychain
|
44
|
-
@keychain = KeychainPlistParser.new "#{$tmp_path}/device/genp.plist"
|
45
57
|
populate_table
|
46
58
|
}
|
47
59
|
|
60
|
+
@keychain_tab_widget = KeychainTabWidget.new
|
61
|
+
@layout.addWidget @keychain_tab_widget, 3, 0,1,3
|
62
|
+
|
63
|
+
|
64
|
+
@delete_button = Qt::PushButton.new "Delete"
|
65
|
+
@delete_button.setEnabled(false)
|
66
|
+
@layout.addWidget @delete_button, 4, 0
|
67
|
+
@delete_button.connect(SIGNAL :released) {
|
68
|
+
service = @keychain.entries[@selected_row+1]["Service"]
|
69
|
+
account = @keychain.entries[@selected_row+1]["Account"]
|
70
|
+
agroup = @keychain.entries[@selected_row+1]["EntitlementGroup"]
|
71
|
+
|
72
|
+
reply = Qt::MessageBox::question(self, "Delete Keychain Item", "Are you sure to delete the item with<br>service=#{service}<br>account=#{account}<br>group=#{agroup}", Qt::MessageBox::Yes, Qt::MessageBox::No);
|
73
|
+
if reply == Qt::MessageBox::Yes
|
74
|
+
@keychain.delete_item service, account, agroup
|
75
|
+
|
76
|
+
reply2 = Qt::MessageBox::question(self, "Refresh?", "Item deleted, refresh keychain data?", Qt::MessageBox::Yes, Qt::MessageBox::No);
|
77
|
+
if reply2 == Qt::MessageBox::Yes
|
78
|
+
populate_table
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
}
|
84
|
+
|
85
|
+
@edit_button = Qt::PushButton.new "Edit as Text"
|
86
|
+
@edit_button.setEnabled(false)
|
87
|
+
@layout.addWidget @edit_button, 4, 1
|
88
|
+
|
89
|
+
@edit_button.connect(SIGNAL :released) {
|
90
|
+
service = @keychain.entries[@selected_row+1]["Service"]
|
91
|
+
account = @keychain.entries[@selected_row+1]["Account"]
|
92
|
+
agroup = @keychain.entries[@selected_row+1]["EntitlementGroup"]
|
93
|
+
data = @keychain.entries[@selected_row+1]["Data"]
|
94
|
+
dialog = KeychainEditDialog.new
|
95
|
+
dialog.connect(SIGNAL :accepted) {
|
96
|
+
|
97
|
+
@keychain.edit_item service, account, agroup, Base64.encode64(dialog.getText)
|
98
|
+
|
99
|
+
reply2 = Qt::MessageBox::question(self, "Refresh?", "Item saved, refresh keychain data?", Qt::MessageBox::Yes, Qt::MessageBox::No);
|
100
|
+
if reply2 == Qt::MessageBox::Yes
|
101
|
+
populate_table
|
102
|
+
end
|
103
|
+
}
|
104
|
+
|
105
|
+
dialog.setText Base64.decode64(data)
|
106
|
+
dialog.show
|
107
|
+
}
|
108
|
+
@edit64_button = Qt::PushButton.new "Edit as Base64"
|
109
|
+
@edit64_button.setEnabled(false)
|
110
|
+
@edit64_button.connect(SIGNAL :released) {
|
111
|
+
service = @keychain.entries[@selected_row+1]["Service"]
|
112
|
+
account = @keychain.entries[@selected_row+1]["Account"]
|
113
|
+
agroup = @keychain.entries[@selected_row+1]["EntitlementGroup"]
|
114
|
+
data = @keychain.entries[@selected_row+1]["Data"]
|
115
|
+
dialog = KeychainEditDialog.new
|
116
|
+
dialog.connect(SIGNAL :accepted) {
|
117
|
+
@keychain.edit_item service, account, agroup, dialog.getText
|
118
|
+
|
119
|
+
reply2 = Qt::MessageBox::question(self, "Refresh?", "Item saved, refresh keychain data?", Qt::MessageBox::Yes, Qt::MessageBox::No);
|
120
|
+
if reply2 == Qt::MessageBox::Yes
|
121
|
+
populate_table
|
122
|
+
end
|
123
|
+
}
|
124
|
+
|
125
|
+
dialog.setText data
|
126
|
+
dialog.show
|
127
|
+
}
|
128
|
+
@layout.addWidget @edit64_button, 4, 2
|
129
|
+
|
48
130
|
end
|
49
131
|
|
50
132
|
|
51
133
|
def populate_table
|
134
|
+
@keychain = KeychainWrapper.new
|
135
|
+
@keychain.parse
|
52
136
|
@keychain_tab_widget.clear
|
53
137
|
@model.clear
|
54
|
-
@model.setHorizontalHeaderItem(0, Qt::StandardItem.new("
|
55
|
-
@model.setHorizontalHeaderItem(1, Qt::StandardItem.new("
|
56
|
-
@model.setHorizontalHeaderItem(2, Qt::StandardItem.new("
|
57
|
-
@model.setHorizontalHeaderItem(3, Qt::StandardItem.new("
|
58
|
-
@model.setHorizontalHeaderItem(4, Qt::StandardItem.new("
|
59
|
-
@model.setHorizontalHeaderItem(5, Qt::StandardItem.new("
|
60
|
-
|
61
|
-
|
62
|
-
|
138
|
+
@model.setHorizontalHeaderItem(0, Qt::StandardItem.new("ID"))
|
139
|
+
@model.setHorizontalHeaderItem(1, Qt::StandardItem.new("Entitlement Group"))
|
140
|
+
@model.setHorizontalHeaderItem(2, Qt::StandardItem.new("Account"))
|
141
|
+
@model.setHorizontalHeaderItem(3, Qt::StandardItem.new("Service"))
|
142
|
+
@model.setHorizontalHeaderItem(4, Qt::StandardItem.new("Protection"))
|
143
|
+
@model.setHorizontalHeaderItem(5, Qt::StandardItem.new("User Presence"))
|
144
|
+
@model.setHorizontalHeaderItem(6, Qt::StandardItem.new("Creation"))
|
145
|
+
@model.setHorizontalHeaderItem(7, Qt::StandardItem.new("Modification"))
|
146
|
+
|
147
|
+
@keychain.entries.each { |entry|
|
148
|
+
item = entry[1]
|
63
149
|
row = Array.new
|
64
|
-
|
65
|
-
|
66
|
-
row <<
|
67
|
-
row << Qt::StandardItem.new(item['
|
68
|
-
row << Qt::StandardItem.new(item['
|
69
|
-
row << Qt::StandardItem.new(item['
|
150
|
+
id = Qt::StandardItem.new
|
151
|
+
id.setData(Qt::Variant.new(entry[0].to_i), Qt::DisplayRole)
|
152
|
+
row << id
|
153
|
+
row << Qt::StandardItem.new(item['EntitlementGroup'].to_s)
|
154
|
+
row << Qt::StandardItem.new(item['Account'].to_s)
|
155
|
+
row << Qt::StandardItem.new(item['Service'].to_s)
|
156
|
+
row << Qt::StandardItem.new(item['Protection'].to_s)
|
157
|
+
row << Qt::StandardItem.new(item['UserPresence'].to_s)
|
158
|
+
row << Qt::StandardItem.new(item['Creation Time'].to_s)
|
159
|
+
row << Qt::StandardItem.new(item['Modified Time'].to_s)
|
70
160
|
@model.appendRow(row)
|
71
161
|
}
|
72
162
|
@keychain_tab.resizeColumnsToContents
|
73
163
|
@keychain_tab.resizeRowsToContents
|
164
|
+
@keychain_tab.sortByColumn(0, Qt::AscendingOrder)
|
74
165
|
|
75
166
|
|
76
167
|
end
|
data/lib/idb/version.rb
CHANGED
data/lib/lib/device.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative 'abstract_device'
|
|
4
4
|
require_relative 'ssh_port_forwarder'
|
5
5
|
require_relative 'device_ca_interface'
|
6
6
|
require_relative 'usb_muxd_wrapper'
|
7
|
+
require 'json'
|
7
8
|
|
8
9
|
module Idb
|
9
10
|
class Device < AbstractDevice
|
@@ -25,7 +26,7 @@ module Idb
|
|
25
26
|
@device_app_paths[:open] = ["/usr/bin/open"]
|
26
27
|
@device_app_paths[:openurl] = ["/usr/bin/uiopen", "/usr/bin/openurl", "/usr/bin/openURL"]
|
27
28
|
@device_app_paths[:aptget] = ["/usr/bin/apt-get", "/usr/bin/aptitude"]
|
28
|
-
@device_app_paths[:
|
29
|
+
@device_app_paths[:keychaineditor] = [ "/var/root/keychaineditor"]
|
29
30
|
@device_app_paths[:pcviewer] = ["/var/root/protectionclassviewer"]
|
30
31
|
@device_app_paths[:pbwatcher] = ["/var/root/pbwatcher"]
|
31
32
|
@device_app_paths[:dumpdecrypted_armv7] = ["/var/root/dumpdecrypted_armv7.dylib"]
|
@@ -124,18 +125,6 @@ module Idb
|
|
124
125
|
end
|
125
126
|
|
126
127
|
|
127
|
-
def dump_keychain
|
128
|
-
device_store_path = "/var/root/genp.plist"
|
129
|
-
local_dir = "#{$tmp_path}/device/"
|
130
|
-
local_path = "#{local_dir}/genp.plist"
|
131
|
-
FileUtils.mkdir_p local_dir unless Dir.exist? local_dir
|
132
|
-
|
133
|
-
$log.info "Dumping keychain..."
|
134
|
-
@ops.execute "#{keychain_dump_path}"
|
135
|
-
$log.info "Downloading dumped keychain..."
|
136
|
-
@ops.download device_store_path, local_path
|
137
|
-
end
|
138
|
-
|
139
128
|
|
140
129
|
|
141
130
|
|
@@ -232,11 +221,11 @@ module Idb
|
|
232
221
|
$log.info "'dumpdecrypted' installed successfully."
|
233
222
|
end
|
234
223
|
|
235
|
-
def
|
236
|
-
if File.exist? "#{File.dirname(File.expand_path(__FILE__))}/../utils/
|
237
|
-
|
224
|
+
def install_keychain_editor
|
225
|
+
if File.exist? "#{File.dirname(File.expand_path(__FILE__))}/../utils/keychain_editor/keychaineditor"
|
226
|
+
upload_keychain_editor
|
238
227
|
else
|
239
|
-
$log.error "
|
228
|
+
$log.error "keychain_editor not found at '#{File.dirname(File.expand_path(__FILE__))}/../utils/keychain_editor/keychaineditor'."
|
240
229
|
false
|
241
230
|
end
|
242
231
|
end
|
@@ -272,15 +261,15 @@ module Idb
|
|
272
261
|
end
|
273
262
|
end
|
274
263
|
|
275
|
-
def
|
264
|
+
def upload_keychain_editor
|
276
265
|
begin
|
277
|
-
$log.info "Uploading
|
278
|
-
@ops.upload "#{File.dirname(File.expand_path(__FILE__))}/../utils/
|
279
|
-
@ops.chmod "/var/root/
|
280
|
-
$log.info "'
|
266
|
+
$log.info "Uploading keychain_editor..."
|
267
|
+
@ops.upload "#{File.dirname(File.expand_path(__FILE__))}/../utils/keychain_editor/keychaineditor", "/var/root/keychaineditor"
|
268
|
+
@ops.chmod "/var/root/keychaineditor", 0744
|
269
|
+
$log.info "'keychain_editor' installed successfully."
|
281
270
|
# true
|
282
271
|
# rescue
|
283
|
-
$log.error "Exception encountered when uploading
|
272
|
+
$log.error "Exception encountered when uploading keychain_editor"
|
284
273
|
# false
|
285
274
|
end
|
286
275
|
end
|
@@ -360,7 +349,7 @@ module Idb
|
|
360
349
|
end
|
361
350
|
|
362
351
|
def configured?
|
363
|
-
apt_get_installed? and open_installed? and openurl_installed? and dumpdecrypted_installed? and pbwatcher_installed? and pcviewer_installed? and
|
352
|
+
apt_get_installed? and open_installed? and openurl_installed? and dumpdecrypted_installed? and pbwatcher_installed? and pcviewer_installed? and keychain_editor_installed? and rsync_installed? and cycript_installed?
|
364
353
|
end
|
365
354
|
|
366
355
|
|
@@ -368,8 +357,8 @@ module Idb
|
|
368
357
|
is_installed? :cycript
|
369
358
|
end
|
370
359
|
|
371
|
-
def
|
372
|
-
is_installed? :
|
360
|
+
def keychain_editor_installed?
|
361
|
+
is_installed? :keychaineditor
|
373
362
|
end
|
374
363
|
|
375
364
|
def pcviewer_installed?
|
@@ -405,8 +394,8 @@ module Idb
|
|
405
394
|
is_installed? :clutch
|
406
395
|
end
|
407
396
|
|
408
|
-
def
|
409
|
-
path_for :
|
397
|
+
def keychain_editor_path
|
398
|
+
path_for :keychaineditor
|
410
399
|
end
|
411
400
|
|
412
401
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Idb
|
2
|
+
class KeychainWrapper
|
3
|
+
attr_accessor :entries
|
4
|
+
def initialize
|
5
|
+
@keychain_editor_path = $device.keychain_editor_path
|
6
|
+
@ops = $device.ops
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
begin
|
11
|
+
@parsed = JSON.parse(dump)
|
12
|
+
@entries = Hash.new
|
13
|
+
@parsed.each {|x|
|
14
|
+
@entries[x[0].to_i] = x[1]
|
15
|
+
}
|
16
|
+
rescue
|
17
|
+
$log.error "Couldn't parse keychain json."
|
18
|
+
@entries = {}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def dump
|
23
|
+
$log.info "Dumping keychain using keychain_editor..."
|
24
|
+
@ops.execute "#{@keychain_editor_path} --action dump"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def delete_item service, account, agroup
|
31
|
+
$log.info "Deleting keychain item for service='#{service}', account='#{account}', agroup='#{agroup}' ..."
|
32
|
+
@ops.execute "#{@keychain_editor_path} --action delete --account \"#{account}\" --service \"#{service}\" --agroup \"#{agroup}\""
|
33
|
+
end
|
34
|
+
|
35
|
+
def edit_item service, account, agroup, data
|
36
|
+
$log.info "Modifying keychain item for service='#{service}', account='#{account}', agroup='#{agroup}'. New data=#{data}"
|
37
|
+
@ops.execute "#{@keychain_editor_path} --action edit --account \"#{account}\" --service \"#{service}\" --agroup \"#{agroup}\" --data \"#{data}\""
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/lib/plist_util.rb
CHANGED
@@ -28,6 +28,13 @@ module Idb
|
|
28
28
|
extract_url_handlers
|
29
29
|
end
|
30
30
|
|
31
|
+
def get_xml
|
32
|
+
doc = Nokogiri::XML(File.open(@plist_file)) do |config|
|
33
|
+
config.nonet.noblanks
|
34
|
+
end
|
35
|
+
doc.to_xml(:indent => 2)
|
36
|
+
end
|
37
|
+
|
31
38
|
def dump
|
32
39
|
doc = Nokogiri::XML(File.open(@plist_file)) do |config|
|
33
40
|
config.nonet.noblanks
|
Binary file
|
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.
|
4
|
+
version: '2.8'
|
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: 2015-04-
|
11
|
+
date: 2015-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -234,6 +234,20 @@ dependencies:
|
|
234
234
|
- - ">="
|
235
235
|
- !ruby/object:Gem::Version
|
236
236
|
version: '0'
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: json
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - ">="
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '0'
|
244
|
+
type: :runtime
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - ">="
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '0'
|
237
251
|
description: idb is a tool to simplify some common tasks for iOS pentesting and research.
|
238
252
|
Please see https://github.com/dmayer/idb for more details on installation and usage.
|
239
253
|
email:
|
@@ -277,6 +291,7 @@ files:
|
|
277
291
|
- lib/gui/images/iphone.ico
|
278
292
|
- lib/gui/images/screenshot.png
|
279
293
|
- lib/gui/keychain_binary_widget.rb
|
294
|
+
- lib/gui/keychain_edit_dialog.rb
|
280
295
|
- lib/gui/keychain_tab_widget.rb
|
281
296
|
- lib/gui/keychain_text_widget.rb
|
282
297
|
- lib/gui/keychain_widget.rb
|
@@ -320,7 +335,7 @@ files:
|
|
320
335
|
- lib/lib/host_file_wrapper.rb
|
321
336
|
- lib/lib/i_device_diagnostics_wrapper.rb
|
322
337
|
- lib/lib/ios8_last_launch_services_map_wrapper.rb
|
323
|
-
- lib/lib/
|
338
|
+
- lib/lib/keychain_wrapper.rb
|
324
339
|
- lib/lib/local_operations.rb
|
325
340
|
- lib/lib/otool_wrapper.rb
|
326
341
|
- lib/lib/plist_util.rb
|
@@ -343,6 +358,7 @@ files:
|
|
343
358
|
- lib/utils/ios-ssl-kill-switch/com.isecpartners.nabla.sslkillswitch_v0.5-iOS_6.1.deb
|
344
359
|
- lib/utils/keychain_dump/README
|
345
360
|
- lib/utils/keychain_dump/keychain_dump
|
361
|
+
- lib/utils/keychain_editor/keychaineditor
|
346
362
|
- lib/utils/pbwatcher/pbwatcher
|
347
363
|
- lib/utils/pcviewer/protectionclassviewer
|
348
364
|
- lib/utils/weak_class_dump/README
|
@@ -1,15 +0,0 @@
|
|
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
|