├── 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 | --------------------------------------------------------------------------------