-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathextract_defs
executable file
·138 lines (127 loc) · 3.69 KB
/
extract_defs
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
#!/bin/bash
# 1. Extract the single lines with eval(base64_decode(..*));
# or containing the serialized array. Write code to decode
# or deserialize those lines.
rm -rf extracted
mkdir extracted
find . -name '*php.file' | xargs grep -l '^eval(base64_decode("' | while read FNAME # /home/bediger/src/php/malware/vigilante_suspected
do
echo "extracting defs and eval line from "$FNAME
# Find timestamp of original attack.
#TIMESTAMP=$(stat $FNAME | grep Modify: | awk '{print $2}')
PREFIX=$(echo $FNAME | sed 's/.php.file//')
NEWFNAME=$( echo $PREFIX.*.scans )
EPOCH=$( fgrep '[REQUEST_TIME]' $NEWFNAME | awk '{print $3}' )
TIMESTAMP=$(date --date="@$EPOCH" '+%Y-%m-%d' )
LETTER=a
while [[ -f extracted/defs.$TIMESTAMP$LETTER ]]
do
LETTER=$(echo $LETTER | tr "a-z" "b-za")
done
TIMESTAMP=$TIMESTAMP$LETTER
# Serialized array
echo '<?php' > extracted/defs.$TIMESTAMP
fgrep '$defs =' $FNAME >> extracted/defs.$TIMESTAMP
cat << 'ENDIT' >> extracted/defs.$TIMESTAMP
foreach ($defs as $i => $entry) {
print("{$entry[0]} {$entry[1]} {$entry[2]}\n");
}
ENDIT
# Encoded functions
echo '<?php' > extracted/eval.$TIMESTAMP
grep '^eval(base64_decode("' $FNAME | sed 's/eval/print/' >> extracted/eval.$TIMESTAMP
done
# 2. Print the elements of the reserialized arrays
DST=extracted_defs
SRC=extracted
rm -rf $DST
mkdir $DST
for FNAME in $SRC/defs.*
do
TIMESTAMP=$(basename $FNAME | sed 's/defs.//')
php $FNAME > $DST/def.$TIMESTAMP
done
# Complicated steps to get to 1 function per file,
# files organized by timestamp of original attack
echo "1. print what was eval-ed code into extracted_evals/"
DST=extracted_evals
SRC=extracted
rm -rf $DST
mkdir $DST
for FNAME in $SRC/eval.*
do
echo $FNAME
TIMESTAMP=$(basename $FNAME | sed 's/eval.//')
echo '<?php' > $DST/eval.$TIMESTAMP
php $FNAME >> $DST/eval.$TIMESTAMP
done
# Pretty print the r- and g-functions
echo "2. pretty-print the eval-ed code into formatted_evals/"
DST=formatted_evals
SRC=extracted_evals
rm -rf $DST
mkdir $DST
for FNAME in $SRC/eval.*
do
echo $FNAME
TIMESTAMP=$(basename $FNAME | sed 's/eval.//')
$HOME/src/php/reverse-php-malware/pp.php $FNAME > $DST/eval.$TIMESTAMP
done
# Substitute the serial number from the re-serialized array
# entry for the function in question. Random names are
# hard to remember.
echo "3. Substitute serial number for random function names, in-place formatted_evals"
SRC=formatted_evals
rm -rf EDITS
mkdir EDITS
for FNAME in $SRC/eval.*
do
echo $FNAME
TIMESTAMP=$(basename $FNAME | sed 's/eval.//')
# Make the ex commands from the deserialized array
# corresponding to a file of decoded functions
touch EDITS/edits.$TIMESTAMP
while read NUMBER RFUNC GFUNC
do
echo "%s/^function $RFUNC/function R$NUMBER/" >> EDITS/edits.$TIMESTAMP
echo "%s/^function $GFUNC/function G$NUMBER/" >> EDITS/edits.$TIMESTAMP
done < extracted_defs/def.$TIMESTAMP
echo "w!" >> EDITS/edits.$TIMESTAMP
echo "q" >> EDITS/edits.$TIMESTAMP
ex -s $FNAME < EDITS/edits.$TIMESTAMP
done
# Break each renamed function into its own file
echo "4. Break out renamed functions into their own files"
DST=renamed_functions
SRC=formatted_evals
rm -rf $DST
mkdir $DST
for FNAME in $SRC/eval.*
do
echo $FNAME
TIMESTAMP=$(basename $FNAME | sed 's/eval.//')
DIR=$DST/$TIMESTAMP
mkdir $DIR
while read LINE
do
if [[ $LINE =~ ^function\ ..* ]]
then
FUNC=$(echo $LINE | sed -e 's/function //' -e 's/(..*//')
OUTPUT=$DIR/$FUNC.php
touch $OUTPUT
if [[ $FUNC =~ G.* ]]
then
LINE=$(echo $LINE | sed 's/function ..*(/function cleanup(/')
fi
fi
if [[ $OUTPUT != "" ]]
then
if [[ $LINE == '<?php' ]]
then
:
else
echo $LINE >> $OUTPUT
fi
fi
done < $FNAME
done