forked from BishopFox/bfinject
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbfinject
More file actions
executable file
·251 lines (221 loc) · 6.97 KB
/
bfinject
File metadata and controls
executable file
·251 lines (221 loc) · 6.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/jb/bin/bash
CYCRIPT_PORT=1337
function help {
echo "Syntax: $0 [-p PID | -P appname] [-l /path/to/yourdylib | -L feature]"
echo
echo For example:
echo " $0 -P Reddit.app -l /path/to/evil.dylib # Injects evil.dylib into the Reddit app"
echo " or"
echo " $0 -p 1234 -L cycript # Inject Cycript into PID"
echo " or "
echo " $0 -p 4566 -l /path/to/evil.dylib # Injects the .dylib of your choice into PID"
echo
echo "Instead of specifying the PID with -p, bfinject can search for the correct PID based on the app name."
echo "Just enter \"-P identifier\" where \"identifier\" is a string unique to your app, e.g. \"fing.app\"."
echo
echo Available features:
echo " cycript - Inject and run Cycript"
echo " decrypt - Create a decrypted copy of the target app"
echo " test - Inject a simple .dylib to make an entry in the console log"
echo " ispy - Inject iSpy. Browse to http://<DEVICE_IP>:31337/"
echo
}
#
# check args
#
if [ "$1" != "-p" ] && [ "$1" != "-P" ]; then
help
exit 1
fi
if [ "$3" != "-l" -a "$3" != "-L" ]; then
help
exit 1
fi
if [ "$1" == "-p" ]; then
PID=$2
else
count=`ps axwww|grep "$2"|grep container|grep '.app'|grep -v grep |wc -l|sed 's/ //g'`
if [ "$count" != "1" ]; then
echo "[!] \"$2\" was not uniquely found, please check your criteria."
exit 1
fi
PID=`ps awwwx|grep "$2"|grep container|grep '.app'|grep -v grep|sed 's/^\ *//g'|cut -f1 -d\ `
bad=1
case "$PID" in
''|*[!0-9]*) bad=1 ;;
*) bad=0 ;;
esac
if [ "$bad" != "0" ]; then
echo "[!] Process not found for string \"$3\""
exit 1
fi
fi
declare -a DYLIBS
if [ "$3" == "-l" ]; then
FEATURE=""
DYLIBS=("$4")
else
FEATURE="$4"
case "$FEATURE" in
cycript)
DYLIBS=(dylibs/cycript.dylib dylibs/cycript-runner.dylib)
;;
decrypt)
DYLIBS=(dylibs/bfdecrypt.dylib)
;;
test)
DYLIBS=(dylibs/simple.dylib)
;;
ispy)
DYLIBS=(dylibs/iSpy.dylib)
;;
iSpy)
DYLIBS=(dylibs/iSpy.dylib)
;;
default)
help
exit 1
;;
esac
fi
#
# Be a good netizen and tidy up your litter
#
function clean_up {
if [ -d "$DYLIB_DIR" ] && [ "$DYLIB_DIR" != "/System/Library/Frameworks" ]; then
rm -rf "$DYLIB_DIR" >/dev/null 2>&1
fi
rm -f "$RANDOM_NAME" > /dev/null 2>&1
rm -f /bootstrap/usr/local/bin/bfinject4realz > /dev/null 2>&1
rm -f /bootstrap/usr/local/bin/jtool.liberios > /dev/null 2>&1
}
#
# Entitlements for dylib injection and for our injector binary.
#
if [ ! -f entitlements.xml ]; then
cat > entitlements.xml << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>platform-application</key>
<true/>
<key>get-task-allow</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<key>com.apple.system-task-ports</key>
<true/>
</dict>
</plist>
EOF
fi
#
# Detect LiberiOS vs Electra
#
if [ -f /bootstrap/inject_criticald ]; then
# This is Electra
echo "[+] Electra detected."
cp jtool.liberios /bootstrap/usr/local/bin/
chmod +x /bootstrap/usr/local/bin/jtool.liberios
JTOOL=/bootstrap/usr/local/bin/jtool.liberios
cp bfinject4realz /bootstrap/usr/local/bin/
INJECTOR=/bootstrap/usr/local/bin/bfinject4realz
elif [ -f /jb/usr/local/bin/jtool ]; then
# This is LiberiOS
echo "[+] Liberios detected"
JTOOL=jtool
INJECTOR=`pwd`/bfinject4realz
else
# echo "[!] Unknown jailbreak. Aborting."
# exit 1
echo "[+] Possible Chimera detected, handling the Electra way ;)"
cp jtool.liberios /usr/local/bin/
chmod +x /usr/local/bin/jtool.liberios
JTOOL=/usr/local/bin/jtool.liberios
cp bfinject4realz /usr/local/bin/
INJECTOR=/usr/local/bin/bfinject4realz
fi
#
# Do the actual injection into the remote process
#
for DYLIB in ${DYLIBS[@]}; do
if [ ! -f "$DYLIB" ]; then
echo "$DYLIB" doesn\'t exist
clean_up
exit 1
fi
# Use random filenames to avoid cached binaries causing "Killed: 9" messages.
RAND=`dd if=/dev/random bs=1 count=16 2>/dev/null | md5sum`
RANDOM_NAME="${INJECTOR%/*}/`dd if=/dev/random bs=1 count=16 2>/dev/null | md5sum`"
DYLIB_DIR="/System/Library/Frameworks/${RAND}.framework"
DYLIB_PATH="$DYLIB_DIR/$RAND.dylib"
# We'll give the injector as a random filename
cp "$INJECTOR" "$RANDOM_NAME"
chmod +x "$RANDOM_NAME"
#
# Find the full path to the target app binary
#
BINARY=`ps -o pid,command $PID|tail -n1|sed 's/^\ *//g'|cut -f2- -d\ `
if [ "$BINARY" == "COMMAND" ]; then
echo "[!] ERROR: PID $PID not found."
clean_up
exit 1
fi
echo "[+] Injecting into '$BINARY'"
#
# Get the Team ID that signed the target app's binary.
# We need this so we can re-sign the injected .dylib to fool the kernel
# into assuming the .dylib is part of the injectee bundle.
# This allows is to map the .dylib into the target's process space via dlopen().
#
echo "[+] Getting Team ID from target application..."
TEAMID=`$JTOOL --ent "$BINARY" 2> /dev/null | grep -A1 'com.apple.developer.team-identifier' | tail -n1 |sed 's/ //g'|cut -f2 -d\>|cut -f1 -d\<`
if [ "$TEAMID" == "" ]; then
echo "[+] WARNING: No Team ID found. Continuing regardless, but expect weird stuff to happen."
fi
#
# Move the injectee dylib to a sandbox-friendly location
#
mkdir "$DYLIB_DIR"
cp "$DYLIB" "$DYLIB_PATH"
#
# Thin the binary so that it's not FAT and contains only an arm64 image
echo "[+] Thinning dylib into non-fat arm64 image"
$JTOOL -arch arm64 -e arch "$DYLIB_PATH" >/dev/null 2>&1
if [ "$?" == "0" ]; then
rm -f "$DYLIB_PATH"
DYLIB_PATH="${DYLIB_PATH}.arch_arm64"
else
echo "[!] WARNING: Wasn't able to thin the dylib."
fi
#
# Sign platform entitlements and Team ID into our dylib
#
echo "[+] Signing injectable .dylib with Team ID $TEAMID and platform entitlements..."
$JTOOL --sign platform --ent entitlements.xml --inplace --teamid "$TEAMID" "$DYLIB_PATH" > /dev/null 2>&1
if [ "$?" != "0" ]; then
echo jtool dylib signing error. barfing.
clean_up
exit 1
fi
#
# Sign the randomly-renamed injector binary with platform entitlements
#
$JTOOL --sign platform --ent entitlements.xml --inplace "$RANDOM_NAME" >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo jtool "$RANDOM_NAME" signing error. barfing.
clean_up
exit 1
fi
#
# Inject!
#
"$RANDOM_NAME" "$PID" "$DYLIB_PATH"
done
#
# EOF
#
echo "[+] So long and thanks for all the fish."
clean_up
exit 0