Skip to content

Format code with autopep8 #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions documented plugins/ifconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
import volatility.obj as obj
from volatility.renderers import TreeGrid


class linux_ifconfig(linux_common.AbstractLinuxCommand):
"""Gathers active interfaces"""

def _get_devs_base(self):
net_device_ptr = obj.Object("Pointer", offset = self.addr_space.profile.get_symbol("dev_base"), vm = self.addr_space)
net_device_ptr = obj.Object("Pointer", offset=self.addr_space.profile.get_symbol(
"dev_base"), vm=self.addr_space)
net_device = net_device_ptr.dereference_as("net_device")

for net_dev in linux_common.walk_internal_list("net_device", "next", net_device):
Expand All @@ -43,7 +45,8 @@ def _get_devs_namespace(self):

# Get network namespace list and define list_head
nslist_addr = self.addr_space.profile.get_symbol("net_namespace_list")
nethead = obj.Object("list_head", offset = nslist_addr, vm = self.addr_space)
nethead = obj.Object(
"list_head", offset=nslist_addr, vm=self.addr_space)

# walk each network namespace
# http://www.linuxquestions.org/questions/linux-kernel-70/accessing-ip-address-from-kernel-ver-2-6-31-13-module-815578/
Expand All @@ -54,43 +57,45 @@ def _get_devs_namespace(self):
yield net_dev

def _gather_net_dev_info(self, net_dev):

# mac_addr and promisc(ous mode) are properties of net_dev symbol (At least thats what written here)
mac_addr = net_dev.mac_addr
promisc = str(net_dev.promisc)
promisc = str(net_dev.promisc)

# ip_ptr is a pointer to an in_device object which holds data about the devices list and IP layer
in_dev = obj.Object(
"in_device", offset=net_dev.ip_ptr, vm=self.addr_space)

# ip_ptr is a pointer to an in_device object which holds data about the devices list and IP layer
in_dev = obj.Object("in_device", offset = net_dev.ip_ptr, vm = self.addr_space)

# Walk each device inside interfaces
# list
for dev in in_dev.devices():
ip_addr = dev.ifa_address.cast('IpAddress') # Get interface IP adress
name = dev.ifa_label # Get interface name
ip_addr = dev.ifa_address.cast(
'IpAddress') # Get interface IP adress
name = dev.ifa_label # Get interface name
yield (name, ip_addr, mac_addr, promisc)

def calculate(self):
linux_common.set_plugin_members(self)

# newer kernels
if self.addr_space.profile.get_symbol("net_namespace_list"):
func = self._get_devs_namespace # Use _get_devs_namespace function
func = self._get_devs_namespace # Use _get_devs_namespace function

elif self.addr_space.profile.get_symbol("dev_base"):
func = self._get_devs_base # Use _get_devs_base function
func = self._get_devs_base # Use _get_devs_base function

else:
debug.error("Unable to determine ifconfig information")

for net_dev in func():
for (name, ip_addr, mac_addr, promisc) in self._gather_net_dev_info(net_dev):
yield (name, ip_addr, mac_addr, promisc)
yield (name, ip_addr, mac_addr, promisc)

def unified_output(self, data):
return TreeGrid([("Interface", str),
("IP", str),
("MAC", str),
("Promiscuous", str)],
("IP", str),
("MAC", str),
("Promiscuous", str)],
self.generator(data))

def generator(self, data):
Expand Down
88 changes: 49 additions & 39 deletions documented plugins/mount.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import volatility.plugins.linux.common as linux_common
import volatility.plugins.linux.pslist as linux_pslist


class linux_mount(linux_common.AbstractLinuxCommand):
"""Gather mounted fs/devices"""

Expand All @@ -40,7 +41,8 @@ def _parse_mnt(self, mnt, ns, fs_types):
return ret

# get mount name
dev_name = mnt.mnt_devname.dereference_as("String", length = linux_common.MAX_STRING_LENGTH)
dev_name = mnt.mnt_devname.dereference_as(
"String", length=linux_common.MAX_STRING_LENGTH)
# name validation
if not dev_name.is_valid():
return ret
Expand All @@ -55,41 +57,45 @@ def _parse_mnt(self, mnt, ns, fs_types):
# I consider this code as obfuscated
n = ord(nn)
# non-printable character or '?' character
if n < 32 or n > 126 or n == 63: # 63 = ?
if n < 32 or n > 126 or n == 63: # 63 = ?
new_name = True
break

