good start to script variables

This commit is contained in:
sadnub 2021-04-01 00:23:21 -04:00
parent ca446cac87
commit 0f32a3ec24
3 changed files with 106 additions and 1 deletions

View File

@ -30,3 +30,4 @@ mkdocs-material
pymdown-extensions
Pygments
mypy
pysnooper

View File

@ -296,10 +296,13 @@ class Agent(BaseAuditModel):
from scripts.models import Script
script = Script.objects.get(pk=scriptpk)
parsed_args = script.parse_script_args(self, script.shell, args)
data = {
"func": "runscriptfull" if full else "runscript",
"timeout": timeout,
"script_args": args,
"script_args": parsed_args,
"payload": {
"code": script.code,
"shell": script.shell,

View File

@ -1,4 +1,8 @@
import base64
from typing import List, Union, Any
import re
# import pysnooper
from django.db import models
@ -116,3 +120,100 @@ class Script(BaseAuditModel):
from .serializers import ScriptSerializer
return ScriptSerializer(script).data
@classmethod
# @pysnooper.snoop()
def parse_script_args(
cls, agent, shell: str, args: List[str] = list()
) -> Union[List[str], None]:
from core.models import CustomField
if not list:
return []
temp_args = list()
# pattern to match for injection
pattern = re.compile(".*\\{\\{(.*)\\}\\}.*")
for arg in args:
match = pattern.match(arg)
if match:
# only get the match between the () in regex
string = match.group(1)
# split by period if exists. First should be model and second should be property
temp = string.split(".")
# check for model and property
if len(temp) != 2:
# ignore arg since it is invalid
continue
if temp[0] == "client":
model = "client"
obj = agent.client
elif temp[0] == "site":
model = "site"
obj = agent.site
elif temp[0] == "agent":
model = "agent"
obj = agent
else:
# ignore arg since it is invalid
continue
if hasattr(obj, temp[1]):
value = getattr(obj, temp[1])
elif CustomField.objects.filter(model=model, name=temp[1]):
field = CustomField.objects.get(model=model, name=temp[1])
model_fields = getattr(field, f"{model}_fields")
if model_fields.filter(**{model: obj}).exists():
value = model_fields.get(**{model: obj}).value
else:
value = field.default_value
# check if value exists and if not use defa
if value and field.type == "multiple":
value = format_shell_array(shell, value)
elif field.type == "checkbox":
value = format_shell_bool(shell, value)
else:
# ignore arg since property is invalid
continue
# replace the value in the arg and push to array
temp_args.append(re.sub("\\{\\{.*\\}\\}", value, arg)) # type: ignore
else:
temp_args.append(arg)
return temp_args
def format_shell_array(shell: str, value: Any) -> str:
if shell == "cmd":
return "array args are not supported with batch"
elif shell == "powershell":
temp_string = ""
for item in value:
temp_string += item + ","
return temp_string.strip(",")
else: # python
temp_string = ""
for item in value:
temp_string += item + ","
return "[" + temp_string.strip(",") + "]"
def format_shell_bool(shell: str, value: Any) -> str:
if shell == "cmd":
return "1" if value else "0"
elif shell == "powershell":
return "$True" if value else "$False"
else: # python
return "True" if value else "False"