Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def decode_atomiku(self, file_name):
- """
- De-obfuscates code that has been encoded with http://atomiku.com/online-php-code-obfuscator/
- :param file_name: File to be decoded
- :return: Returns the de-obfuscated code or None if failed to decode
- """
- # Open up the file for reading
- with open(file_name, 'r') as file_handle:
- file_data = file_handle.read()
- # Regex patterns for different recursive layers
- search_code_1 = (r'preg_replace\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C'
- r'\\x61\\x74\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65'
- r'\\x28\'(?P<encoded_code>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);(?!preg_replace)')
- search_code_2 = (r'preg_replace\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C'
- r'\\x61\\x74\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65'
- r'\\x28\'(?P<encoded_code_1>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);preg_replace'
- r'\(\"\/\.\*\/e\",\s*\"\\x65\\x76\\x61\\x6C\\x28\\x67\\x7A\\x69\\x6E\\x66\\x6C\\x61\\x74'
- r'\\x65\\x28\\x62\\x61\\x73\\x65\\x36\\x34\\x5F\\x64\\x65\\x63\\x6F\\x64\\x65\\x28\''
- r'(?P<encoded_code_2>.+)\'\\x29\\x29\\x29\\x3B\",\s*\"\"\);')
- search_code_3 = (r'\$[\w\d]+\s*.=\s*\"(?P<encoded_1>.+)\";\s*\$[\w\d]+\s*.=\s*\"(?P<encoded_2>.+)\";\s*\$'
- r'[\w\d]+\s*.=\s*\"(?P<encoded_3>.+)\";\s*\$[\w\d]+\s*.=\s*\"(?P<encoded_4>.+)\";')
- search_code_4 = r'eval\([\w\d]+\(\"(?P<encoded_code>.+)\"\)\);'
- first_run = True
- still_matches = True
- obfuscated_code = None
- while still_matches:
- if first_run:
- first_run = False
- # First round will always follow the same pattern
- regex = re.compile(search_code_1)
- match = regex.search(file_data)
- if match:
- # De-obfuscate the layer and continue to next round
- obfuscated_code = self.gzinflate(self.base64_decode(match.group('encoded_code')))
- continue
- else:
- # If no match, likely a corrupted file. Return None
- return None
- else:
- # On subsequent runs
- if obfuscated_code is None: # If this is None, likely a corrupted file.
- return None
- # First check for double preg_replace() pattern
- regex = re.compile(search_code_2)
- match = regex.search(obfuscated_code)
- if match:
- # De-obfuscate the layer and continue to next round
- # We only need the code from the second preg_replace()
- obfuscated_code = self.base64_decode(match.group('encoded_code_2'))
- obfuscated_code = self.gzinflate(obfuscated_code)
- continue
- # Check for single preg_replace() pattern
- regex = re.compile(search_code_1)
- match = regex.search(obfuscated_code)
- if match:
- # De-obfuscate the layer and continue to next round
- obfuscated_code = self.base64_decode(match.group('encoded_code'))
- obfuscated_code = self.gzinflate(obfuscated_code)
- continue
- # Check for 4 randomly named variables pattern
- regex = re.compile(search_code_3)
- match = regex.search(obfuscated_code)
- if match:
- # Append all for variables together and convert hex to ascii and move to next round
- obfuscated_code = match.group('encoded_1') + match.group('encoded_2') + \
- match.group('encoded_3') + match.group('encoded_4')
- obfuscated_code = obfuscated_code.replace('\\x', '').decode('hex')
- continue
- # Check for final eval() pattern
- regex = re.compile(search_code_4)
- match = regex.search(obfuscated_code)
- if match:
- # De-obfuscate and go through one more round in case of more rounds
- obfuscated_code = self.gzinflate(self.base64_decode(match.group('encoded_code')))
- continue
- # No more matches, end while loop
- still_matches = False
- # Return de-obfuscated code, trim ?> from beginning of string
- return obfuscated_code[2:]
Advertisement
Add Comment
Please, Sign In to add comment