# the first rule of programming is: DO NOT COMPARE BOOLEANS TO TRUE!!!
if new_name == True:
# basically what this does is that if the name was invalid, try extracting the name from a field that is 16 bytes further into the struct.
# I have absolutely no idea what this field is supposed to be
s = obj.Object("Pointer", offset = mnt.mnt_devname.obj_offset + 16, vm = self.addr_space)
s = obj.Object(
"Pointer", offset=mnt.mnt_devname.obj_offset + 16, vm=self.addr_space)
if not s.is_valid():
return ret

dev_name = s.dereference_as("String", length = linux_common.MAX_STRING_LENGTH)
dev_name = s.dereference_as(
"String", length=linux_common.MAX_STRING_LENGTH)
if not dev_name.is_valid() or len(dev_name) < 3:
return ret

for nn in str(dev_name)[:3]:
n = ord(nn)
if n < 32 or n > 126 or n == 63: # 63 = ?
if n < 32 or n > 126 or n == 63: # 63 = ?
return ret

# get the mount's superblock's filesystem type's name (that was a mouthful)
fstype = mnt.mnt_sb.s_type.name.dereference_as("String", length = linux_common.MAX_STRING_LENGTH)
fstype = mnt.mnt_sb.s_type.name.dereference_as(
"String", length=linux_common.MAX_STRING_LENGTH)

# bad filesystem type name
if not fstype.is_valid() or len(fstype) < 3:
return ret

for nn in str(fstype)[:3]:
n = ord(nn)
if n < 32 or n > 126 or n == 63: # 63 = ?
if n < 32 or n > 126 or n == 63: # 63 = ?
return ret

# get the full vfs path
path = linux_common.do_get_path(mnt.mnt_sb.s_root, mnt.mnt_parent, mnt.mnt_root, mnt)
path = linux_common.do_get_path(
mnt.mnt_sb.s_root, mnt.mnt_parent, mnt.mnt_root, mnt)
# bad path
if path == [] or len(path) > 4096:
return ret
Expand All @@ -103,7 +109,7 @@ def _parse_mnt(self, mnt, ns, fs_types):
rr = "ro"
else:
rr = "rw"

# return superblock, mount name, mount path, filesystem type name, access type, mount attributes
return mnt.mnt_sb, str(dev_name), path, fstype, rr, mnt_string

