spender-sandbox / community-modified

Modified edition of cuckoo community modules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Providing extra information from signatures

Waffles-2 opened this issue · comments

Hi,

I have some working signatures and cannot seem to make it so when the signature is clicked, on the web page, that the extra bit of information is expanded below and displayed. I am assuming self.data.append is the way to do this, if anyone could help me out that would get great, cheers.

Below is my code I am trying to do it with:

from lib.cuckoo.common.abstracts import Signature

class rundll32(Signature):
    name = "rundll32 loaded"
    description = "Rundll32.exe has been executed"
    severity = 1
    categories = ["DLLs"]
    authors = ["Daniel Perrie"]
    minimum = "1.2"
    evented = True

    def __init__(self, *args, **kwargs):
        Signature.__init__(self, *args, **kwargs)
        self.dll = False

    filter_apinames = set(["CreateProcessInternalW"])

    def on_call(self, call, process):
        if call["api"] == "CreateProcessInternalW":
            funcName = self.get_argument(call, "ApplicationName")
            if r"C:\Users\admin\AppData\Local\Temp\Cerber3.exe" in funcName:
                processName = self.get_argument(call, "Process")
                commandLineParameter = self.get_argument(call, "CommandLine")
                self.data.append({"Process" : "%s executed rundll32.exe with the command line: %s" % (processName, commandLineParameter)})
                self.dll = True
        return self.dll

you need return True if mached, and return False if not, so then cuckoo will know if it must be showed or not

I have a return True in there I just forgot to include it (I have amended it), so the problem is that the signature is being returned as True or false like it should be but it is not including the appended information, like other signatures.

And yeah I know that is a better one, I was just using Cerber as a placeholder for other exes such as rundll32.

you verified what is matched in ifs? you can add logging to see if it was True or False

Where you have the return self.dll is incorrect -- It'll stop processing your signature immediately after the first call to CreateProcessInternalW. Here's what happens regarding returns from on_call:

If you return True from the function, it will mark the signature as matched and stop calling the signature for future APIs. It will also not call the on_complete() function of the signature
If you return False from the function, it will stop calling the signature for future APIs and likewise will not call the on_complete() function of the signature.

What you need to do is return None or simply don't add any return, this will make the signature get called for every CreateProcessInternalW function. So if you want it to only add one entry below the signature for the first instance where it sees the cerber3.exe execution (and you should probably be doing case-insensitive matching there) then return True from the same indentation level as the self.data.append()

-Brad

@doomedraven The code above is correctly returning True or False that is not the problem, hopefully this gif will better illustrate my issue: https://gyazo.com/444c2627c21b3344b1167657b1cf8fbd

@spender-sandbox Thank you that explains it well, I shall try returning None. The cerber3.exe is just a placeholder for testing and will be changed to rundll32.exe, I'll add some matching there though thanks!

