This repository has been archived by the owner on May 27, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 134
/
base
executable file
·374 lines (318 loc) · 10.9 KB
/
base
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
374
#!/bin/bash
####################################################################
# PREY Base Functions - by Tomas Pollak (bootlog.org)
# URL: http://preyproject.com
# License: GPLv3
####################################################################
####################################################################
# base functions
####################################################################
# fetches a var and then assigns it as $value
# expects the name of hash and then the name of var
function get_var {
HASH="$1[*]"
local ${!HASH}
eval 'echo ${'"${2}"'} | sed -e "s/%20/ /g"'
}
# if you need to fetch a specific trace or file
function get_trace {
get_var traces ${current_module}__$1
}
function get_file {
get_var files ${current_module}__$1
}
function add_trace {
trace="${current_module}__$1=$2"
echo " -- Adding trace for $current_module: $1 -> $2"
# we need to encode whitespaces, otherwise well get into trouble
trace=`echo $trace | sed 's/\s/%20/g'`
traces[${#traces[*]}]="$trace"
}
function add_file {
if [ -f "$2" ]; then
echo " -- Adding file for $current_module: $1 -> $2"
files[${#files[*]}]=${current_module}__$1=$2
fi
}
function list_traces {
# echo " -- ${#traces[*]} traces gathered!"
for t in "${traces[@]}"
do
current_node=`echo $t | sed 's/^\([^_].*\)__\(.*\)$/\1/'`
# if [ $current_node != $previous_node ]; then
# echo $current_node
# fi
if [ "$post_method" == 'http' ]; then
# echo -n $t | sed 's/^\([^_].*\)__\([^=].*\)=\(.*\)/\1[\2]="\3"\&/' # query string
echo "-F $t" | sed 's/^\([^_].*\)__\([^=].*\)=\(.*\)/\1[\2]=\3/' # form field list
# echo $t | sed 's/^\([^_].*\)__\([^=].*\)=\(.*\)$/<\2>\3<\/\2>/' # xml
else
# removes module name, then capitalizes, and replaces _'s with whitespaces
echo -e "$t\n" | sed 's/^\([^_].*\)__//' | sed 's/^./\u&/' | sed 's/_/ /'
fi
# previous_node=$current_node
done
}
function list_files {
# echo " -- ${#files[*]} files gathered!"
for f in "${files[@]}"
do
if [ "$post_method" == 'http' ]; then
# echo -e "-F $f" | sed -e 's/=/=@/'
echo "-F $f" | sed 's/^\([^_].*\)__\([^=].*\)=\(.*\)/\1[\2]=@\3/'
else # just list the file paths
echo -e $f | sed -e 's/.*=//'
fi
done
}
function remove_traces {
unset -v traces
echo ' -- Dropping all traces!'
}
function remove_files {
for f in "${files[@]}"
do
file=`echo $f | sed -e 's/^.*=//'`
rm -f $file
echo " -- Removed $file"
done
}
####################################################################
# string functions
####################################################################
# TODO: should switch to more advanced forms of encryption!
function encrypt {
echo -n "$1" | openssl enc -base64
}
function decrypt {
echo "$1" | openssl enc -base64 -d
}
###################################################################
# request/response functions
####################################################################
getter='curl -s'
# returns if we have have network access, otherwise 0
# you can check against the gateway or the net, change it if you like
function check_net_status {
get_gateway_ip
net_check_target=$gateway_ip
# net_check_target="www.google.com"
connected=`ping -q -c 1 $net_check_target &> /dev/null && echo 1 || echo 0`
}
# we could eventually use a different method for status checking
function check_status {
if [ "$post_method" == 'http' ]; then
check_url="$check_url/devices/$device_key.xml"
fi
headers=`$getter -I $check_url`
status=`echo "$headers" | awk /HTTP/ | sed 's/[^200|302|400|404|500]//g' | sed 's/^0//'`
}
# we may eventually use a specific header for Prey
function parse_headers {
content_type=`echo "$headers" | grep "Content-Type" | sed 's/.*: \([a-z\/-]*\).*/\1/'`
}
# this is where the magic will happen. :)
# some ideas:
# if its a shell script, run it and post back the response
# if its a zip file, unzip it in modules and run the active modules (the executable ones)
# if its a xml/json file, parse it and assign config values correspondingly
function process_response {
if [ "$content_type" == "text/xml" ]; then
echo ' -- Got XML. Parsing...'
response_type='xml'
elif [ "$content_type" == "application/octet-stream" ]; then
echo ' -- Got a ZIP file! What shall we do with it?'
response_type='zip'
elif [ "$content_type" == "text/plain" ]; then
echo ' -- Got a text file! Lets see if its something we can actually run.'
response_type='text'
elif [ "$content_type" == "text/html" ]; then
echo " -- Response was just an HTML file. Lets just do our job."
return
else
return
fi
response=`$getter $check_url`
eval 'process_'"${response_type}"''
}
# REALLY untested. function expects a <modules> section in the xml and activates de modules as requested
# format should be as follows:
# <device>
# <device-type>phone</device-type>
# <missing>true</missing>
# </device>
# <configuration>
# <delay>10</delay>
# <loop>0</loop>
# </configuration>
# <modules>
# <module name="alert" active="true">
# <alert-message>asdasd</alert-message>
# </module>
# <module name="autologin" active="true">
# <user-name>guest</user-name>
# </module>
# <module name="report" active="false">
# <traceroute>y</traceroute>
# </module>
# </modules>
# it should also work with one-line module entries (with no configuration), such as
#
# <module name="location" active="true" />
function process_xml {
process_config
process_modules
}
function process_config {
echo -e "$response" | sed -n '/<config>/,/<\/config>/p' | grep -v "config>" | while read line; do
if [[ "$line" =~ 'delay="' ]]; then
delay=`echo $line | sed 's/^<.*>\([^<].*\)<.*>$/\1/'`
if [ -n "$delay" ]; then
(crontab -l | grep -v prey; echo "*/$delay * * * * $base_path/prey.sh > /dev/null") | crontab -
fi
fi
done
}
function process_modules {
echo -e "$response" | sed -n '/<modules>/,/<\/modules>/p' | grep -v "/module" | sed '1d' | while read line; do
if [[ "$line" =~ 'name="' ]]; then # we have a module node
module=`echo $line | sed 's/^<module name="\(.*\)" .*$/\1/g'`
# echo " -- Got instructions for $module module."
if [[ "$line" =~ "true" ]]; then # module is active
if [ ! -d $base_path/modules/$module ]; then
install_new_module $module # <-- we're only installing the module if it is active
echo " -- Installing new $module module..."
fi
if [ ! -x $base_path/modules/$module/run ]; then
echo " -- Enabling $module module!"
chmod +x $base_path/modules/$module/run
fi
else # module is inactive
if [ -x $base_path/modules/$module/run ]; then
echo " -- Disabling $module module!"
chmod -x $base_path/modules/$module/run
fi
module='' # this allows us to check below if the module is inactive
fi
else
if [[ -n "$module" && -f $base_path/modules/$module/config ]]; then # module is active and has configuration
param=`echo $line | sed 's/^<\(.*\)>.*<.*>$/\1/' | sed 'y/-/_/'` # we also replace -'s to _'s
value=`echo $line | sed 's/^<.*>\([^<].*\)<.*>$/\1/'`
# echo " -- Setting param $param -> $value for $module module."
sed -i -e "s/$param='.*'/$param='$value'/" $base_path/modules/$module/config
fi
fi
done
}
# this is REALLY untested stuff
# we should put this in a module with the new hash-by-module trace structure
function process_text {
if [[ -n `echo $response | grep '#!/bin/bash'` && ! -n `echo $response | grep ' rm '` ]]; then
echo ' -- Valid script! Lets get it on.'
script=/tmp/script.sh
echo -e $response > $script
chmod +x $script
output=`$script`
add_trace 'script_output' $output
else
echo " !! Invalid script. Remember Prey doesn't run any external script which try to destroy things (for security reasons)."
fi
}
function process_zip {
echo ' -- Processing ZIP... (well, not really :)'
}
####################################################################
# module functions
####################################################################
# this should work, we only need to set up the module repository!
function install_new_module {
wget "$check_url/modules/download/$module?api_key=$api_key" -o /tmp/$1.zip &> /dev/null
if [ -f "/tmp/$1.zip" ]; then
echo " -- Got new module from $check_url! Unpackaging..."
mv /tmp/$1.zip $base_path/modules
unzip $base_path/modules/$1.zip
rm $base_path/modules/$1.zip
echo " -- New $1 module placed and ready to go!"
fi
}
function run_active_modules {
for module_path in `find $base_path/modules -maxdepth 1 -mindepth 1 -type d`; do
if [ -x $module_path/run ]; then
current_module=`echo "$module_path" | sed "s:$base_path\/modules\/::"`
echo -e " -- Running $current_module module!"
# if there's a language file, lets run it
if [ -f $module_path/lang/$lang ]; then
. $module_path/lang/$lang
elif [ -f $module_path/lang/$lang ]; then
. $module_path/lang/en
fi
# if there's a config file, lets run it as well
if [ -f $module_path/config ]; then
. $module_path/config
fi
# lets load the base functions for the module
if [ -f $module_path/platform/base ]; then
. $module_path/platform/base
fi
# and the OS-specific if there are
if [ -f $module_path/platform/$os ]; then
. $module_path/platform/$os
fi
# now, go!
. $module_path/run
fi
done
unset -v current_module
}
####################################################################
# data posting functions
####################################################################
function post_data {
trace_list=`list_traces`
file_list=`list_files`
if [[ $trace_list || $file_list ]]; then
if [ "$test_mode" == 1 ]; then
echo ' >> This is where the data gets sent. Though not in test mode!'
else
trace_file=/tmp/prey_traces.tmp
echo "$trace_list" > $trace_file
eval 'send_via_'"${post_method}"''
rm $trace_file
fi
remove_traces
remove_files
else
echo " -- No data to send. We're done!"
fi
}
function send_via_email {
decoded_pass=`decrypt "$smtp_password"`
complete_subject="$mail_subject @ `date +"%a, %e %Y %T %z"`"
response=`$base_path/lib/sendEmail -f "$mail_from" -t "$mail_to" -u "$complete_subject" -s $smtp_server -a $file_list -o message-file=$trace_file tls=auto username=$smtp_username password=$decoded_pass`
if [[ "$response" =~ "ERROR" ]]; then
echo -e "$STRING_ERROR_EMAIL"
echo -e "\n This is the complete error message: \n $response\n"
fi
}
function send_via_http {
post_url=`echo $check_url | sed 's/\.xml/\/reports/'`
if [ -n "$post_url" ]; then
if [ -n "$api_key" ]; then
post_data="$file_list -F api_key=$api_key"
fi
response=`curl -s $trace_list $post_data "$post_url"`
# echo $response
else
echo ' !! You need to set up a URL for the HTTP sending to work!'
fi
}
function send_via_scp {
if [[ -n "$scp_server" && -n "$scp_path" ]]; then
echo -e " -- Uploading the stuff to $scp_path in $scp_server..."
new_folder="prey_data_`echo $start_time | sed 'y/ :/_-/'`"
ssh $scp_server mkdir $scp_path/$new_folder
status=`scp $trace_file $file_list $scp_server:$scp_path/$new_folder`
else
echo ' !! You need to set up a server in order to send the report via SCP!'
fi
}