├── Readme.md
├── options
├── backdoorscan.php
├── clamav-0.99.2.tar.gz
├── clamav-0.99.2.tar.gz.sig
├── excludes.txt
└── rkhunter-1.4.4.tar.gz
└── rcsirt-linux_triage.sh
/Readme.md:
--------------------------------------------------------------------------------
1 | R-CSIRT Linux Triage tool
2 | ====
3 |
4 | Linux Server Triage tool written in Shell Script.
5 |
6 |
7 | ## Description
8 | Linux Server Triage tool for CSIRT.
9 | * Collect not only 'log files' but also 'config file' and "web server's script files"
10 | * Find Suspicious Script and Binary on Web Server.
11 | * Include : Backup function of Web Server All Contents on DOCUMENT_ROOT
12 | * [2018.06.20] AUTO Web server's DOCUMENT_ROOT and WEB CONFIG Directories. ( httpd,apache2,nginx support checked)
13 | * [2018.06.20] LOG Archive SCOPE: Automatically from 1 year ago to TODAY when this executed.
14 |
15 | Operation Check :
16 | Linux : Ubuntu 14.04, 16.04, Ubuntu Server, CentOS 7.0, 7.5
17 |
18 | ## Requirements
19 | No Requirement for Default Usage.
20 | If you use [ClamAV](https://www.clamav.net) and [RKhunter](http://rkhunter.sourceforge.net) scan,
21 | Please put these installers into *option* directory.
22 | clamav-0.99.2 and rkhunter-1.4.4 had already set.
23 |
24 | ## Usage
25 |
26 | 0. Set the rcsirt-linux_triage.sh and options folder in the same directory which Linux server you want to do triage in.
27 |
28 | 1. Check configs(const variable) on shell script top.
29 |
30 | 2. Excluded Folders
31 | Edit and Add it in ./options/excludes.txt
32 | Last LF(\n) doesn't need.
33 |
34 | 3. Execute
35 | `$ sudo bash rcsirt-linux_triage.sh`
36 |
37 | 4. Pull tar.gz file created.
38 | Output files : Please See source code in detail.
39 | ERROR LOG => 0_SCRIPT-ERRORS.txt
40 | Output files tree LOG => 1_OUTPUT-TREE.txt
41 |
42 | *Recruit-CSIRT does not assume any responsibility about using this tool.*
43 | **you can take advantage on Self-responsibility**
44 |
45 | ## Licence
46 | MIT
47 |
48 |
49 | ## Author
50 | Tatsuya Ichida ([icchida](https://github.com/icchida))
51 | Ref: r-csirt ([r-csirt](https://github.com/r-csirt))
52 |
53 | ## Refer Other Triage Tools and Thanks
54 | * [ir-triage-toolkit](https://github.com/rshipp/ir-triage-toolkit)
55 | * [Fastir_Collector_Linux](https://github.com/SekoiaLab/Fastir_Collector_Linux)
56 | * [ir-rescue(-nix)](https://github.com/diogo-fernan/ir-rescue)
57 |
58 | And Others some tools. /options/backdoorscan.php was got from Internet, We didn't develop it by ourselves.
59 |
--------------------------------------------------------------------------------
/options/backdoorscan.php:
--------------------------------------------------------------------------------
1 | 10000000) continue;
40 | $fp = fopen($path,'r');
41 | $code = fread($fp,filesize($path));
42 | fclose($fp);
43 | if(empty($code)) continue;
44 | foreach($matches as $matche) {
45 | $array = array();
46 | preg_match($matche,$code,$array);
47 | if(!$array) continue;
48 | $len = strlen($array[0]);
49 | if($len > 0) {
50 | echo 'special_file '.htmlspecialchars(substr($array[0],0,100)).' '.$path.' \n';
51 | flush(); ob_flush(); break;
52 | }
53 | }
54 | unset($code,$array);
55 | }
56 | }
57 | closedir($handle);
58 | return true;
59 | }
60 |
61 | function strdir($str) { return str_replace(array('\\','//','//'),array('/','/','/'),chop($str)); }
62 |
63 |
64 | $dir = strdir($argv[1]);
65 | $exs = '/(\\.php|\\.inc|\\.phtml)/i';
66 | echo antivirus($dir,$exs,$matches) ? 'completed' : 'halted';
67 | ?>
68 |
--------------------------------------------------------------------------------
/options/clamav-0.99.2.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Recruit-CSIRT/LinuxTriage/faef286b0ae65a04c5ae4a905248b4d4f1e38145/options/clamav-0.99.2.tar.gz
--------------------------------------------------------------------------------
/options/clamav-0.99.2.tar.gz.sig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Recruit-CSIRT/LinuxTriage/faef286b0ae65a04c5ae4a905248b4d4f1e38145/options/clamav-0.99.2.tar.gz.sig
--------------------------------------------------------------------------------
/options/excludes.txt:
--------------------------------------------------------------------------------
1 | /dev
--------------------------------------------------------------------------------
/options/rkhunter-1.4.4.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Recruit-CSIRT/LinuxTriage/faef286b0ae65a04c5ae4a905248b4d4f1e38145/options/rkhunter-1.4.4.tar.gz
--------------------------------------------------------------------------------
/rcsirt-linux_triage.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # R-CSIRT
4 | # Date: 2018.06.20
5 | # Version: 2.0
6 | # usage: sudo bash rcsirt-linux_triage.sh
7 | # Licence: MIT
8 |
9 | [[ $UID == 0 || $EUID == 0 ]] || (
10 | echo "Must be root! Please execute after 'su -' OR with 'sudo' . "
11 | exit 1
12 | ) || exit 1
13 |
14 |
15 | ### dynamic Configs
16 | WEBROOT=()
17 | WEBSERVICE=()
18 | WEBROOT+= ###### web server document root dir (IF YOU ALREADY KNOW, Please ADD)
19 | WEBSERVICE+= ###### web server installed directory (IF YOU ALREADY KNOW, Please ADD)
20 | STARTDATE=$((`date -I | cut -d"-" -f1`-1))-`date -I | cut -d"-" -f2,3` ###### start date score for getting log rotation file (DEFAULT 1 year ago) except for boot.log,kern.log,auth.log
21 | ENDDATE=`date -I | cut -d"-" -f1,2`-$((`date -I | cut -d"-" -f3`+1)) ###### end date score for getting log rotation file ( TODAY ) except for boot.log,kern.log,auth.log
22 | ###
23 |
24 | ### static Configs
25 | EXCLUDES_PATHS=./options/excludes.txt ###### exclude paths from the directory listing. Each path should be on a new line.
26 | SaveCWD=1 ###### SAVE OUTPUT FILE TO WORKING DIRECTORY (SAME AS SCRIPT)
27 | STORAGETEST=1 ###### STORAGE TEST VARIABLES : STORAGETEST: 1=enable
28 | MINSPACE=1000000 ###### MINSPACE(KB): Set to minimum number of KB required to keep temp files locally
29 | IRCASE=`hostname` ###### basename of results archive
30 | LOC=/tmp/$IRCASE ###### output destination, change according to needs
31 | TMP=$LOC/$IRCASE'-tmp.txt' ###### tmp file to redirect results
32 | ERROR_LOG=$LOC/0_SCRIPT-ERRORS.txt ###### redirect stderr and Debug echo
33 | PHPBACKDOOR=./options/backdoorscan.php ###### phpbackdoor script
34 | ## FLAG options
35 | HASHFLAG=1 ###### HashFlag 1=enable : get binary hash
36 | CLAMAVFLAG=0 ###### clamavFlag 1= install clamav and scan full
37 | RKHUNTERFLAG=0 ###### rkhunterFlag 1= install rkhunter and scan
38 | MESSAGEFLAG=1 ###### messageFlag 1= collect /var/log/messages and syslog (eg: mail log)
39 | BACKUPFLAG=0 ###### BACKUPFLAG 1= copy web server conf, contents for backup
40 | ###
41 |
42 |
43 | check_tmpstorage(){
44 | # Check that there is at least MINSPACE KB available on /
45 | if [ "$STORAGETEST" = "1" ] ; then
46 | echo -e "\n[Debug][check_tmpstorage] check /tmp storage enough..."
47 | DF=$(df /tmp)
48 | while IFS=' ' read -ra RES; do
49 | LEN=${#RES[@]}
50 | AVAIL=`expr $LEN - 3`
51 | if [ ${RES[$AVAIL]} -lt $MINSPACE ]
52 | then
53 | echo Less than $MINSPACE available. Exiting.
54 | exit
55 | fi
56 | done <<< $DF
57 | fi
58 | }
59 |
60 | excludes_paths(){
61 | # To exclude paths from the directory listing, provide a file called
62 | EXCLUDES="-path /var/cache -o -path /var/spool"
63 | if [ -f $EXCLUDES_PATHS ]; then
64 | while read line
65 | do
66 | EXCLUDES="$EXCLUDES -o -path $line"
67 | done <$EXCLUDES_PATHS
68 | fi
69 | echo -e "\n[Debug][excludes_paths] set excludes_paths [$EXCLUDES]..."
70 | }
71 |
72 |
73 | prepare(){
74 | mkdir $LOC
75 | touch $ERROR_LOG
76 | echo -e "\n[Debug][prepare] mkdir "$LOC"\n"
77 | } 2> /dev/null
78 |
79 | get_userprofile(){
80 | # userprofile
81 | mkdir $LOC/Dir_userprofiles
82 | while read line
83 | do
84 | user=`echo "$line" | cut -f1 -d:`
85 | home=`echo "$line" | cut -f6 -d:`
86 | mkdir $LOC/Dir_userprofiles/$user
87 | # user shell history
88 | echo -e "\n[Debug][userprofile][$user] get user shell history ... to Dir_userprofiles/$user/shellhistory.txt"
89 | for f in $home/.*_history; do
90 | count=0
91 | while read line
92 | do
93 | echo $f $count $line >> $LOC/Dir_userprofiles/$user/$IRCASE'-shellhistory.txt'
94 | echo $f $count $line >> $LOC/Dir_userprofiles/$user/$IRCASE'-shellhistory.txt'
95 | count=$(( $count + 1 ))
96 | done < $f
97 | done
98 | # user contabs
99 | echo -e "\n[Debug][userprofile][$user] get user crontabs ... to Dir_userprofiles/$user/crontab.txt"
100 | crontab -u $user -l > $LOC/Dir_userprofiles/$user/$IRCASE'-crontab.txt'
101 | # ssh known hosts
102 | echo -e "\n[Debug][userprofile][$user] get ssh known hosts ... to Dir_userprofiles/$user/ssh_known_hosts.txt"
103 | cp -RH $home/.ssh/known_hosts $LOC/Dir_userprofiles/$user/$IRCASE'-ssh_known_hosts.txt'
104 | # ssh config
105 | echo -e "\n[Debug][userprofile][$user] get ssh config ... to Dir_userprofiles/$user/ssh_config.txt"
106 | cp -RH $home/.ssh/config $LOC/Dir_userprofiles/$user/$IRCASE'-ssh_config.txt'
107 | done < /etc/passwd
108 |
109 | # user accounts
110 | echo -e "\n[Debug][userprofile] get user accounts ... to passwd.txt"
111 | cp -RH /etc/passwd $LOC/$IRCASE'-passwd.txt'
112 |
113 | # user groups
114 | echo -e "\n[Debug][userprofile] get user groups ... to group.txt"
115 | cp -RH /etc/group $LOC/$IRCASE'-group.txt'
116 |
117 | # user accounts
118 | {
119 | echo -e "\n[Debug][userprofile] get user shadows ... to shadow.txt"
120 | while read line
121 | do
122 | user=`echo "$line" | cut -d':' -f1`
123 | pw=`echo "$line" | cut -d':' -f2`
124 | # ignore the salt and hash, but capture the hashing method
125 | hsh_method=`echo "$pw" | cut -d'$' -f2`
126 | rest=`echo "$line" | cut -d':' -f3,4,5,6,7,8,9`
127 | echo "$user:$hsh_method:$rest"
128 | done < /etc/shadow
129 | } > $LOC/$IRCASE'-shadow.txt'
130 | }
131 |
132 | get_systeminfo(){
133 | # version information
134 | echo -e "\n[Debug][systeminfo] get version infomation ... to virsion.txt"
135 | {
136 | echo -n "kernel_name="; uname -s;
137 | echo -n "nodename="; uname -n;
138 | echo -n "kernel_release="; uname -r;
139 | echo -n "kernel_version="; uname -v;
140 | echo -n "machine="; uname -m;
141 | echo -n "processor="; uname -p;
142 | echo -n "hardware_platform="; uname -i;
143 | echo -n "os="; uname -o;
144 |
145 | } > $LOC/$IRCASE'-version.txt'
146 |
147 | # kernel modules
148 | echo -e "\n[Debug][systeminfo] get kernel modules ... to modules.txt"
149 | lsmod | sed 1d > $TMP
150 | while read module size usedby
151 | do
152 | {
153 | echo -e $module'\t'$size'\t'$usedby;
154 | modprobe --show-depends $module;
155 | modinfo $module;
156 | echo "";
157 | } >> $LOC/$IRCASE'-modules.txt'
158 | done < $TMP
159 | rm $TMP
160 |
161 | # list of PCI devices
162 | echo -e "\n[Debug][systeminfo] get PCI devices list ... to lspci.txt"
163 | if [ -x /sbin/lspci ]
164 | then
165 | # rhel5
166 | LSPCI=/sbin/lspci
167 | else
168 | LSPCI=`which ifconfig`
169 | fi
170 | $LSPCI > $LOC/$IRCASE'-lspci.txt'
171 |
172 | # locale information
173 | echo -e "\n[Debug][systeminfo] get locale info ... to locale.txt"
174 | locale > $LOC/$IRCASE'-locale.txt'
175 |
176 | # installed packages with version information - ubuntu
177 | echo -e "\n[Debug][systeminfo] get installed packages on ubuntu ... to package.txt"
178 | if dpkg-query -W &> /dev/null
179 | then
180 | dpkg-query -W -f='${PackageSpec}\t${Version}\n' > $LOC/$IRCASE'-packages.txt'
181 | fi
182 | # installed packages with version information - redhat/centos
183 | echo -e "\n[Debug][systeminfo] get installed packages on redhat/centos ... to package.txt"
184 | if /bin/rpm -qa --queryformat "%{NAME}\t%{VERSION}\n" &> /dev/null
185 | then
186 | /bin/rpm -qa --queryformat '%{NAME}\t%{VERSION}\n' >> $LOC/$IRCASE'-packages.txt'
187 | fi
188 |
189 | # kernel ring buffer messages
190 | echo -e "\n[Debug][systeminfo] get kernel ring buffer message [dmeg] ... to dmesg.txt"
191 | {
192 | if dmesg -T &> /dev/null
193 | then
194 | dmesg -T
195 | else
196 | dmesg
197 | fi
198 | } > $LOC/$IRCASE'-dmesg.txt'
199 |
200 | # network interfaces
201 | echo -e "\n[Debug][systeminfo] get network interfaces [ifconfig] ... to ifconfig.txt"
202 | if [ -x /sbin/ifconfig ]
203 | then
204 | # rhel5
205 | IFCONFIG=/sbin/ifconfig
206 | else
207 | IFCONFIG=`which ifconfig`
208 | fi
209 | $IFCONFIG -a > $LOC/$IRCASE'-ifconfig.txt'
210 |
211 | # mounted devices
212 | echo -e "\n[Debug][systeminfo] Collecting information about currently mounted devices ... to mounted_devices.txt"
213 | mount > $LOC/$IRCASE_'lin-mounted_devices.txt'
214 |
215 |
216 | }
217 |
218 |
219 | get_activity(){
220 | # running processes
221 | echo -e "\n[Debug][activity] get running process [ps] ... to ps.txt"
222 | {
223 | PS_FORMAT=user,pid,ppid,vsz,rss,tname,stat,stime,time,args
224 | if ps axwwSo $PS_FORMAT &> /dev/null
225 | then
226 | # bsd
227 | ps axwwSo $PS_FORMAT
228 | elif ps -eF &> /dev/null
229 | then
230 | # gnu
231 | ps -eF
232 | else
233 | # bsd without ppid
234 | ps axuSww
235 | fi
236 | } > $LOC/$IRCASE'-ps.txt'
237 |
238 | # active network connections
239 | echo -e "\n[Debug][activity] get network conections [netstat] ... to netstat.txt"
240 | {
241 | if netstat -pvWanoee &> /dev/null
242 | then
243 | # gnu
244 | netstat -pvWanoee
245 | else
246 | # redhat/centos
247 | netstat -pvTanoee
248 | fi
249 | } > $LOC/$IRCASE'-netstat.txt'
250 |
251 | # active network infomation
252 | echo -e "\n[Debug][activity] get network informations [interface|ifconfig|ip|route|lsof|hosts] ... to netinfo.txt"
253 | {
254 | echo -e "\n";cat /etc/network/interfaces
255 | echo -e "\n";ifconfig -a
256 | echo -e "\n"; ip addr
257 | echo -e "\n";ip link
258 | echo -e "\n;"netstat -lnput
259 | echo -e "\n";lsof -i -n -P
260 | echo -e "\n";ss -ap
261 | echo -e "\n";route -n # "netstat -nr"; "ip route"
262 | echo -e "\n";ip neigh
263 | echo -e "\n";cat /etc/hosts
264 | echo -e "\n";cat /etc/hosts.allow
265 | echo -e "\n";cat /etc/hosts.deny
266 | } > $LOC/$IRCASE'-netinfo.txt'
267 |
268 | # current logged in users
269 | echo -e "\n[Debug][activity] get current logged in users ... to who.txt(\$who), who.bin(\$utmp)"
270 | if who -a &> /dev/null
271 | then
272 | who -a > $LOC/$IRCASE'-who.txt'
273 | else
274 | cat /var/run/utmp > $LOC/$IRCASE'-who.bin'
275 | fi
276 | # last logged in users
277 | echo -e "\n[Debug][activity] get last logged in users ... to last.txt"
278 | if last -Fwx -f /var/log/wtmp* &> /dev/null
279 | then
280 | last -Fwx -f /var/log/wtmp* > $LOC/$IRCASE'-last.txt'
281 | else
282 | cp -RH /var/log/wtmp* > $LOC/
283 | fi
284 | }
285 |
286 | get_fileinfo(){
287 | # list of open files
288 | if [ -x /usr/sbin/lsof ]
289 | then
290 | LSOF=/usr/sbin/lsof
291 | elif [ -x /sbin/lsof ]
292 | then
293 | LSOF=/sbin/lsof
294 | else
295 | LSOF=`which lsof`
296 | fi
297 |
298 | # list of open files, link counts
299 | echo -e "\n[Debug][fileinfo] get list of open files, link counts ... to linkcounts.txt"
300 | $LSOF +L > $LOC/$IRCASE'-lsof-linkcounts.txt'
301 | # list of open files, with network connection
302 | echo -e "\n[Debug][fileinfo] get list of open files, with network connection ... to netfiles.txt"
303 | $LSOF -i > $LOC/$IRCASE'-lsof-netfiles.txt'
304 |
305 | # directory listings
306 | # The listings are actually done through the 'find' command, not the
307 | # ls command. The '-xdev' flag prevents the script from walking directories on other file systems.
308 | echo -e "\n[Debug][fileinfo] get directory listings ... to ls.txt"
309 | echo -e "\n"$EXCLUDES
310 | {
311 | find / -xdev \( $EXCLUDES \) -prune -o -type f -printf '%C+\t%CZ\t' -ls;
312 | } > $LOC/$IRCASE'-ls.txt';
313 |
314 | }
315 |
316 | get_servicereg(){
317 | # list all services and runlevel
318 | echo -e "\n[Debug][servicereg] get list all services and runlevel ... to chkconfig.txt"
319 | if chkconfig -l &> /dev/null; then
320 | chkconfig -l > $LOC/$IRCASE'-chkconfig.txt'
321 | else
322 | chkconfig --list > $LOC/$IRCASE'-chkconfig.txt'
323 | fi
324 | # list all services and runlevel on ubuntu16 ~
325 | if sysv-rc-conf -list &> /dev/null; then
326 | sysv-rc-conf -list >> $LOC/$IRCASE'-chkconfig.txt'
327 | else
328 | insserv -s >> $LOC/$IRCASE'-chkconfig.txt'
329 | fi
330 | # list all services and runlevel on cent7 ~
331 | systemctl list-unit-files >> $LOC/$IRCASE'-chkconfig.txt'
332 |
333 |
334 | # cron
335 | echo -e "\n[Debug][servicereg] get cron information ... to cron*.txt"
336 | # users with crontab access
337 | cp -RH /etc/cron.allow $LOC/$IRCASE'-cronallow.txt'
338 | # users with crontab access
339 | cp -RH /etc/cron.deny $LOC/$IRCASE'-crondeny.txt'
340 | # crontab listing
341 | cp -RH /etc/crontab $LOC/$IRCASE'-crontab.txt'
342 | # cronfile listing
343 | ls -al /etc/cron.* > $LOC/$IRCASE'-cronfiles.txt'
344 | }
345 |
346 | get_logs(){
347 | # logs
348 | # SCOPE : STARTDATE ~ ENDDATE find . -type f -name "*.php" -newermt "$STARTDATE" -and ! -newermt "$ENDDATE" -ls
349 | echo "LOG SCOPE: FROM "$STARTDATE" TO "$ENDDATE
350 |
351 | # httpd logs
352 | echo -e "\n[Debug][logs] get httpd log ... to Dir_httpdlogs"
353 | mkdir $LOC/Dir_httpdlogs
354 | if [ -d "/var/log/httpd/" ]; then
355 | find /var/log/httpd/ -name *access* -o -name *error* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_httpdlogs/
356 | fi
357 | # apache logs
358 | echo -e "\n[Debug][logs] get apache log ... to Dir_apachelogs"
359 | mkdir $LOC/Dir_apachelogs
360 | if [ -d "/var/log/apache2/" ] || [ -d "/var/log/apache/" ]; then
361 | find /var/log/apache* -name *access* -o -name *error* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_apachelogs/
362 | fi
363 |
364 | # nginx logs
365 | echo -e "\n[Debug][logs] get nginx log ... to Dir_nginxlogs"
366 | mkdir $LOC/Dir_nginxlogs
367 | if [ -d "/var/log/nginx/" ]; then
368 | find /var/log/nginx/ -name *access* -o -name *error* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_nginxlogs/
369 | fi
370 |
371 | # squid logs
372 | echo -e "\n[Debug][logs] get squid log ... to Dir_squidlogs"
373 | mkdir $LOC/Dir_squidlogs
374 | if [ -d "/var/log/squid/" ] || [ -d "/var/log/squid3/" ]; then
375 | find /var/log/squid* -name *access* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_squidlogs/
376 | fi
377 |
378 | # mysql & maria logs
379 | echo -e "\n[Debug][logs] get mysql & maria log ... to Dir_dblogs/mariadb"
380 | mkdir $LOC/Dir_dblogs
381 | if [ -d "/var/log/mariadb/" ]; then
382 | mkdir $LOC/Dir_dblogs/mariadb
383 | find /var/log/mariadb/* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_dblogs/mariadb/
384 | elif [ -d "/var/log/mysql/" ]; then
385 | mkdir $LOC/Dir_dblogs/mysqldb
386 | find /var/log/mysql/* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_dblogs/mysqldb/
387 | fi
388 |
389 |
390 | # boot logs
391 | echo -e "\n[Debug][logs] get boot log ... to Dir_bootlogs"
392 | mkdir $LOC/Dir_bootlogs
393 | find /var/log/boot* | xargs -I{} cp -RH {} $LOC/Dir_bootlogs/
394 | # kernel logs
395 | echo -e "\n[Debug][logs] get kernel log ... to Dir_kernlogs"
396 | mkdir $LOC/Dir_kernlogs
397 | find /var/log/kern* | xargs -I{} cp -RH {} $LOC/Dir_kernlogs/
398 | # auth log
399 | echo -e "\n[Debug][logs] get auth log ... Dir_authlogs"
400 | mkdir $LOC/Dir_authlogs
401 | find /var/log/auth* | xargs -I{} cp -RH {} $LOC/Dir_authlogs/
402 | # security log
403 | echo -e "\n[Debug][logs] get security log ... Dir_securelogs"
404 | mkdir $LOC/Dir_securelogs
405 | find /var/log/secure* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_securelogs/
406 | # mail log
407 | echo -e "\n[Debug][logs] get mail log ... Dir_maillogs"
408 | mkdir $LOC/Dir_maillogs
409 | find /var/log/mail* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_maillogs/
410 |
411 | if [ "$MESSAGEFLAG" = "1" ] ; then
412 | echo -e "\n[Debug][logs] get message log ... Dir_messagelogs"
413 | mkdir $LOC/Dir_messagelogs
414 | find /var/log/ -name message* -o -name syslog* -newermt $STARTDATE -and ! -newermt $ENDDATE | xargs -I{} cp -RH {} $LOC/Dir_messagelogs/ # redhat / centos (message), ubuntu (syslog)
415 | else
416 | echo -e 'MESSAGEFLAG = '$MESSAGEFLAG' -> NOT Enabled'
417 | fi
418 | }
419 |
420 | get_srvconf(){
421 | # make output dir
422 | mkdir $LOC/Dir_srvconf
423 |
424 | # get webserver config: ex *.conf | /conf/ under web document root
425 | # WEB: apache, tomcat,
426 | echo -e "\n[Debug][srvconf] get web server conf ... to Dir_srvconf and srvconfig.txt(list)"
427 | find ${WEBROOT[@]} ${WEBSERVICE[@]} \( -name '*.conf*' -o -name '*.xml' -o -name '*htaccess' -o \( -type d -name 'conf' \) \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ > $LOC/$IRCASE'-srvconfig.txt'
428 |
429 | # get db config
430 | # DATABASE : mysql & maria or postgres or oracle or maria
431 | echo -e "\n[Debug][srvconf] searching mysql db ..."
432 | if type mysql > /dev/null 2>&1; then
433 | echo -e "[Debug][srvconf] mysql db found ... to Dir_srvconf and srvconfig.txt(list)"
434 | for i in `mysql --help | grep '/my.cnf' | tr ' ' '\n' `; do echo -e $i'\n' >> $LOC/$IRCASE'-srvconfig.txt';cp -RH --parents -rp $i $LOC/Dir_srvconf/; done
435 | else
436 | echo -e "[Debug][srvconf] mysql db NOT found"
437 | fi
438 |
439 | echo -e "\n[Debug][srvconf] searching postgres db ... "
440 | if type psql > /dev/null 2>&1; then
441 | echo -e "[Debug][srvconf] postgres db found ... to Dir_srvconf and srvconfig.txt(list)"
442 | find /var/lib/pgsql/ \( -name '*.conf*' -o -name '*.cnf*' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
443 | else
444 | echo -e "[Debug][srvconf] postgres db NOT found"
445 | fi
446 |
447 | echo -e "\n[Debug][srvconf] searching oracle db ... "
448 | if [ -d '/usr/lib/oracle/' ]; then
449 | echo -e "[Debug][srvconf] oracle db found ... to Dir_srvconf and srvconfig.txt(list)"
450 | find /usr/lib/oracle/ \( -name '*.conf*' -o -name '*.cnf*' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
451 | else
452 | echo -e "[Debug][srvconf] oracle db NOT found"
453 | fi
454 |
455 | echo -e "\n[Debug][srvconf] searching maria db ... "
456 | if [ -d '/etc/my.cnf.d/' ]; then
457 | echo -e "[Debug][srvconf] maria db found ... to Dir_srvconf and srvconfig.txt(list)"
458 | find /etc/my.cnf.d/ \( -name '*.conf*' -o -name '*.cnf*' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
459 | else
460 | echo -e "[Debug][srvconf] maria db NOT found"
461 | fi
462 |
463 | #PROXY: squid
464 | echo -e "\n[Debug][srvconf] searching squid proxy ... "
465 | if [ -d '/usr/local/squid/' ] || [ -d "/usr/local/squid3/" ]; then
466 | echo -e "[Debug][srvconf] squid proxy found ... to Dir_srvconf and srvconfig.txt(list)"
467 | find /usr/local/squid* \( -name '*.conf*' -o -name '*.cnf*' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
468 | else
469 | echo -e "[Debug][srvconf] squid proxy NOT found"
470 | fi
471 |
472 | #FTP: vsftpd
473 | echo -e "\n[Debug][srvconf] searching vsftpd ... "
474 | if [ -d '/etc/vsftpd/' ]; then
475 | echo -e "[Debug][srvconf] vsftpd found ... "
476 | find /etc/vsftpd/ \( -name '*.conf*' -o -name '*.cnf*' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
477 | else
478 | echo -e "[Debug][srvconf] vsftpd NOT found"
479 | fi
480 |
481 | #Mail:
482 | echo -e "\n[Debug][srvconf] searching mail ... "
483 | if [ -f '/usr/share/misc/mail.rc' ] || [ -f ' /usr/local/etc/mail.rc' ] || [ -f '/etc/mail.rc' ] ; then
484 | echo -e "[Debug][srvconf] mailserver config found ... "
485 | find /etc/ /usr/share/misc/ /usr/local/etc/ -name mail* -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvconf/ >> $LOC/$IRCASE'-srvconfig.txt'
486 | else
487 | echo -e "[Debug][srvconf] mailserver config NOT found"
488 | fi
489 |
490 | }
491 |
492 | get_srvcontents(){
493 | # make output dir
494 | mkdir $LOC/Dir_srvcontents
495 |
496 | echo -e "\n[Debug][srvcontents] get server contents "${WEBROOT[@]}"... to srvcontents.txt"
497 | find ${WEBROOT[@]} \( -name '*.php' -o -name '*.js' -o -name '*.py' -o -name '*.rb' -o -name '*.go' -o -name '*.war' -o -name '*.pl' -o -name '*.cgi' \) -ls | xargs -I{} cp -RH --parents -rp {} $LOC/Dir_srvcontents/ > $LOC/$IRCASE'-srvcontents.txt'
498 |
499 | echo -e "\n[Debug][srvcontents] get suspicous executable ...( /tmp "${WEBROOT[@]}") to susbin.txt"
500 | find ${WEBROOT[@]} -type f -exec file {} \; | egrep -qw "(ELF|executable|PE32|shared object|script)" | xargs -i echo {}; cp -RH --parents -rp {} $LOC/Dir_srvcontents/ >> $LOC/$IRCASE'-susbin.txt'
501 | find /tmp -type f -exec file {} \; | egrep -qw "(ELF|executable|PE32|shared object|script)" | xargs -i echo {};cp -RH --parents -rp {} $LOC/Dir_srvcontents/ >> $LOC/$IRCASE'-susbin.txt'
502 |
503 | }
504 |
505 |
506 | scan_virus(){
507 | #pwd
508 | # backdoor scan
509 | echo -e "\n[Debug][virus] scan php backdoor ... to phpbackdoor.txt"
510 | if [ ! -r $PHPBACKDOOR ]; then
511 | echo -e '\n file not exist : options/backdoorscan.php'
512 | elif type php > /dev/null 2>&1; then
513 | for item in ${WEBROOT[@]}; do
514 | php $PHPBACKDOOR $item >> $LOC/$IRCASE'-phpbackdoor.txt'
515 | done
516 | else
517 | echo -e '\n php does not installed. '
518 | fi
519 |
520 | #clam av install and scan ref: https://www.clamav.net/documents/installing-clamav#requirements
521 | # https://www.clamav.net/documents/upgrading-clamav
522 | echo -e "\n[Debug][virus] try to install and scan clam av ..."
523 | if [ "$CLAMAVFLAG" = "1" ] ; then
524 | echo -e "\n[Debug][virus] install and scan clam av ... to clamscan.txt"
525 | tar -xzvf ./options/clamav-0.99.2.tar.gz
526 | cd ./options/clamav-0.99.2
527 | ./configure with-user `whoami` with-group `whoami`
528 | make
529 | cd ../../
530 |
531 | # signiture
532 | gpg --verify ./options/clamav-0.99.2.tar.gz.sig
533 |
534 | # [UPDATE] (if you connect to internet)
535 | # freshclam
536 |
537 | # virus scan
538 | clamscan -r -i / --exclude=".*\.core|.*\.snap"$ > $LOC/$IRCASE'-clamscan.txt'
539 |
540 | #[remind] uninstall clamav
541 | else
542 | echo -e 'CLAMAVFLAG = '$CLAMAVFLAG' -> NOT Enabled'
543 | fi
544 |
545 | #rkhunter install and scan ref: http://rkhunter.sourceforge.net
546 | echo -e "\n[Debug][virus] try to install and scan rkhunter ..."
547 | if [ "$RKHUNRERFLAG" = "1" ] ; then
548 | echo -e "\n[Debug][virus] install and scan rkhunter ... to rkhunter.txt"
549 | tar -zxvf ./options/rkhunter-1.4.4.tar.gz; cd rkhunter-1.4.4
550 | ./install.sh --install
551 |
552 | # [UPDATE] (if you connect to internet)
553 | #rkhunter --update
554 | #rkhunter --propupd
555 |
556 | # rootkit scan
557 | rkhunter --check --skip-keypress --report-warnings-only > $LOC/$IRCASE'-rkhunter.txt'
558 | # white list: https://qiita.com/Peranikov/items/3f14476d0767d4589bcb
559 | #[remind] uninstall rkhunter
560 | else
561 | echo -e 'RKHUNTERFLAG = '$RKHUNTERFLAG' -> NOT Enabled'
562 | fi
563 |
564 | }
565 |
566 | get_hash(){
567 | echo -e "\n[Debug][hash] try to get SHA256 hash value for bin ..."
568 | if [ "$HASHFLAG" = "1" ] ; then
569 | echo -e "\n[Debug][hash] get SHA256 hash value for bin ... to binhashlist.txt"
570 | cat $LOC/$IRCASE'-ls.txt' | rev | cut -d" " -f1 | rev | grep -e '/bin/' -e '/sbin/' | xargs -i sha256sum {} > $LOC/$IRCASE'-binhashlist.txt'
571 | else
572 | echo -e 'HASHFLAG = '$HASHFLAG' -> NOT Enabled'
573 | fi
574 | }
575 |
576 | additional_backup(){
577 | echo -e "\n[Debug][backup] try to additional backup ... to Dir_backup, backup.txt(list)"
578 | mkdir $LOC/Dir_backup
579 | mkdir $LOC/Dir_backup/CONFIG
580 | find / -type f \( -name *.conf -o -name *.cnf \) -ls | xargs -I{} cp -RH --parent -rp {} $LOC/Dir_backup/CONFIG >> $LOC/$IRCASE'-backup.txt'
581 | find / -type d \( -name *conf* -o -name *config* \) -ls | xargs -I{} cp -RH --parent -rp {} $LOC/Dir_backup/CONFIG >> $LOC/$IRCASE'-backup.txt'
582 | echo 'cp -RH --parents -rp /var/spool $LOC/Dir_backup/' >> $LOC/$IRCASE'-backup.txt'
583 | cp -RH --parents -rp /var/spool $LOC/Dir_backup/
584 | echo 'cp -RH --parents -rp /etc/cron* $LOC/Dir_backup/' >> $LOC/$IRCASE'-backup.txt'
585 | cp -RH --parents -rp /etc/cron* $LOC/Dir_backup/
586 | for item in ${WEBROOT[@]}; do
587 | echo 'cp -RH --parents -rp '$item' $LOC/Dir_backup/' >> $LOC/$IRCASE'-backup.txt'
588 | cp -RH --parents -rp $item $LOC/Dir_backup/ >> $LOC/$IRCASE'-backup.txt'
589 | done
590 | echo -e "\n[Debug][backup] backup func FIN ..."
591 | }
592 |
593 |
594 | ###################### MAIN ##########################
595 | {
596 | check_tmpstorage 2>&1
597 | excludes_paths 2>&1
598 | prepare 2>&1
599 | }
600 |
601 | # start timestamp
602 | date '+%Y-%m-%d %H:%M:%S %Z %:z' > $LOC/$IRCASE'-date.txt'
603 |
604 | ### Detect WEBROOT and WEBSERVICE
605 | echo -e "\n[Debug] Detect ( WEBROOT and WEBSERVICE ) PATH ... STATIC CONF << ( "${WEBROOT[@]}" and "${WEBSERVICE[@]}" )."
606 |
607 | {
608 | echo "############## DEBUG & ERROR LOGS START ####################"
609 |
610 | echo -e "\n[Debug][httpd] Searching WebROOT and WEBSERVICE."
611 | WEBCONF_HTTPD=`httpd -V | grep "SERVER_CONFIG_FILE" | cut -d"=" -f2 | xargs`
612 | if [ ${#WEBCONF_HTTPD} -gt 1 ]; then
613 | echo -e "[Debug] httpd FOUND (installed)"
614 | HTTPD=`httpd -V | grep "HTTPD_ROOT" | cut -d"=" -f2 | xargs`
615 | if [ ${WEBCONF_HTTPD:zero:1} != "/" ]; then
616 | WEBCONF_HTTPD=$HTTPD/$WEBCONF_HTTPD
617 | fi
618 | WEBSERVICE+=( $HTTPD )
619 | WEBROOT+=( `grep -v "#" $WEBCONF_HTTPD | grep DocumentRoot | cut -d" " -f2 | xargs` )
620 | WEBROOT+=( `grep -v "#" $WEBCONF_HTTPD | grep -i include | grep conf | cut -d" " -f2 | xargs cat | grep DocumentRoot | cut -d" " -f2 | xargs` )
621 | HTTPD_WILDCONF=`grep -v "#" $WEBCONF_HTTPD | grep -i include | grep conf |grep "\*" | cut -d" " -f2 | xargs`
622 | if [ ${#HTTPD_WILDCONF} -gt 1 ]; then
623 | WEBROOT+=( `grep -v "#" $HTTPD_WILDCONF | grep DocumentRoot | cut -d" " -f2 | xargs` )
624 | fi
625 | fi
626 |
627 | echo -e "\n[Debug][apache2] Searching WebROOT and WEBSERVICE."
628 | WEBCONF_APACHE2=`apache2ctl -V | grep "SERVER_CONFIG_FILE" | cut -d"=" -f2 | xargs`
629 | if [ ${#WEBCONF_APACHE2} -gt 1 ]; then
630 | echo -e "[Debug] apache2 FOUND (installed)"
631 | APACHE2=`apache2ctl -V | grep "HTTPD_ROOT" | cut -d"=" -f2 | xargs`
632 | if [ ${WEBCONF_APACHE2:zero:1} != "/" ]; then
633 | WEBCONF_APACHE2=$APACHE2/$WEBCONF_APACHE2
634 | fi
635 | WEBSERVICE+=( $APACHE2 )
636 | WEBROOT+=( `grep -v "#" $WEBCONF_APACHE2 | grep "Options Indexes" -B1 | grep Directory | sed -e "s/^.*.*$/\1/" | xargs` )
637 | APACHE2_INCLUDE=`grep -v "#" $WEBCONF_APACHE2 | grep -i include | grep conf | cut -d" " -f2 | xargs`
638 | if [ ${#APACHE2_INCLUDE} -gt 1 ]; then
639 | WEBROOT+=( `cat $APACHE2_INCLUDE | grep -v "#" | grep "Options Indexes" -B1 | grep Directory | sed -e "s/^.*.*$/\1/" | xargs`)
640 | fi
641 | fi
642 |
643 | echo -e "\n[Debug][nginx] Searching WebROOT and WEBSERVICE."
644 | WEBCONF_NGINX=`nginx -V 2>&1 1>/dev/null | grep "configure arguments" | sed -e "s/^.*--conf-path=\(.*\)conf.*$/\1/" | xargs`'conf'
645 | if [ ${#WEBCONF_NGINX} -gt 1 ]; then
646 | echo -e "[Debug] nginx FOUND (installed)"
647 | WEBROOT+=( `grep -v "#" $WEBCONF_NGINX | grep root | sed -e "s/^.*root\(.*\);.*$/\1/" | grep "/" | xargs` )
648 | WEBROOT+=( `grep -v "#" $WEBCONF_NGINX | grep -i include | grep conf | sed -e "s/^.*include\(.*\);.*$/\1/" | grep "/" | xargs cat | grep -v "#" | grep root | sed -e "s/^.*root\(.*\);.*$/\1/" | xargs` )
649 | NGINX_WILDCONF=`grep -v "#" $WEBCONF_NGINX | grep -i include | grep conf | sed -e "s/^.*include\(.*\);.*$/\1/" | grep "\*" | cut -d" " -f2`
650 | if [ ${#NGINX_WILDCONF} -gt 1 ]; then
651 | WEBROOT+=( `grep -v "#" $NGINX_WILDCONF | grep root | sed -e "s/^.*root\(.*\);.*$/\1/" | grep "/" | xargs` )
652 | fi
653 | fi
654 |
655 | echo -e "\nRESULT WEBROOTs: ["${WEBROOT[@]}"]"
656 | echo -e "RESULT WEBSERVICEs: ["${WEBSERVICE[@]}"]"
657 | } >> $ERROR_LOG
658 |
659 |
660 | echo -e "\nRESULT WEBROOTs: ["${WEBROOT[@]}"]"
661 | echo -e "RESULT WEBSERVICEs: ["${WEBSERVICE[@]}"]"
662 |
663 | echo -e "\n[Debug] Collect triage data ..."
664 | {
665 | get_userprofile 2>&1
666 | get_systeminfo 2>&1
667 | get_activity 2>&1
668 | get_fileinfo 2>&1
669 | get_servicereg 2>&1
670 | get_logs 2>&1
671 | get_srvconf 2>&1
672 | get_srvcontents 2>&1
673 | scan_virus 2>&1
674 | get_hash 2>&1
675 | echo -e "\n############## DEBUG & ERROR LOGS END ####################"
676 | } >> $ERROR_LOG
677 |
678 |
679 | if [ "$BACKUPFLAG" = "1" ] ; then
680 | echo -e "\n[Debug] Back Up collection ..."
681 | {
682 | additional_backup 2>&1
683 | } >> $ERROR_LOG
684 | else
685 | echo -e 'BACKUPFLAG = '$BACKUPFLAG' -> NOT Enabled'
686 | fi
687 |
688 | # tree of outputs
689 | {
690 | echo -e "\n[Debug] make OUTPUT-TREE ..."
691 | if tree &> /dev/null; then
692 | tree -alh $LOC > $LOC/1_OUTPUT-TREE.txt
693 | else
694 | find $LOC | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/| /g' > $LOC/1_OUTPUT-TREE.txt
695 | fi
696 | }
697 |
698 | echo -e "\n[Debug] Compress to tar.gz ..."
699 | CUR_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
700 | cd $LOC
701 | tar -zcvf "/tmp/"$IRCASE".tar.gz" * > /dev/null
702 | cd $CUR_DIR
703 |
704 | echo -e "\n[Debug] move tar.gz to here ..."
705 | if [ "$SaveCWD" = "1" ] ; then
706 | mv "/tmp/"$IRCASE".tar.gz" $CUR_DIR
707 | fi
708 |
709 | # end timestamp
710 | date '+%Y-%m-%d %H:%M:%S %Z %:z' >> $LOC/$IRCASE'-date.txt'
711 |
712 | echo -e "\n[Debug] del /tmp file ..."
713 | cd /tmp
714 | rm -r $LOC
715 |
716 | echo -e "\n[Debug] triage script END "
717 |
--------------------------------------------------------------------------------