This file is indexed.

/usr/lib/python2.7/dist-packages/volatility/plugins/linux/check_evt_arm.py is in volatility 2.4-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# Volatility
#
# This file is part of Volatility.
#
# Volatility is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Volatility is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Volatility.  If not, see <http://www.gnu.org/licenses/>.
#

"""
@author:       Joe Sylve
@license:      GNU General Public License 2.0
@contact:      joe.sylve@gmail.com
@organization: 504ENSICS Labs
"""

import volatility.obj as obj
import volatility.debug as debug
import volatility.plugins.linux.common as linux_common

class linux_check_evt_arm(linux_common.AbstractLinuxARMCommand):
    ''' Checks the Exception Vector Table to look for syscall table hooking '''

    VECTOR_BASE = 0xffff0000
    SWI_BASE = VECTOR_BASE + 8
        
    def calculate(self):
        linux_common.set_plugin_members(self)
        # Get instructions executed when an inturrupt exception occurs
        swi = obj.Object("unsigned int", offset = self.SWI_BASE, vm = self.addr_space)
        
        # Get offset of address to vector_swi
        offset = (swi & 0x0fff) + 8
        
        # Verify that instruction hasn't been modified (should be: ldr pc, [pc, #???] (e59ff???))
        if (swi & 0xfffff000) == 0xe59ff000:
            yield ("SWI Offset Instruction", "PASS", "Offset: {0}".format(offset))
        else:
            yield ("SWI Offset Instruction", "FAIL", "{0:X}".format(swi))
            return
        
        # Get vector_swi_addr from table
        vector_swi_addr = obj.Object("unsigned int", offset = self.SWI_BASE + (offset), vm = self.addr_space)
        
        # Check to see if vector_swi handler has been hooked
        if vector_swi_addr == self.addr_space.profile.get_symbol("vector_swi"):
            yield ("vector_swi address", "PASS", "0x{0:X}".format(vector_swi_addr))
        else:
            yield ("vector_swi address", "FAIL", "0x{0:X}".format(vector_swi_addr))
            return
            
        # Check for hooking of sys_call table pointer
        sc_opcode = None;
        max_opcodes_to_check = 1024
        while (max_opcodes_to_check):
            opcode = obj.Object("unsigned int", offset=  vector_swi_addr, vm = self.addr_space)
            if ((opcode & 0xffffff00) == 0xe28f8000):
                sc_opcode = opcode
                break
            vector_swi_addr += 4
            max_opcodes_to_check -= 1
            
        if sc_opcode:
            yield ("vector_swi code modification", "PASS", "{0:X}".format(sc_opcode))
        else:
            yield ("vector_swi code modification", "FAIL", "Opcode E28F80?? not found")
            return
          
    def render_text(self, outfd, data):
        self.table_header(outfd, [("Check", "<30"), ("PASS/FAIL", "<5"), ("Info", "<30")])
        for (check, result, info) in data:
            self.table_row(outfd, check, result, info)