Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
Added use-cases presented at EuskalHack 2018
Browse files Browse the repository at this point in the history
  • Loading branch information
xabiugarte committed Jun 25, 2018
1 parent 654d8ee commit e490f7f
Show file tree
Hide file tree
Showing 12 changed files with 1,844 additions and 0 deletions.
Empty file added exploit_detect/__init__.py
Empty file.
180 changes: 180 additions & 0 deletions exploit_detect/mem_info.py
@@ -0,0 +1,180 @@
# -------------------------------------------------------------------------------
#
# Copyright (C) 2018 Cisco Talos Security Intelligence and Research Group
#
# PyREBox: Python scriptable Reverse Engineering Sandbox
# Author: Xabier Ugarte-Pedrero
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# -------------------------------------------------------------------------------

# Just a class to hold VAD region attributes
# and an __str__ function implementation
class VADRegion(object):
def __init__(self, obj_offset,
parent_obj_offset,
start,
end,
file_name,
tag,
type,
private,
protection):

self.obj_offset = obj_offset
self.parent_obj_offset = parent_obj_offset
self.start = start
self.end = end
self.file_name = file_name
self.tag = tag
self.type = type
self.private = private
self.protection = protection
self.is_parent = False

def __str__(self):
return "[%s] [%016x - %016x] [%s][%s][%s] - %s" % (self.tag,
self.start,
self.end,
self.type,
"P" if self.private else " ",
self.protection + " " * max(0, 22 - len(self.protection)),
self.file_name)
def get_stacks(pgd):
'''
Get list of VAD regions using volatility
'''
import volatility.obj as obj
import volatility.win32.tasks as tasks
import volatility.plugins.vadinfo as vadinfo
from utils import get_addr_space

stack_list = []

# Get volatility address space using the function in utils
addr_space = get_addr_space(pgd)

# Get list of Task objects using volatility (EPROCESS executive objects)
eprocs = [t for t in tasks.pslist(
addr_space) if t.Pcb.DirectoryTableBase.v() == pgd]

# Traverse the list of selected EPROCESSes
for task in eprocs:
# Get Stack base for every THREAD

for thread in task.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"):
teb = obj.Object("_TEB",
offset=thread.Tcb.Teb,
vm=task.get_process_address_space())
if teb:
stack_list.append((teb.NtTib.StackBase.v(), teb.NtTib.StackLimit.v()))

return stack_list

def get_vads(pgd):
'''
Get list of VAD regions using volatility
'''
import volatility.obj as obj
import volatility.win32.tasks as tasks
import volatility.plugins.vadinfo as vadinfo
from utils import get_addr_space

vad_list = []
vad_parents = []
stacks = []

# Get volatility address space using the function in utils
addr_space = get_addr_space(pgd)

# Get list of Task objects using volatility (EPROCESS executive objects)
eprocs = [t for t in tasks.pslist(
addr_space) if t.Pcb.DirectoryTableBase.v() == pgd]

# Traverse the list of selected EPROCESSes
for task in eprocs:
# Get heap base for every process HEAP
heaps = task.Peb.ProcessHeaps.dereference()

# Get base for every DLL
modules = [mod.DllBase for mod in task.get_load_modules()]

# Get Stack base for every THREAD

for thread in task.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"):
teb = obj.Object("_TEB",
offset=thread.Tcb.Teb,
vm=task.get_process_address_space())
if teb:
stacks.append((teb.NtTib.StackBase.v(), teb.NtTib.StackLimit.v()))

# Traverse VAD tree
for vad in task.VadRoot.traverse():
if vad is not None:
# Determine if the VAD is a HEAP, STACK, or MODULE
vad_type = ""
if vad.Start in heaps:
# Heaps
vad_type = "H"
elif vad.Start in modules:
# Module
vad_type = "M"
elif any([s[1] >= vad.Start and s[1] <= vad.End for s in stacks]):
# Stacks
vad_type = "S"
else:
vad_type = "-"

# Get protection flags
try:
protection = vadinfo.PROTECT_FLAGS.get(
vad.VadFlags.Protection.v(), "")
except Exception:
traceback.print_exc()

# Get mapped file
file_name = ""
try:
control_area = vad.ControlArea
# even if the ControlArea is not NULL, it is only meaningful
# for shared (non private) memory sections.
if vad.VadFlags.PrivateMemory != 1 and control_area:
if control_area:
file_object = vad.FileObject
if file_object:
file_name = file_object.file_name_with_device()
except AttributeError:
pass

# Return VAD regions
vad_list.append(VADRegion(vad.obj_offset,
vad.Parent.obj_offset if vad.Parent else None,
vad.Start,
vad.End,
file_name,
str(vad.Tag),
vad_type,
(vad.VadFlags.PrivateMemory == 1),
protection))
if vad.Parent:
vad_parents.append(vad.Parent.obj_offset)

for v in vad_list:
if v.obj_offset in vad_parents:
v.is_parent = True

return vad_list

0 comments on commit e490f7f

Please sign in to comment.