Expand All @@ -120,9 +126,11 @@ def calculate(self):
"""
linux_common.set_plugin_members(self)
# get pointer to mount_hashtable
mntptr = obj.Object("Pointer", offset = self.addr_space.profile.get_symbol("mount_hashtable"), vm = self.addr_space)
mntptr = obj.Object("Pointer", offset=self.addr_space.profile.get_symbol(
"mount_hashtable"), vm=self.addr_space)
# convert mount_hashtable to list_head array
mnt_list = obj.Object(theType = "Array", offset = mntptr, vm = self.addr_space, targetType = "list_head", count = 8200)
mnt_list = obj.Object(theType="Array", offset=mntptr,
vm=self.addr_space, targetType="list_head", count=8200)

# older kernel versions have 'vfsmount' instead of 'mount'
if self.profile.has_type("mount"):
Expand All @@ -135,7 +143,7 @@ def calculate(self):
# get filesystem types
fs_types = self._get_filesystem_types()

hash_mnts = {} # dictionary of mount object as key (WTF??)
hash_mnts = {} # dictionary of mount object as key (WTF??)
seen_outer = {}
# iterate through mount_hashtable arrray
for (idx, outerlist) in enumerate(mnt_list):
Expand Down Expand Up @@ -176,22 +184,22 @@ def calculate(self):
if not mkey in mseen:
hash_mnts[mnt] = 1
# mark as seen (AGAIN?!)
mseen[mkey] = 1
mseen[mkey] = 1
else:
break
# TL;DR if parent exists add it to list
if mnt.mnt_parent.is_valid():
mkey = mnt.mnt_parent.v()
if not mkey in mseen:
if not mkey in mseen:
hash_mnts[mnt.mnt_parent] = 1
mseen[mkey] = 1

# TL;DR if parent's parent exists add it to list
# (what about parent's parent's parent :O )
# seriously this code is ridiculous
if mnt.mnt_parent.mnt_parent.is_valid():
if mnt.mnt_parent.mnt_parent.is_valid():
mkey = mnt.mnt_parent.mnt_parent.v()
if not mkey in mseen:
if not mkey in mseen:
hash_mnts[mnt.mnt_parent.mnt_parent] = 1
mseen[mkey] = 1

Expand All @@ -201,14 +209,14 @@ def calculate(self):
cseen = {}
# walk linked list of children mounts
for child_mnt in mnt.mnt_child.list_of_type(mnttype, "mnt_child"):

# invalid child
if not child_mnt.is_valid():
break

# add child to list (why TF is this a dict)
child_mnts[child_mnt] = 1
child_mnts[child_mnt] = 1

# we've seen this node
if child_mnt.v() in cseen:
break
Expand All @@ -219,11 +227,11 @@ def calculate(self):

# mark node as seen
cseen[child_mnt.v()] = 1

# add parent to child list (WHY???)
if child_mnt.mnt_parent.is_valid():
child_mnts[child_mnt.mnt_parent] = 1

# you guessed it - parent's parent ;)
if child_mnt.mnt_parent.mnt_parent.is_valid():
child_mnts[child_mnt.mnt_parent.mnt_parent] = 1
Expand All @@ -236,23 +244,24 @@ def calculate(self):
# iterate through seen mounts
for t in tmp_mnts:
# mount name (great variable naming, as usual)
tt = t.mnt_devname.dereference_as("String", length = linux_common.MAX_STRING_LENGTH)
tt = t.mnt_devname.dereference_as(
"String", length=linux_common.MAX_STRING_LENGTH)
# name validation
if tt:
if len(str(tt)) > 2 or (len(str(tt)) > 1 and str(tt)[0] == '/'):
# add to list of valid mounts
all_mnts.append(t)

list_mnts = {}
seen_m = {}
list_mnts = {}
seen_m = {}
# iterate through valid mounts
for mnt in all_mnts:
# we've seen this mount
if mnt.v() in seen_m:
continue
else:
# mark this mount as seen
seen_m[mnt.v()] = 1
seen_m[mnt.v()] = 1

# walk mnt_list linked list of mounts
for (idx, child_mnt) in enumerate(mnt.mnt_list.list_of_type(mnttype, "mnt_list")):
Expand All @@ -262,12 +271,12 @@ def calculate(self):

# add to yet another list of mounts
if child_mnt.is_valid():
list_mnts[child_mnt] = 1
list_mnts[child_mnt] = 1

# add parent to list
if child_mnt.mnt_parent.is_valid():
list_mnts[child_mnt.mnt_parent] = 1

# you know what it is
if child_mnt.mnt_parent.mnt_parent.is_valid():
list_mnts[child_mnt.mnt_parent.mnt_parent] = 1
Expand All @@ -283,9 +292,9 @@ def calculate(self):
if mnt.mnt_sb.v() not in seen:
# get all kinds of info about this mount
ret = self._parse_mnt(mnt, ns, fs_types)

mark = False

# unpack the info
if ret:
(mnt_sb, dev_name, path, fstype, rr, mnt_string) = ret
Expand All @@ -312,17 +321,19 @@ def _calc_mnt_string(self, mnt):

def _get_filesystem_types(self):
all_fs = {}

# get linked list of filesystem types from symbol 'file_systems'
fs_ptr = obj.Object("Pointer", offset = self.addr_space.profile.get_symbol("file_systems"), vm = self.addr_space)
fs_ptr = obj.Object("Pointer", offset=self.addr_space.profile.get_symbol(
"file_systems"), vm=self.addr_space)
file_systems = fs_ptr.dereference_as("file_system_type")

fs = file_systems

# walk the linked list of filesystem types
while fs.is_valid():
# get the fs type name
fsname = obj.Object("String", offset = fs.name, vm = self.addr_space, length=256)
fsname = obj.Object("String", offset=fs.name,
vm=self.addr_space, length=256)
# add the fs type to a dict
all_fs[str(fsname)] = fs
fs = fs.next
Expand All @@ -331,6 +342,5 @@ def _get_filesystem_types(self):

def render_text(self, outfd, data):
for (_sb, dev_name, path, fstype, rr, mnt_string) in data:
outfd.write("{0:25s} {1:35s} {2:12s} {3:2s}{4:64s}\n".format(dev_name, path, fstype, rr, mnt_string))


outfd.write("{0:25s} {1:35s} {2:12s} {3:2s}{4:64s}\n".format(
dev_name, path, fstype, rr, mnt_string))
Loading