├── README.md └── linux_mem_diff.py /README.md: -------------------------------------------------------------------------------- 1 | # linux_mem_diff_tool 2 | Script to perform Linux Memory Diff Analysis Using Volatility 3 | 4 | 5 | Details of configuring and running the script can be found here: 6 | 7 | http://malware-unplugged.blogspot.in/2015/09/linux-memory-diff-analysis-using.html 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /linux_mem_diff.py: -------------------------------------------------------------------------------- 1 | #################################################################################### 2 | #### script name: linux_mem_diff.py #### 3 | #### Description: Script to perform Linux Memory Diff Analysis Using Volatility #### 4 | #### Author: Monnappa #### 5 | #################################################################################### 6 | 7 | import subprocess 8 | import optparse 9 | import sys 10 | import os 11 | 12 | # set the below variables with appropriate values, this is mandatory 13 | python_path = r'' # path to python interpreter, example: r'/usr/bin/python' 14 | vol_path = r'' # path to Volatility script(vol.py), example: r'/root/Volatility/vol.py' 15 | 16 | # set the below variables, this is optional, these values can be given while running the script 17 | clean_mem_image = "" 18 | infected_mem_image = "" 19 | mem_image_profile = "" 20 | out_report_file = "" 21 | 22 | 23 | class MemDiff: 24 | def __init__(self, python_path, vol_path, clean_mem_file, infected_mem_file, profile): 25 | self.clean_mem_file = clean_mem_file 26 | self.infected_mem_file = infected_mem_file 27 | self.profile = profile 28 | self.volatility = vol_path 29 | self.python = python_path 30 | self.ldrmodules_clean = "" 31 | self.ldrmoudles_infected = "" 32 | self.proc_info_clean = {} 33 | self.proc_info_infected = {} 34 | self.proc_path_clean = {} 35 | self.proc_path_infected = {} 36 | self.proc_lib_clean = {} 37 | self.proc_lib_infected = {} 38 | self.ldrmodules_header = "" 39 | self.ldrmodules_header1 = "" 40 | self.update_proc_info_clean() 41 | self.update_proc_info_infected() 42 | self.update_proc_path_lib_clean() 43 | self.update_proc_path_lib_infected() 44 | 45 | 46 | def run_cmd(self, mem_file, cmd, args=[]): 47 | pargs = [self.python, self.volatility, self.profile, '-f', mem_file, cmd] 48 | if len(args): 49 | pargs.extend(args) 50 | proc = subprocess.Popen(pargs, stdout=subprocess.PIPE) 51 | return proc.communicate()[0] 52 | 53 | def ldrmodules(self, mem_file): 54 | return self.run_cmd(mem_file, 'linux_ldrmodules') 55 | 56 | def update_proc_info_clean(self): 57 | self.ldrmodules_clean = self.ldrmodules(self.clean_mem_file) 58 | ldrmodules_clean = self.ldrmodules_clean.splitlines() 59 | self.ldrmodules_header = ldrmodules_clean[0] 60 | self.ldrmodules_header1 = ldrmodules_clean[1] 61 | ldrmodules_clean = ldrmodules_clean[2:] 62 | for line in ldrmodules_clean: 63 | pid, proc_name, start, proc_path, kernel, libc = line.split() 64 | if proc_name in self.proc_info_clean: 65 | self.proc_info_clean[proc_name].append([pid, proc_name, proc_path,line]) 66 | else: 67 | self.proc_info_clean[proc_name] = [] 68 | self.proc_info_clean[proc_name].append([pid, proc_name, proc_path,line]) 69 | 70 | def update_proc_info_infected(self): 71 | self.ldrmodules_infected = self.ldrmodules(self.infected_mem_file) 72 | ldrmodules_infected = self.ldrmodules_infected.splitlines() 73 | ldrmodules_infected = ldrmodules_infected[2:] 74 | for line in ldrmodules_infected: 75 | pid, proc_name, start, proc_path, kernel, libc = line.split() 76 | if proc_name in self.proc_info_infected: 77 | self.proc_info_infected[proc_name].append([pid, proc_name, proc_path,line]) 78 | else: 79 | self.proc_info_infected[proc_name] = [] 80 | self.proc_info_infected[proc_name].append([pid, proc_name, proc_path,line]) 81 | 82 | def update_proc_path_lib_clean(self): 83 | for each_proc in self.proc_info_clean: 84 | proc_path = [] 85 | proc_lib = [] 86 | each_proc_info = self.proc_info_clean[each_proc] 87 | for each_info in each_proc_info: 88 | path = each_info[2] 89 | if ".so" in path: 90 | proc_lib.append(path) 91 | else: 92 | proc_path.append(path) 93 | 94 | if each_proc in self.proc_path_clean: 95 | self.proc_path_clean[each_proc].extend(list(set(proc_path))) 96 | else: 97 | self.proc_path_clean[each_proc] = [] 98 | self.proc_path_clean[each_proc].extend(list(set(proc_path))) 99 | 100 | if each_proc in self.proc_lib_clean: 101 | self.proc_lib_clean[each_proc].extend(list(set(proc_lib))) 102 | else: 103 | self.proc_lib_clean[each_proc] = [] 104 | self.proc_lib_clean[each_proc].extend(list(set(proc_lib))) 105 | 106 | def update_proc_path_lib_infected(self): 107 | for each_proc in self.proc_info_infected: 108 | proc_path = [] 109 | proc_lib = [] 110 | each_proc_info = self.proc_info_infected[each_proc] 111 | for each_info in each_proc_info: 112 | path = each_info[2] 113 | if ".so" in path: 114 | proc_lib.append(path) 115 | else: 116 | proc_path.append(path) 117 | 118 | if each_proc in self.proc_path_infected: 119 | self.proc_path_infected[each_proc].extend(list(set(proc_path))) 120 | else: 121 | self.proc_path_infected[each_proc] = [] 122 | self.proc_path_infected[each_proc].extend(list(set(proc_path))) 123 | 124 | if each_proc in self.proc_lib_infected: 125 | self.proc_lib_infected[each_proc].extend(list(set(proc_lib))) 126 | else: 127 | self.proc_lib_infected[each_proc] = [] 128 | self.proc_lib_infected[each_proc].extend(list(set(proc_lib))) 129 | 130 | 131 | 132 | def pslist(self, mem_file): 133 | return self.run_cmd(mem_file, 'linux_pslist') 134 | 135 | def psxview(self, mem_file): 136 | return self.run_cmd(mem_file, 'linux_psxview') 137 | 138 | def pidhashtable(self, mem_file): 139 | return self.run_cmd(mem_file,'linux_pidhashtable') 140 | 141 | def netstat(self, mem_file): 142 | args = ["-U"] 143 | return self.run_cmd(mem_file, 'linux_netstat', args) 144 | 145 | def ifconfig(self, mem_file): 146 | return self.run_cmd(mem_file, 'linux_ifconfig') 147 | 148 | def list_raw(self, mem_file): 149 | return self.run_cmd(mem_file,'linux_list_raw') 150 | 151 | def library_list(self, mem_file): 152 | return self.run_cmd(mem_file,'linux_library_list') 153 | 154 | def dmesg(self, mem_file): 155 | return self.run_cmd(mem_file,'linux_dmesg') 156 | 157 | def lsmod(self, mem_file): 158 | return self.run_cmd(mem_file,'linux_lsmod') 159 | 160 | def check_modules(self, mem_file): 161 | return self.run_cmd(mem_file,'linux_check_modules') 162 | 163 | def hidden_modules(self, mem_file): 164 | return self.run_cmd(mem_file,'linux_hidden_modules') 165 | 166 | def kernel_opened_files(self, mem_file): 167 | return self.run_cmd(mem_file,'linux_kernel_opened_files') 168 | 169 | def check_creds(self, mem_file): 170 | return self.run_cmd(mem_file,'linux_check_creds') 171 | 172 | def keyboard_notifiers(self, mem_file): 173 | return self.run_cmd(mem_file,'linux_keyboard_notifiers') 174 | 175 | def check_tty(self, mem_file): 176 | return self.run_cmd(mem_file,'linux_check_tty') 177 | 178 | def check_syscall(self, mem_file): 179 | return self.run_cmd(mem_file,'linux_check_syscall') 180 | 181 | def bash_history(self, mem_file): 182 | return self.run_cmd(mem_file,'linux_bash') 183 | 184 | def check_fop(self, mem_file): 185 | return self.run_cmd(mem_file,'linux_check_fop') 186 | 187 | def check_afinfo(self, mem_file): 188 | return self.run_cmd(mem_file,'linux_check_afinfo') 189 | 190 | def netfilter(self, mem_file): 191 | return self.run_cmd(mem_file,'linux_netfilter') 192 | 193 | def check_inline_kernel(self, mem_file): 194 | return self.run_cmd(mem_file,'linux_check_inline_kernel') 195 | 196 | def malfind(self, mem_file): 197 | return self.run_cmd(mem_file,'linux_malfind') 198 | 199 | def plthook(self, mem_file): 200 | return self.run_cmd(mem_file,'linux_plthook') 201 | 202 | def apihooks(self, mem_file): 203 | return self.run_cmd(mem_file,'linux_apihooks') 204 | 205 | def diff_pslist(self): 206 | diff_list = [] 207 | pslist_clean = self.pslist(self.clean_mem_file) 208 | pslist_infected = self.pslist(self.infected_mem_file) 209 | pslist_clean = pslist_clean.splitlines() 210 | header = pslist_clean[0] 211 | clean_pslist = {} 212 | for line in pslist_clean: 213 | splitted = line.split() 214 | proc_name = splitted[1] 215 | pid = splitted[2] 216 | clean_pslist[proc_name] = line 217 | pslist_infected = pslist_infected.splitlines() 218 | infected_pslist = {} 219 | for line in pslist_infected: 220 | splitted = line.split() 221 | proc_name = splitted[1] 222 | pid = splitted[2] 223 | infected_pslist[proc_name] = line 224 | diff_list.append(header) 225 | for each in infected_pslist: 226 | if each not in clean_pslist: 227 | if infected_pslist[each]: 228 | diff_list.append(infected_pslist[each]) 229 | else: 230 | if each in self.proc_path_clean and each in self.proc_path_infected: 231 | proc_paths_infected = self.proc_path_infected[each] 232 | proc_paths_clean = self.proc_path_clean[each] 233 | for each_path in proc_paths_infected: 234 | if each_path not in proc_paths_clean: 235 | diff_list.append(infected_pslist[each]) 236 | return diff_list 237 | 238 | def diff_psxview(self): 239 | diff_list = [] 240 | psxview_clean = self.psxview(self.clean_mem_file) 241 | psxview_infected = self.psxview(self.infected_mem_file) 242 | psxview_clean = psxview_clean.splitlines() 243 | header = psxview_clean[0] 244 | clean_psxview = {} 245 | for line in psxview_clean: 246 | splitted = line.split() 247 | proc_name = splitted[1] 248 | pid = splitted[2] 249 | clean_psxview[proc_name] = line 250 | psxview_infected = psxview_infected.splitlines() 251 | infected_psxview = {} 252 | for line in psxview_infected: 253 | splitted = line.split() 254 | proc_name = splitted[1] 255 | pid = splitted[2] 256 | infected_psxview[proc_name] = line 257 | diff_list.append(header) 258 | for each in infected_psxview: 259 | if each not in clean_psxview: 260 | if infected_psxview[each]: 261 | diff_list.append(infected_psxview[each]) 262 | else: 263 | if each in self.proc_path_clean and each in self.proc_path_infected: 264 | proc_paths_infected = self.proc_path_infected[each] 265 | proc_paths_clean = self.proc_path_clean[each] 266 | for each_path in proc_paths_infected: 267 | if each_path not in proc_paths_clean: 268 | diff_list.append(infected_psxview[each]) 269 | return diff_list 270 | 271 | def diff_pidhashtable(self): 272 | diff_list = [] 273 | pidhashtable_clean = self.pidhashtable(self.clean_mem_file) 274 | pidhashtable_infected = self.pidhashtable(self.infected_mem_file) 275 | pidhashtable_clean = pidhashtable_clean.splitlines() 276 | header = pidhashtable_clean[0] 277 | clean_pidhashtable = {} 278 | for line in pidhashtable_clean: 279 | splitted = line.split() 280 | proc_name = splitted[1] 281 | pid = splitted[2] 282 | clean_pidhashtable[proc_name] = line 283 | pidhashtable_infected = pidhashtable_infected.splitlines() 284 | infected_pidhashtable = {} 285 | for line in pidhashtable_infected: 286 | splitted = line.split() 287 | proc_name = splitted[1] 288 | pid = splitted[2] 289 | infected_pidhashtable[proc_name] = line 290 | diff_list.append(header) 291 | for each in infected_pidhashtable: 292 | if each not in clean_pidhashtable: 293 | if infected_pidhashtable[each]: 294 | diff_list.append(infected_pidhashtable[each]) 295 | else: 296 | if each in self.proc_path_clean and each in self.proc_path_infected : 297 | proc_paths_infected = self.proc_path_infected[each] 298 | proc_paths_clean = self.proc_path_clean[each] 299 | for each_path in proc_paths_infected: 300 | if each_path not in proc_paths_clean: 301 | diff_list.append(infected_pidhashtable[each]) 302 | return diff_list 303 | 304 | def diff_netstat(self): 305 | diff_list = [] 306 | add_entry = True 307 | netstat_clean = self.netstat(self.clean_mem_file) 308 | netstat_infected = self.netstat(self.infected_mem_file) 309 | netstat_clean = netstat_clean.splitlines() 310 | netstat_infected = netstat_infected.splitlines() 311 | for each in netstat_infected: 312 | inf_entry,inf_pid = each.split("/") 313 | for each_line in netstat_clean: 314 | if inf_entry in each_line: 315 | add_entry = False 316 | break 317 | else: 318 | continue 319 | if add_entry: 320 | diff_list.append(each) 321 | else: 322 | add_entry = True 323 | 324 | return diff_list 325 | 326 | def diff_ifconfig(self): 327 | diff_list = [] 328 | ifconfig_clean = self.ifconfig(self.clean_mem_file) 329 | ifconfig_infected = self.ifconfig(self.infected_mem_file) 330 | ifconfig_clean = ifconfig_clean.splitlines() 331 | ifconfig_infected = ifconfig_infected.splitlines() 332 | header = ifconfig_clean[0] 333 | diff_list.append(header) 334 | for each in ifconfig_infected: 335 | if each not in ifconfig_clean: 336 | diff_list.append(each) 337 | return diff_list 338 | 339 | def diff_list_raw(self): 340 | diff_list = [] 341 | list_raw_clean = self.list_raw(self.clean_mem_file) 342 | list_raw_infected = self.list_raw(self.infected_mem_file) 343 | list_raw_clean = list_raw_clean.splitlines() 344 | list_raw_infected = list_raw_infected.splitlines() 345 | header = list_raw_clean[0] 346 | diff_list.append(header) 347 | for each in list_raw_infected: 348 | if each not in list_raw_clean: 349 | diff_list.append(each) 350 | return diff_list 351 | 352 | def diff_library_list(self): 353 | diff_list = [] 354 | library_list_clean = self.library_list(self.clean_mem_file) 355 | library_list_infected = self.library_list(self.infected_mem_file) 356 | library_list_clean = library_list_clean.splitlines() 357 | library_list_infected = library_list_infected.splitlines() 358 | header = library_list_clean[0] 359 | diff_list.append(header) 360 | header1 = library_list_clean[1] 361 | diff_list.append(header1) 362 | clean_proc_line = {} 363 | clean_proc_lib_list = {} 364 | library_list_clean = library_list_clean[2:] 365 | for line in library_list_clean: 366 | splitted = line.split() 367 | proc_name = splitted[0] 368 | lib_name = splitted[3] 369 | if proc_name in clean_proc_line: 370 | clean_proc_line[proc_name].append(line) 371 | else: 372 | clean_proc_line[proc_name] = [] 373 | clean_proc_line[proc_name].append(line) 374 | 375 | if proc_name in clean_proc_lib_list: 376 | clean_proc_lib_list[proc_name].append(lib_name) 377 | else: 378 | clean_proc_lib_list[proc_name] = [] 379 | clean_proc_lib_list[proc_name].append(lib_name) 380 | 381 | infected_proc_line= {} 382 | infected_proc_lib_list = {} 383 | library_list_infected = library_list_infected[2:] 384 | for line in library_list_infected: 385 | splitted = line.split() 386 | proc_name = splitted[0] 387 | lib_name = splitted[3] 388 | if proc_name in infected_proc_line: 389 | infected_proc_line[proc_name].append(line) 390 | else: 391 | infected_proc_line[proc_name] = [] 392 | infected_proc_line[proc_name].append(line) 393 | if proc_name in infected_proc_lib_list: 394 | infected_proc_lib_list[proc_name].append(lib_name) 395 | else: 396 | infected_proc_lib_list[proc_name] = [] 397 | infected_proc_lib_list[proc_name].append(lib_name) 398 | 399 | for each in infected_proc_lib_list: 400 | if each not in clean_proc_lib_list: 401 | diff_list.extend(infected_proc_line[each]) 402 | else: 403 | clean_libs = clean_proc_lib_list[each] 404 | infected_libs = infected_proc_lib_list[each] 405 | for each_lib in infected_libs: 406 | if each_lib not in clean_libs: 407 | infected_lines = infected_proc_line[each] 408 | for each_line in infected_lines: 409 | if each_lib in each_line: 410 | diff_list.append(each_line) 411 | return diff_list 412 | 413 | 414 | def diff_ldrmodules(self): 415 | diff_list = [] 416 | diff_list.append(self.ldrmodules_header) 417 | diff_list.append(self.ldrmodules_header1) 418 | for proc in self.proc_info_infected: 419 | add_module = True 420 | if proc not in self.proc_info_clean: 421 | info_list = self.proc_info_infected[proc] 422 | for info in info_list: 423 | line = info[3] 424 | diff_list.append(line) 425 | else: 426 | clean_info_list = self.proc_info_clean[proc] 427 | infected_info_list = self.proc_info_infected[proc] 428 | for inf_info in infected_info_list: 429 | inf_mod_path = inf_info[2] 430 | inf_line = inf_info[3] 431 | for cln_info in clean_info_list: 432 | cln_mod_path = cln_info[2] 433 | if inf_mod_path in cln_mod_path: 434 | add_module = False 435 | break 436 | else: 437 | continue 438 | if add_module: 439 | diff_list.append(inf_line) 440 | else: 441 | add_module=True 442 | 443 | return diff_list 444 | 445 | def diff_dmesg(self): 446 | diff_list = [] 447 | dmesg_clean = self.dmesg(self.clean_mem_file) 448 | dmesg_infected = self.dmesg(self.infected_mem_file) 449 | dmesg_clean = dmesg_clean.splitlines() 450 | dmesg_infected = dmesg_infected.splitlines() 451 | for each in dmesg_infected: 452 | if each not in dmesg_clean: 453 | diff_list.append(each) 454 | return diff_list 455 | 456 | def diff_lsmod(self): 457 | diff_list = [] 458 | lsmod_clean = self.lsmod(self.clean_mem_file) 459 | lsmod_infected = self.lsmod(self.infected_mem_file) 460 | lsmod_clean = lsmod_clean.splitlines() 461 | clean_lsmod = {} 462 | for line in lsmod_clean: 463 | splitted = line.split() 464 | module = splitted[1] 465 | clean_lsmod[module] = line 466 | lsmod_infected = lsmod_infected.splitlines() 467 | infected_lsmod = {} 468 | for line in lsmod_infected: 469 | splitted = line.split() 470 | module = splitted[1] 471 | infected_lsmod[module] = line 472 | for each in infected_lsmod: 473 | if each not in clean_lsmod: 474 | diff_list.append(infected_lsmod[each]) 475 | return diff_list 476 | 477 | def diff_check_modules(self): 478 | diff_list = [] 479 | check_modules_clean = self.check_modules(self.clean_mem_file) 480 | check_modules_infected = self.check_modules(self.infected_mem_file) 481 | check_modules_clean = check_modules_clean.splitlines() 482 | header = check_modules_clean[0] 483 | clean_check_modules = {} 484 | for line in check_modules_clean: 485 | splitted = line.split() 486 | module = splitted[1] 487 | clean_check_modules[module] = line 488 | check_modules_infected = check_modules_infected.splitlines() 489 | infected_check_modules = {} 490 | for line in check_modules_infected: 491 | splitted = line.split() 492 | module = splitted[1] 493 | infected_check_modules[module] = line 494 | diff_list.append(header) 495 | for each in infected_check_modules: 496 | if each not in clean_check_modules: 497 | if infected_check_modules[each]: 498 | diff_list.append(infected_check_modules[each]) 499 | return diff_list 500 | 501 | def diff_hidden_modules(self): 502 | diff_list = [] 503 | hidden_modules_clean = self.hidden_modules(self.clean_mem_file) 504 | hidden_modules_infected = self.hidden_modules(self.infected_mem_file) 505 | hidden_modules_clean = hidden_modules_clean.splitlines() 506 | header = hidden_modules_clean[0] 507 | clean_hidden_modules = {} 508 | for line in hidden_modules_clean: 509 | splitted = line.split() 510 | module = splitted[1] 511 | clean_hidden_modules[module] = line 512 | hidden_modules_infected = hidden_modules_infected.splitlines() 513 | infected_hidden_modules = {} 514 | for line in hidden_modules_infected: 515 | splitted = line.split() 516 | module = splitted[1] 517 | infected_hidden_modules[module] = line 518 | diff_list.append(header) 519 | for each in infected_hidden_modules: 520 | if each not in clean_hidden_modules: 521 | if infected_hidden_modules[each]: 522 | diff_list.append(infected_hidden_modules[each]) 523 | return diff_list 524 | 525 | def diff_kernel_opened_files(self): 526 | diff_list = [] 527 | kernel_opened_files_clean = self.kernel_opened_files(self.clean_mem_file) 528 | kernel_opened_files_infected = self.kernel_opened_files(self.infected_mem_file) 529 | kernel_opened_files_clean = kernel_opened_files_clean.splitlines() 530 | header = kernel_opened_files_clean[0] 531 | clean_kernel_opened_files = {} 532 | for line in kernel_opened_files_clean: 533 | splitted = line.split() 534 | file_path = splitted[1] 535 | clean_kernel_opened_files[file_path] = line 536 | kernel_opened_files_infected = kernel_opened_files_infected.splitlines() 537 | infected_kernel_opened_files = {} 538 | for line in kernel_opened_files_infected: 539 | splitted = line.split() 540 | file_path = splitted[1] 541 | infected_kernel_opened_files[file_path] = line 542 | diff_list.append(header) 543 | for each in infected_kernel_opened_files: 544 | if each not in clean_kernel_opened_files: 545 | if infected_kernel_opened_files[each]: 546 | diff_list.append(infected_kernel_opened_files[each]) 547 | return diff_list 548 | 549 | def diff_check_creds(self): 550 | diff_list = [] 551 | check_creds_clean = self.check_creds(self.clean_mem_file) 552 | check_creds_infected = self.check_creds(self.infected_mem_file) 553 | check_creds_clean = check_creds_clean.splitlines() 554 | check_creds_infected = check_creds_infected.splitlines() 555 | header = check_creds_clean[0] 556 | diff_list.append(header) 557 | for each in check_creds_infected: 558 | if each not in check_creds_clean: 559 | diff_list.append(each) 560 | return diff_list 561 | 562 | def diff_keyboard_notifiers(self): 563 | diff_list = [] 564 | keyboard_notifiers_clean = self.keyboard_notifiers(self.clean_mem_file) 565 | keyboard_notifiers_infected = self.keyboard_notifiers(self.infected_mem_file) 566 | keyboard_notifiers_clean = keyboard_notifiers_clean.splitlines() 567 | keyboard_notifiers_infected = keyboard_notifiers_infected.splitlines() 568 | header = keyboard_notifiers_clean[0] 569 | diff_list.append(header) 570 | for each in keyboard_notifiers_infected: 571 | if each not in keyboard_notifiers_clean: 572 | diff_list.append(each) 573 | return diff_list 574 | 575 | def diff_check_tty(self): 576 | diff_list = [] 577 | check_tty_clean = self.check_tty(self.clean_mem_file) 578 | check_tty_infected = self.check_tty(self.clean_mem_file) 579 | check_tty_clean = check_tty_clean.splitlines() 580 | check_tty_infected = check_tty_infected.splitlines() 581 | header = check_tty_clean[0] 582 | diff_list.append(header) 583 | for each in check_tty_infected: 584 | if each not in check_tty_clean: 585 | diff_list.append(each) 586 | return diff_list 587 | 588 | def diff_check_syscall(self): 589 | diff_list = [] 590 | check_syscall_clean = self.check_syscall(self.clean_mem_file) 591 | check_syscall_infected = self.check_syscall(self.infected_mem_file) 592 | check_syscall_clean = check_syscall_clean.splitlines() 593 | check_syscall_infected = check_syscall_infected.splitlines() 594 | header = check_syscall_clean[0] 595 | header1 = check_syscall_clean[1] 596 | diff_list.append(header) 597 | diff_list.append(header1) 598 | for each in check_syscall_infected: 599 | if each not in check_syscall_clean: 600 | diff_list.append(each) 601 | return diff_list 602 | 603 | def diff_bash_history(self): 604 | diff_list = [] 605 | bash_history_clean = self.bash_history(self.clean_mem_file) 606 | bash_history_infected = self.bash_history(self.infected_mem_file) 607 | bash_history_clean = bash_history_clean.splitlines() 608 | bash_history_infected = bash_history_infected.splitlines() 609 | header = bash_history_clean[0] 610 | header1 = bash_history_clean[1] 611 | diff_list.append(header) 612 | diff_list.append(header1) 613 | for each in bash_history_infected: 614 | if each not in bash_history_clean: 615 | diff_list.append(each) 616 | return diff_list 617 | 618 | 619 | def diff_check_afinfo(self): 620 | diff_list = [] 621 | check_afinfo_clean = self.check_afinfo(self.clean_mem_file) 622 | check_afinfo_infected = self.check_afinfo(self.infected_mem_file) 623 | check_afinfo_clean = check_afinfo_clean.splitlines() 624 | check_afinfo_infected = check_afinfo_infected.splitlines() 625 | header = check_afinfo_clean[0] 626 | header1 = check_afinfo_clean[1] 627 | diff_list.append(header) 628 | diff_list.append(header1) 629 | for each in check_afinfo_infected: 630 | if each not in check_afinfo_clean: 631 | diff_list.append(each) 632 | return diff_list 633 | 634 | def diff_check_fop(self): 635 | diff_list = [] 636 | check_fop_clean = self.check_fop(self.clean_mem_file) 637 | check_fop_infected = self.check_fop(self.infected_mem_file) 638 | check_fop_clean = check_fop_clean.splitlines() 639 | check_fop_infected = check_fop_infected.splitlines() 640 | header = check_fop_clean[0] 641 | header1 = check_fop_clean[1] 642 | diff_list.append(header) 643 | diff_list.append(header1) 644 | for each in check_fop_infected: 645 | if each not in check_fop_clean: 646 | diff_list.append(each) 647 | return diff_list 648 | 649 | def diff_netfilter(self): 650 | diff_list = [] 651 | netfilter_clean = self.netfilter(self.clean_mem_file) 652 | netfilter_infected = self.netfilter(self.infected_mem_file) 653 | netfilter_clean = netfilter_clean.splitlines() 654 | netfilter_infected = netfilter_infected.splitlines() 655 | header = netfilter_clean[0] 656 | header1 = netfilter_clean[1] 657 | diff_list.append(header) 658 | diff_list.append(header1) 659 | for each in netfilter_infected: 660 | if each not in netfilter_clean: 661 | diff_list.append(each) 662 | return diff_list 663 | 664 | def diff_check_inline_kernel(self): 665 | diff_list = [] 666 | check_inline_kernel_clean = self.check_inline_kernel(self.clean_mem_file) 667 | check_inline_kernel_infected = self.check_inline_kernel(self.infected_mem_file) 668 | check_inline_kernel_clean = check_inline_kernel_clean.splitlines() 669 | check_inline_kernel_infected = check_inline_kernel_infected.splitlines() 670 | header = check_inline_kernel_clean[0] 671 | header1 = check_inline_kernel_clean[1] 672 | diff_list.append(header) 673 | diff_list.append(header1) 674 | for each in check_inline_kernel_infected: 675 | if each not in check_inline_kernel_clean: 676 | diff_list.append(each) 677 | return diff_list 678 | 679 | def diff_plthook(self): 680 | diff_list = [] 681 | plthook_clean = self.plthook(self.clean_mem_file) 682 | plthook_infected = self.plthook(self.infected_mem_file) 683 | plthook_clean = plthook_clean.splitlines() 684 | plthook_infected = plthook_infected.splitlines() 685 | header = plthook_clean[0] 686 | header1 = plthook_clean[1] 687 | diff_list.append(header) 688 | diff_list.append(header1) 689 | for each in plthook_infected: 690 | if each not in plthook_clean: 691 | diff_list.append(each) 692 | return diff_list 693 | 694 | def diff_apihooks(self): 695 | diff_list = [] 696 | apihooks_clean = self.apihooks(self.clean_mem_file) 697 | apihooks_infected = self.apihooks(self.infected_mem_file) 698 | apihooks_clean = apihooks_clean.splitlines() 699 | apihooks_infected = apihooks_infected.splitlines() 700 | header = apihooks_clean[0] 701 | header1 = apihooks_clean[1] 702 | diff_list.append(header) 703 | diff_list.append(header1) 704 | for each in apihooks_infected: 705 | if each not in apihooks_clean: 706 | diff_list.append(each) 707 | return diff_list 708 | 709 | 710 | if __name__ == "__main__": 711 | 712 | parser = optparse.OptionParser('Usage: %prog -c -i -p [options]') 713 | parser.add_option("-c", "--cleanimage", dest="clean_mem_image",help="path to clean memory image") 714 | parser.add_option("-i", "--infectedimage", dest="infected_mem_image",help="path to infected memory image") 715 | parser.add_option("-p", "--profile", dest="mem_image_profile",help="profile for the memory images") 716 | parser.add_option("-o", "--output", dest="output_filename", help="path to the output filename", default="final_report.txt") 717 | parser.add_option("-v", "--verbose", action="store_true", dest="is_verbose", help="perfoms verbose diff analysis (slow)", default=False) 718 | 719 | (options, args) = parser.parse_args() 720 | 721 | clean_mem_image = options.clean_mem_image 722 | infected_mem_image = options.infected_mem_image 723 | mem_image_profile = options.mem_image_profile 724 | out_report_file = options.output_filename 725 | is_verbose = options.is_verbose 726 | 727 | if not python_path: 728 | print("Please update the variable 'python_path' with path to the python interpreter") 729 | sys.exit() 730 | 731 | if not vol_path: 732 | print("Please update the variable 'vol_path' with path to the Volatility (vol.py)") 733 | sys.exit() 734 | 735 | if not clean_mem_image: 736 | print("Please specify path to the clean memory image, type -h or --help for more information") 737 | sys.exit() 738 | if not infected_mem_image: 739 | print("Please specify path to the infected memory image, type -h or --help for more information") 740 | sys.exit() 741 | if not mem_image_profile: 742 | print("Please specify profile to use for the memory images, type -h or --help for more information") 743 | sys.exit() 744 | 745 | mem_image_profile = "--profile=" + mem_image_profile 746 | 747 | print "Starting Diff Analysis using Volatility" 748 | print "Please Wait: Getting Process Related Information, this may take a while" 749 | 750 | vol = MemDiff(python_path, vol_path, clean_mem_image, infected_mem_image, mem_image_profile) 751 | 752 | f = open(out_report_file, 'w') 753 | 754 | f.write("=======================[MEMORY DIFF ANALYSIS RESULTS]=======================\n\n") 755 | 756 | diff_pslist = vol.diff_pslist() 757 | diff_pslist = "\n".join(diff_pslist) 758 | print "DIFF_PSLIST" 759 | print "==========================================" 760 | print diff_pslist 761 | print "\n" 762 | f.write("DIFF_PSLIST\n") 763 | f.write("=======================================\n") 764 | f.write(diff_pslist) 765 | f.write("\n") 766 | f.write("\n") 767 | 768 | diff_psxview = vol.diff_psxview() 769 | diff_psxview = "\n".join(diff_psxview) 770 | print "DIFF_PSXVIEW" 771 | print "==========================================" 772 | print diff_psxview 773 | print "\n" 774 | f.write("DIFF_PSXVIEW\n") 775 | f.write("=======================================\n") 776 | f.write(diff_psxview) 777 | f.write("\n") 778 | f.write("\n") 779 | 780 | diff_pidhashtable = vol.diff_pidhashtable() 781 | diff_pidhashtable = "\n".join(diff_pidhashtable) 782 | print "DIFF_PIDHASHTABLE" 783 | print "==========================================" 784 | print diff_pidhashtable 785 | print "\n" 786 | f.write("DIFF_PIDHASHTABLE\n") 787 | f.write("=======================================\n") 788 | f.write(diff_pidhashtable) 789 | f.write("\n") 790 | f.write("\n") 791 | 792 | diff_netstat = vol.diff_netstat() 793 | diff_netstat = "\n".join(diff_netstat) 794 | print "DIFF_NETSTAT" 795 | print "==========================================" 796 | print diff_netstat 797 | print "\n" 798 | f.write("DIFF_NETSTAT\n") 799 | f.write("=======================================\n") 800 | f.write(diff_netstat) 801 | f.write("\n") 802 | f.write("\n") 803 | 804 | diff_ifconfig = vol.diff_ifconfig() 805 | diff_ifconfig = "\n".join(diff_ifconfig) 806 | print "DIFF_IFCONFIG" 807 | print "==========================================" 808 | print diff_ifconfig 809 | print "\n" 810 | f.write("DIFF_IFCONFIG\n") 811 | f.write("=======================================\n") 812 | f.write(diff_ifconfig) 813 | f.write("\n") 814 | f.write("\n") 815 | 816 | diff_raw_socks = vol.diff_list_raw() 817 | diff_raw_socks = "\n".join(diff_raw_socks) 818 | print "DIFF_RAW_SOCKETS" 819 | print "==========================================" 820 | print diff_raw_socks 821 | print "\n" 822 | f.write("DIFF_RAW_SOCKETS\n") 823 | f.write("=======================================\n") 824 | f.write(diff_raw_socks) 825 | f.write("\n") 826 | f.write("\n") 827 | 828 | diff_library_list = vol.diff_library_list() 829 | diff_library_list = "\n".join(diff_library_list) 830 | print "DIFF_LIBRARY_LIST" 831 | print "==========================================" 832 | print diff_library_list 833 | print "\n" 834 | f.write("DIFF_LIBRARY_LIST\n") 835 | f.write("=======================================\n") 836 | f.write(diff_library_list) 837 | f.write("\n") 838 | f.write("\n") 839 | 840 | diff_ldrmodules = vol.diff_ldrmodules() 841 | diff_ldrmodules = "\n".join(diff_ldrmodules) 842 | print "DIFF_LDRMODULES" 843 | print "==========================================" 844 | print diff_ldrmodules 845 | print "\n" 846 | f.write("DIFF_LDRMODULES\n") 847 | f.write("=======================================\n") 848 | f.write(diff_ldrmodules) 849 | f.write("\n") 850 | f.write("\n") 851 | 852 | diff_dmesg = vol.diff_dmesg() 853 | diff_dmesg = "\n".join(diff_dmesg) 854 | print "DIFF_DMESG" 855 | print "==========================================" 856 | print diff_dmesg 857 | print "\n" 858 | f.write("DIFF_DMESG\n") 859 | f.write("=======================================\n") 860 | f.write(diff_dmesg) 861 | f.write("\n") 862 | f.write("\n") 863 | 864 | diff_lsmod = vol.diff_lsmod() 865 | diff_lsmod = "\n".join(diff_lsmod) 866 | print "DIFF_LSMOD" 867 | print "==========================================" 868 | print diff_lsmod 869 | print "\n" 870 | f.write("DIFF_LSMOD\n") 871 | f.write("=======================================\n") 872 | f.write(diff_lsmod) 873 | f.write("\n") 874 | f.write("\n") 875 | 876 | diff_check_modules = vol.diff_check_modules() 877 | diff_check_modules = "\n".join(diff_check_modules) 878 | print "DIFF_CHECK_MODULES" 879 | print "==========================================" 880 | print diff_check_modules 881 | print "\n" 882 | f.write("DIFF_CHECK_MODULES\n") 883 | f.write("=======================================\n") 884 | f.write(diff_check_modules) 885 | f.write("\n") 886 | f.write("\n") 887 | 888 | diff_hidden_modules = vol.diff_hidden_modules() 889 | diff_hidden_modules = "\n".join(diff_hidden_modules) 890 | print "DIFF_HIDDEN_MODULES" 891 | print "==========================================" 892 | print diff_hidden_modules 893 | print "\n" 894 | f.write("DIFF_HIDDEN_MODULES\n") 895 | f.write("=======================================\n") 896 | f.write(diff_hidden_modules) 897 | f.write("\n") 898 | f.write("\n") 899 | 900 | diff_kernel_opened_files = vol.diff_kernel_opened_files() 901 | diff_kernel_opened_files = "\n".join(diff_kernel_opened_files) 902 | print "DIFF_KERNEL_OPENED_FILES" 903 | print "==========================================" 904 | print diff_kernel_opened_files 905 | print "\n" 906 | f.write("DIFF_KERNEL_OPENED_FILES\n") 907 | f.write("=======================================\n") 908 | f.write(diff_kernel_opened_files) 909 | f.write("\n") 910 | f.write("\n") 911 | 912 | diff_check_creds = vol.diff_check_creds() 913 | diff_check_creds = "\n".join(diff_check_creds) 914 | print "DIFF_CHECK_CREDS" 915 | print "==========================================" 916 | print diff_check_creds 917 | print "\n" 918 | f.write("DIFF_CHECK_CREDS\n") 919 | f.write("=======================================\n") 920 | f.write(diff_check_creds) 921 | f.write("\n") 922 | f.write("\n") 923 | 924 | diff_keyboard_notifiers = vol.diff_keyboard_notifiers() 925 | diff_keyboard_notifiers = "\n".join(diff_keyboard_notifiers) 926 | print "DIFF_KEYBOARD_NOTIFIERS" 927 | print "==========================================" 928 | print diff_keyboard_notifiers 929 | print "\n" 930 | f.write("DIFF_KEYBOARD_NOTIFIERS\n") 931 | f.write("=======================================\n") 932 | f.write(diff_keyboard_notifiers) 933 | f.write("\n") 934 | f.write("\n") 935 | 936 | diff_check_tty = vol.diff_check_tty() 937 | diff_check_tty = "\n".join(diff_check_tty) 938 | print "DIFF_CHECK_TTY" 939 | print "==========================================" 940 | print diff_check_tty 941 | print "\n" 942 | f.write("DIFF_CHECK_TTY\n") 943 | f.write("=======================================\n") 944 | f.write(diff_check_tty) 945 | f.write("\n") 946 | f.write("\n") 947 | 948 | diff_check_syscall = vol.diff_check_syscall() 949 | diff_check_syscall = "\n".join(diff_check_syscall) 950 | print "DIFF_CHECK_SYSCALL" 951 | print "==========================================" 952 | print diff_check_syscall 953 | print "\n" 954 | f.write("DIFF_CHECK_SYSCALL\n") 955 | f.write("=======================================\n") 956 | f.write(diff_check_syscall) 957 | f.write("\n") 958 | f.write("\n") 959 | 960 | diff_bash_history = vol.diff_bash_history() 961 | diff_bash_history = "\n".join(diff_bash_history) 962 | print "DIFF_BASH_HISTORY" 963 | print "==========================================" 964 | print diff_bash_history 965 | print "\n" 966 | f.write("DIFF_BASH_HISTORY\n") 967 | f.write("=======================================\n") 968 | f.write(diff_bash_history) 969 | f.write("\n") 970 | f.write("\n") 971 | 972 | 973 | diff_check_afinfo = vol.diff_check_afinfo() 974 | diff_check_afinfo = "\n".join(diff_check_afinfo) 975 | print "DIFF_CHECK_AFINFO" 976 | print "==========================================" 977 | print diff_check_afinfo 978 | print "\n" 979 | f.write("DIFF_CHECK_AFINFO\n") 980 | f.write("=======================================\n") 981 | f.write(diff_check_afinfo) 982 | f.write("\n") 983 | f.write("\n") 984 | 985 | diff_netfilter = vol.diff_netfilter() 986 | diff_netfilter = "\n".join(diff_netfilter) 987 | print "DIFF_NETFILTER" 988 | print "==========================================" 989 | print diff_netfilter 990 | print "\n" 991 | f.write("DIFF_NETFILTER\n") 992 | f.write("=======================================\n") 993 | f.write(diff_netfilter) 994 | f.write("\n") 995 | f.write("\n") 996 | 997 | diff_check_inline_kernel = vol.diff_check_inline_kernel() 998 | diff_check_inline_kernel = "\n".join(diff_check_inline_kernel) 999 | print "DIFF_CHECK_INLINE_KERNEL" 1000 | print "==========================================" 1001 | print diff_check_inline_kernel 1002 | print "\n" 1003 | f.write("DIFF_CHECK_INLINE_KERNEL\n") 1004 | f.write("=======================================\n") 1005 | f.write(diff_check_inline_kernel) 1006 | f.write("\n") 1007 | f.write("\n") 1008 | 1009 | diff_check_fop = vol.diff_check_fop() 1010 | diff_check_fop = "\n".join(diff_check_fop) 1011 | print "DIFF_CHECK_FOP" 1012 | print "==========================================" 1013 | print diff_check_fop 1014 | print "\n" 1015 | f.write("DIFF_CHECK_FOP\n") 1016 | f.write("=======================================\n") 1017 | f.write(diff_check_fop) 1018 | f.write("\n") 1019 | f.write("\n") 1020 | 1021 | if is_verbose: 1022 | diff_plthook = vol.diff_plthook() 1023 | diff_plthook = "\n".join(diff_plthook) 1024 | print "DIFF_PLTHOOK" 1025 | print "==========================================" 1026 | print diff_plthook 1027 | print "\n" 1028 | f.write("DIFF_PLTHOOK\n") 1029 | f.write("=======================================\n") 1030 | f.write(diff_plthook) 1031 | f.write("\n") 1032 | f.write("\n") 1033 | 1034 | diff_apihooks = vol.diff_apihooks() 1035 | diff_apihooks = "\n".join(diff_apihooks) 1036 | print "DIFF_APIHOOKS" 1037 | print "==========================================" 1038 | print diff_apihooks 1039 | print "\n" 1040 | f.write("DIFF_APIHOOKS\n") 1041 | f.write("=======================================\n") 1042 | f.write(diff_apihooks) 1043 | f.write("\n") 1044 | f.write("\n") 1045 | 1046 | f.close() 1047 | print "Final report is stored in %s" % out_report_file 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | --------------------------------------------------------------------------------