Skip to content

Commit

Permalink
Merge pull request #46 from CybercentreCanada/atob
Browse files Browse the repository at this point in the history
Atob
  • Loading branch information
cccs-jh authored Mar 23, 2023
2 parents d59c06e + 8b1f343 commit c8c58e5
Showing 1 changed file with 48 additions and 29 deletions.
77 changes: 48 additions & 29 deletions deobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,42 +153,61 @@ def string_replace(text: bytes) -> Optional[bytes]:

def b64decode_str(self, text: bytes) -> Optional[bytes]:
""" Decode base64 """
b64str = regex.findall(b'((?:[A-Za-z0-9+/]{3,}={0,2}(?:&#[x1][A0];)?[\r]?[\n]?){6,})', text)
output = text

head: bytes
bmatch: bytes
tail: bytes
for head, bmatch, tail in regex.findall(rb'((?:atob\()+)\'([A-Za-z0-9+/]+={0,2})\'(\)+)', text):
iters = min(len(head)//5, len(tail))
d = bmatch
for _ in range(iters):
try:
d = binascii.a2b_base64(d)
except binascii.Error:
break
output = output.replace(b'atob('*iters + b"'" + bmatch + b"'" + b')'*iters, b"'" + d + b"'")

b64str: list[bytes] = regex.findall(b'((?:[A-Za-z0-9+/]{3,}={0,2}(?:&#[x1][A0];)?[\r]?[\n]?){6,})', text)
for bmatch in b64str:
s = bmatch.replace(b'\n',
b'').replace(b'\r', b'').replace(b' ', b'').replace(b'
', b'').replace(b'
', b'')
if bmatch not in output:
continue # was already processed by atob
s = (bmatch.replace(b'\n', b'')
.replace(b'\r', b'')
.replace(b' ', b'')
.replace(b'
', b'')
.replace(b'
', b''))
uniq_char = set(s)
if len(uniq_char) > 6:
if len(s) >= 16 and len(s) % 4 == 0:
try:
d = binascii.a2b_base64(s)
except binascii.Error:
continue
if len(uniq_char) <= 6 or len(s) < 16 or len(s) % 4:
continue
try:
d = binascii.a2b_base64(s)
except binascii.Error:
continue
sha256hash = hashlib.sha256(d).hexdigest()
if sha256hash not in self.hashes:
if len(d) > 500:
m = magic.Magic(mime=True)
mag = magic.Magic()
ftype = m.from_buffer(d)
mag_ftype = mag.from_buffer(d)
sha256hash = hashlib.sha256(d).hexdigest()
if sha256hash not in self.hashes:
if len(d) > 500:
for file_type in self.FILETYPES:
if (file_type in ftype and 'octet-stream' not in ftype) or file_type in mag_ftype:
b64_file_name = f"{sha256hash[0:10]}_b64_decoded"
b64_file_path = os.path.join(self.working_directory, b64_file_name)
with open(b64_file_path, 'wb') as b64_file:
b64_file.write(d)
self.files_extracted.add(b64_file_path)
self.hashes.add(sha256hash)
break

if len(set(d)) > 6 and all(8 < c < 127 for c in d) and len(regex.sub(rb"\s", b"", d)) > 14:
output = output.replace(bmatch, d)
else:
# Test for ASCII seperated by \x00
p = d.replace(b'\x00', b'')
if len(set(p)) > 6 and all(8 < c < 127 for c in p) and len(regex.sub(rb"\s", b"", p)) > 14:
output = output.replace(bmatch, p)
for file_type in self.FILETYPES:
if (file_type in ftype and 'octet-stream' not in ftype) or file_type in mag_ftype:
b64_file_name = f"{sha256hash[0:10]}_b64_decoded"
b64_file_path = os.path.join(self.working_directory, b64_file_name)
with open(b64_file_path, 'wb') as b64_file:
b64_file.write(d)
self.files_extracted.add(b64_file_path)
self.hashes.add(sha256hash)
break

if len(set(d)) > 6 and all(8 < c < 127 for c in d) and len(regex.sub(rb"\s", b"", d)) > 14:
output = output.replace(bmatch, d)
else:
# Test for ASCII seperated by \x00
p = d.replace(b'\x00', b'')
if len(set(p)) > 6 and all(8 < c < 127 for c in p) and len(regex.sub(rb"\s", b"", p)) > 14:
output = output.replace(bmatch, p)

if output == text:
return None
Expand Down

0 comments on commit c8c58e5

Please sign in to comment.