View difference between Paste ID: k1DC9MJb and 7eDN5Fkt
SHOW: | | - or go back to the newest paste.
1
    def decode_atomiku(self, file_name):
2
        """
3
        De-obfuscates code that has been encoded with http://atomiku.com/online-php-code-obfuscator/
4
        :param file_name: File to be decoded
5
        :return: Returns the de-obfuscated code or None if failed to decode
6
        """
7
8
        # Open up the file for reading
9
        with open(file_name, 'r') as file_handle:
10
            file_data = file_handle.read()
11
12
            # Regex patterns for different recursive layers
13
            search_code_1 = (r'preg_replace\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C'
14
                             r'\\x61\\x74\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65'
15
                             r'\\x28\'(?P<encoded_code>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);(?!preg_replace)')
16
            search_code_2 = (r'preg_replace\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C'
17
                             r'\\x61\\x74\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65'
18
                             r'\\x28\'(?P<encoded_code_1>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);preg_replace'
19
                             r'\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C\\x61\\x74'
20
                             r'\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65\\x28\''
21
                             r'(?P<encoded_code_2>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);')
22
            search_code_3 = (r'\$[\w\d]+\s*.=\s*\"(?P<encoded_1>.+)\";\s*\$[\w\d]+\s*.=\s*\"(?P<encoded_2>.+)\";\s*\$'
23
                             r'[\w\d]+\s*.=\s*\"(?P<encoded_3>.+)\";\s*\$[\w\d]+\s*.=\s*\"(?P<encoded_4>.+)\";')
24
            search_code_4 = r'eval\([\w\d]+\(\"(?P<encoded_code>.+)\"\)\);'
25
26
            first_run = True
27
            still_matches = True
28
            obfuscated_code = None
29
30
            while still_matches:
31
                if first_run:
32
                    first_run = False
33
34
                    # First round will always follow the same pattern
35
                    regex = re.compile(search_code_1)
36
                    match = regex.search(file_data)
37
38
                    if match:
39
                        # De-obfuscate the layer and continue to next round
40
                        obfuscated_code = self.gzinflate(self.base64_decode(match.group('encoded_code')))
41
                        continue
42
                    else:
43
                        # If no match, likely a corrupted file. Return None
44
                        return None
45
                else:
46
                    # On subsequent runs
47
48
                    if obfuscated_code is None:  # If this is None, likely a corrupted file.
49
                        return None
50
51
                    # First check for double preg_replace() pattern
52
                    regex = re.compile(search_code_2)
53
                    match = regex.search(obfuscated_code)
54
55
                    if match:
56
                        # De-obfuscate the layer and continue to next round
57
                        # We only need the code from the second preg_replace()
58
                        obfuscated_code = self.base64_decode(match.group('encoded_code_2'))
59
                        obfuscated_code = self.gzinflate(obfuscated_code)
60
                        continue
61
62
                    # Check for single preg_replace() pattern
63
                    regex = re.compile(search_code_1)
64
                    match = regex.search(obfuscated_code)
65
66
                    if match:
67
                        # De-obfuscate the layer and continue to next round
68
                        obfuscated_code = self.base64_decode(match.group('encoded_code'))
69
                        obfuscated_code = self.gzinflate(obfuscated_code)
70
                        continue
71
72
                    # Check for 4 randomly named variables pattern
73
                    regex = re.compile(search_code_3)
74
                    match = regex.search(obfuscated_code)
75
76
                    if match:
77
                        # Append all for variables together and convert hex to ascii and move to next round
78
                        obfuscated_code = match.group('encoded_1') + match.group('encoded_2') + \
79
                                          match.group('encoded_3') + match.group('encoded_4')
80
                        obfuscated_code = obfuscated_code.replace('\\x', '').decode('hex')
81
                        continue
82
83
                    # Check for final eval() pattern
84
                    regex = re.compile(search_code_4)
85
                    match = regex.search(obfuscated_code)
86
87
                    if match:
88
                        # De-obfuscate and go through one more round in case of more rounds
89
                        obfuscated_code = self.gzinflate(self.base64_decode(match.group('encoded_code')))
90
                        continue
91
92
                # No more matches, end while loop
93
                still_matches = False
94
95
        # Return de-obfuscated code, trim ?> from beginning of string
96
        return obfuscated_code[2:]