@spender-sandbox Hi Brad, sorry for the bother again. I'm struggling to make the changes that you have suggested and to make the signature so that it shows the entries below the signature as currently it doesn't show anything (https://gyazo.com/444c2627c21b3344b1167657b1cf8fbd)

EDIT:

Semi-working code the process in self.data.append isn't working.

from lib.cuckoo.common.abstracts import Signature

class rundll32(Signature):
    name = "RunDll32"
    description = "RUNDLL32.exe has been executed"
    severity = 3
    categories = ["anti-av"]
    authors = ["Optiv"]
    minimum = "1.2"
    evented = True

    def __init__(self, *args, **kwargs):
        Signature.__init__(self, *args, **kwargs)
        self.processName = None
        self.commandLineParameter = None

    filter_apinames = set(["CreateProcessInternalW"])

    def on_call(self, call, process):
        if call["api"] == "CreateProcessInternalW":
            funcName = self.get_argument(call, "ApplicationName")
            if r"C:\Users\admin\AppData\Local\Temp\Cerber3.exe" in funcName:
                self.processName = self.get_argument(call, "Process")
                self.commandLineParameter = self.get_argument(call, "CommandLine")
                self.data.append({"Process" :  "%s executed rundll32.exe with the command line: %s" % (self.processName, self.commandLineParameter)})
            return True

You're returning True at the wrong indentation. Put it under the if.

-Brad

I have moved it under the other if statement, but it still only returns one result even though it should return multiple responses

    def on_call(self, call, process):
        if call["api"] == "CreateProcessInternalW":
            funcName = self.get_argument(call, "ApplicationName")
            if r"C:\Users\admin\AppData\Local\Temp\Cerber3.exe" in funcName:
                self.processName = self.get_argument(call, "Process")
                self.commandLineParameter = self.get_argument(call, "CommandLine")
                self.data.append({"Process" :  "%s executed rundll32.exe with the command line: %s" % (self.processName, self.commandLineParameter)})
        return True

try to not return nothing as Brad told, and add def on_complate(self) and do return there

So would it be like this? Because this does return as True but does not provide the information appended? Do I have to append the information in def on_complete(self) ?

    def on_call(self, call, process):
        if call["api"] == "CreateProcessInternalW":
            funcName = self.get_argument(call, "ApplicationName")
            if r"C:\Users\admin\AppData\Local\Temp\Cerber3.exe" in funcName:
                #self.processName = self.get_argument(call, "Process")
                self.commandLineParameter = self.get_argument(call, "CommandLine")
                self.data.append({"Process" : " " + process["process_name"] + " executed rundll32.exe with the command line: %s" % (self.commandLineParameter)})
            return None

    def on_complete(self):
        return True

yes, but i would suggest add some check to on_complate as is it will return True all the time even when is not cerber3

When I add a check it never returns true and always returns false, do you have an example of a check I could implement?

from lib.cuckoo.common.abstracts import Signature

class rundll32(Signature):
name = "RunDll32"
description = "RUNDLL32.exe has been executed"
severity = 3
categories = ["anti-av"]
authors = ["Optiv"]
minimum = "1.2"
evented = True

def __init__(self, *args, **kwargs):
    Signature.__init__(self, *args, **kwargs)
    self.processName = None
    self.commandLineParameter = None
    self.matched = False
filter_apinames = set(["CreateProcessInternalW"])

def on_call(self, call, process):
    if call["api"] == "CreateProcessInternalW":
        funcName = self.get_argument(call, "ApplicationName")
        if r"C:\Users\admin\AppData\Local\Temp\Cerber3.exe" in funcName:
            self.processName = self.get_argument(call, "Process")
            self.commandLineParameter = self.get_argument(call, "CommandLine")
            self.data.append({"Process" :  "%s executed rundll32.exe with the command line: %s" % (self.processName, self.commandLineParameter)})
            self.matched = True

def on_complete(self):
    return self.matched

Brad, unfortunately that signature will always return as False, regardless of whether the on_call def sets self.matched to true, this is my final working signature (not sure if the return None lines are necessary):

from lib.cuckoo.common.abstracts import Signature

class rundll32(Signature):
    name = "RunDll32"
    description = "RUNDLL32.exe has been executed"
    severity = 1
    categories = ["Dll execution"]
    authors = ["Daniel Perrie"]
    minimum = "1.2"
    evented = True

    def __init__(self, *args, **kwargs):
        Signature.__init__(self, *args, **kwargs)
        self.processName = None
        self.commandLineParameter = None
        
    filter_apinames = set(["CreateProcessInternalW"])

    def on_call(self, call, process):
        if call["api"] == "CreateProcessInternalW":
            funcName = self.get_argument(call, "ApplicationName")
            if r"C:\Windows\system32\rundll32.exe" in funcName:
                self.processName = self.get_argument(call, "Process")
                self.commandLineParameter = self.get_argument(call, "CommandLine")
                self.data.append({"Process" : " " + process["process_name"] + " executed rundll32.exe with the command line: %s" % (self.commandLineParameter)})
                return None
        return None

    def on_complete(self):
        if len(self.data) > 0:
            return True
        else:
            return False