Skip to content

Updated _get_incapsula_sl #23

Open
@Wh1terat

Description

@Wh1terat

Without doubt some of the roughest, dirtiest code I've ever ever written, but it works to return the "sl" value from the latest incapsula/imperva obfuscated js.

I'm logging it as an issue simply because although it works, it's just too damn nasty to be a pull request and in all honesty I just did this for the fun of the challenge and don't particularly feel like refactoring it into something pretty. (although if I did, I'd go down the pyjsparser route I think)

Enjoy.

   def _get_incapsula_sl(self, b):
        """
        Get the sl var value from the obfuscated JS code.

        "Never again"
        -Wh1terat (19/10/2019 @ 2AM)
        
        :param b: Obfuscated JS code where is the sl var value.
        :return: 
        """

        if not b:
            return None

        def decode(data, key):
            data = b64decode(data).decode('utf-8')
            key = [ord(c) for c in key]
            keylength = len(key)
            S = list(range(256))
            j = 0
            for i in range(256):
                j = (j + S[i] + key[i % keylength]) % 256
                S[i], S[j] = S[j], S[i]
            i = 0
            j = 0
            out = []
            for x in range(len(data)):
                i = (i + 1) % 256
                j = (j + S[i]) % 256
                S[i], S[j] = S[j], S[i]
                K = S[(S[i] + S[j]) % 256]
                out.append(ord(data[x]) ^ K)
            return ''.join(chr(x) for x in out)

        def hexstr(data):
            return bytes.fromhex(re.sub('[x\\\\,]','',data))

        rxps = {
                'body' : r'"";var [a-z]="([^"]*)',
                'arrays' : r"var (_0x\w+)=\[('.*?)\]",
                'inits' : r"}\((_0x\w+),(0x\w+)\)\);var (_0x\w+)",
        }
        body = re.search(rxps['body'], b)
        body = bytes.fromhex(body.group(1)).decode('utf-8')
        arrays = {}
        for array in re.finditer(rxps['arrays'], body):
            arrname = array.group(1)
            arrays.setdefault(arrname, {})
            arrays[arrname]['data'] = [hexstr(x.group(1)) for x in re.finditer(r"'(.*?)'", array.group(2))]
        for init in re.finditer(rxps['inits'], body):
            arrname = init.group(1)
            arrays[arrname]['name'] = init.group(3)
            n = int(init.group(2),16) % len(arrays[arrname]['data'])
            arrays[arrname]['data'] = arrays[arrname]['data'][n:] + arrays[arrname]['data'][:n]
        for k,v in arrays.items():
            name = v['name']
            for x in re.finditer("{}\('(0x\w+)', '(.*?)'\)".format(v['name']), body):
                try:
                    hexstr(x.group(2)).decode('utf-8')
                except UnicodeError:
                    i = int(x.group(1),16)
                    k = hexstr(x.group(2)).decode('latin')
                    l = v['data'][i]
                    d = decode(l, k)
                    if len(d) == 40:
                        return d
        return None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions