Skip to content
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

~/.polymorph dir //WIP #3

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
__pycache__/*g
*~
.DS_Store
*.egg-info
4 changes: 2 additions & 2 deletions polymorph/UI/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from polymorph.UI.command_parser import CommandParser
from collections import OrderedDict
import os
from os.path import dirname
# from os.path import dirname
import polymorph


Expand All @@ -21,7 +21,7 @@ class Interface(object):

def __init__(self):
self._poisoner = None
self._polym_path = dirname(polymorph.__file__)
self._polym_path = polymorph.settings.path

@staticmethod
def print_help(hdict):
Expand Down
15 changes: 7 additions & 8 deletions polymorph/UI/templateinterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import polymorph.conditions
import platform
from shutil import copyfile

from polymorph import settings, utils

class TemplateInterface(Interface):
"""This class is responsible for parsing and respond to user commands in
Expand All @@ -46,7 +46,7 @@ def __init__(self, template, index, poisoner=None):
self._t = template
self._index = index
self._poisoner = poisoner
self._conds_path = dirname(polymorph.conditions.__file__)
self._conds_path = settings.paths['conditions']

def run(self):
"""Runs the interface and waits for user input commands."""
Expand Down Expand Up @@ -256,10 +256,10 @@ def _conditions(self, command, cond):
# Adds a condition
elif args['-a']:
# Create the new file if not exists
if not os.path.isfile(join(self._conds_path, cond, args["-a"] + ".py")):
if not os.path.isfile(join(self._conds_path, settings.paths[cond], args["-a"] + ".py")):
self._create_cond(cond, args["-a"])
ret = os.system("%s %s.py" % (
args["-e"], join(self._conds_path, cond, args["-a"])))
args["-e"], join(self._conds_path, settings.paths[cond], args["-a"])))
if ret != 0:
Interface._print_error(
"The editor is not installed or is not in the PATH")
Expand Down Expand Up @@ -288,6 +288,7 @@ def _conditions(self, command, cond):
name = file
if name[-3:] == ".py":
name = name[:-3]
self._add_cond(cond, name)
try:
self._add_cond(cond, name)
Interface._print_info("Condition %s imported" % args['-i'])
Expand All @@ -300,14 +301,12 @@ def _conditions(self, command, cond):
def _create_cond(self, cond, name):
"""Creates a new condition with the initial source code."""
code = "def %s(packet):\n\n # your code here\n\n # If the condition is meet\n return packet" % name
with open("%s.py" % join(self._conds_path, cond, name), 'w') as f:
with open("%s.py" % join(settings.paths[cond], name), 'w') as f:
f.write(code)

def _add_cond(self, cond, name):
"""Adds a new condition to the `Template`."""
m = importlib.import_module(
"polymorph.conditions.%s.%s" % (cond, name))
importlib.reload(m)
m = utils.import_file(join(settings.paths[cond], "{}.py".format(name)), "polymorph.conditions.%s.%s" % (cond, name))
self._t.add_function(cond, name, getattr(m, dir(m)[-1]))

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions polymorph/UI/tlistinterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from polymorph.deps.prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from polymorph.deps.prompt_toolkit.shortcuts import CompleteStyle
import polymorph
from os.path import dirname, join
from os.path import join


class TListInterface(Interface):
Expand All @@ -37,7 +37,7 @@ def __init__(self, tlist, poisoner=None):
# Class Attributes
self._t = tlist
self._poisoner = poisoner
self._polym_path = dirname(polymorph.__file__)
self._polym_path = polymorph.settings.path

def run(self):
"""Runs the interface and waits for user input commands."""
Expand Down
3 changes: 3 additions & 0 deletions polymorph/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from .settings import Settings

# PoC to create initial settings manager
settings = Settings()
21 changes: 21 additions & 0 deletions polymorph/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os

class Settings (object):

def __init__(self):
self._poisoner = None
self.path = os.path.expanduser("~/.polymorph")

self.paths = {
"": self.path,
"conditions": "{}/conditions".format(self.path),
"preconditions": "{}/conditions/preconditions".format(self.path),
"postconditions": "{}/conditions/postconditions".format(self.path),
"executions": "{}/conditions/executions".format(self.path),
"templates": "{}/templates".format(self.path),
}

# TODO; Ensure that all App reuse this iface._polym_path instead of redefine it
for _path in self.paths.values():
if not os.path.exists(_path):
os.makedirs(_path)
24 changes: 16 additions & 8 deletions polymorph/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import polymorph.conditions
from os import listdir
from os.path import isfile, join

from polymorph import settings

class Template:
"""Main class that represents a template"""
Expand Down Expand Up @@ -47,7 +47,7 @@ def __init__(self, name=None, raw=None, from_path=None,
if from_path:
self.read(from_path)
# Path to conditions (precs, execs, posts)
self._conds_path = dirname(polymorph.conditions.__file__)
self._conds_path = dirname(settings.paths['conditions'])

def __repr__(self):
return "<template.Template: %s>" % "/".join(self.layernames())
Expand All @@ -67,7 +67,13 @@ def write(self, path=None):
"""
if not path:
path = "../templates/" + self._name.replace("/", "_") + ".json"
with open(path, 'w') as outfile:

if not path.endswith(".json"):
path += ".json"

template_file = "{}/{}".format(settings.paths['templates'], path)

with open(template_file, 'w') as outfile:
json.dump(self.dict(), outfile, indent=4)

@property
Expand Down Expand Up @@ -213,7 +219,7 @@ def del_execution(self, name):
"""
self.del_function('executions', name)

def get_function_source(self, func, name):
def get_function_source(self, cond, name):
"""Returns a precondition/postcondition/execution source code.

Parameters
Expand All @@ -229,7 +235,7 @@ def get_function_source(self, func, name):
Source code of the function.

"""
path = "%s/%s/%s.py" % (self._conds_path, func, name)
path = join(settings.paths[cond], "{}.py".format(name))
if os.path.isfile(path):
return open(path).read()
return "[!] File is not in disk"
Expand Down Expand Up @@ -581,7 +587,8 @@ def show_conditions(self, cond, name=None, verbose=False):
def print_source(cond, n):
print(colored(n, 'cyan'))
print(self.get_function_source(cond, n))


_cond_path = settings.paths[cond]
cond_names = list(self._functions[cond])
if name and name in cond_names and verbose:
print_source(cond, name)
Expand All @@ -606,9 +613,10 @@ def show_all_conds(self, cond, verbose=False):
conditions.

"""
_cond_path = settings.paths[cond]
cond_names = [f[:-3]
for f in listdir(join(self._conds_path, cond))
if isfile(join(join(self._conds_path, cond), f))
for f in listdir(_cond_path)
if isfile(join(_cond_path, f))
and f != "__init__.py"
and f[-3:] == ".py"]
if verbose:
Expand Down
36 changes: 34 additions & 2 deletions polymorph/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,42 @@
import platform
import polymorph
from os.path import dirname, join
import imp, os, importlib

POLYM_PATH = dirname(polymorph.__file__)


def import_file(filename, module=""):
"""
old stuff just for debug purposes
# m = importlib.import_module(
# "polymorph.conditions.%s.%s" % (settings.paths[cond], name))
# importlib.reload(m)

"""
module = None

try:
# Get module name and path from full path
module_dir, module_file = os.path.split(filename)
module_name, module_ext = os.path.splitext(module_file)

# Get module "spec" from filename
spec = importlib.util.spec_from_file_location(module_name,filename)

module = spec.loader.load_module()

except Exception as ec:
# TODO validate py2 importing if needed @shramos
print(ec)

finally:
return module

with open(filename, "r") as f:
return imp.load_module(module, f, filename, "")


def capture(userfilter="", pcapname=".tmp.pcap", func=None, count=0, time=None):
"""This function is a wrapper function above the sniff scapy function. The
result is a list of templates. The specification on filtering options can
Expand Down Expand Up @@ -144,7 +177,7 @@ def set_ip_forwarding(value):
file.write(str(value))
file.close()


def get_arpspoofer(targets, gateway, iface=None, gatewaymac=None,
ignore=None, arpmode='rep', mac=None, ip=None):
# Creating a poison object
Expand All @@ -154,4 +187,3 @@ def get_arpspoofer(targets, gateway, iface=None, gatewaymac=None,
poisoner = ARPpoisoner(poison)
# return the poisoner
return poisoner