This repository has been archived by the owner on Feb 21, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added use-cases presented at EuskalHack 2018
- Loading branch information
1 parent
654d8ee
commit e490f7f
Showing
12 changed files
with
1,844 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
Oops, something went wrong.