Background
Οι επιτιθέμενοι έριξαν μέσα ένα Ransomware το οποίο μέχρι τώρα δεν είχαμε ξαναδεί, και προσπάθησαν να διασπείρουν το εκτελέσιμο αρχείο του Ransomware μέσω PsExec.
Δυστυχώς, το νέο στέλεχος δεν λειτουργεί τόσο απλά, οπότε η εύρεση του κλειδιού με αυτόν τον τρόπο είναι αδύνατη.
Προϋποθέσεις και ενέργειες
Θελήσαμε να εκμεταλλευτούμε τη μνήμη RAM για να προσπαθήσουμε και να βρούμε το κλειδί αποκρυπτογράφησης.
Για να γίνει αυτό, απαραίτητη προϋπόθεση ήταν να μην έχει κλείσει ο Η/Υ που έχει προσβληθεί, καθώς κάτι τέτοιο θα σημαίνει ότι η μνήμη RAM χάνεται, και τότε είναι οριστικό Game Over.
Ψάχνοντας κλειδιά…
Μόλις ήμασταν έτοιμοι με το RAM dump, χρησιμοποιήσαμε το Volatility για να κάνουμε την ανάλυσή μας.
Το Volatility είναι ένα εξαιρετικό εργαλείο που χρησιμοποιείται για την εξαγωγή χρήσιμων πληροφοριών από τη μνήμη RAM και μάλιστα λειτουργεί άψογα σε μεγάλη ποικιλία λειτουργικών συστημάτων.
Για να το κάνουμε αυτό, απλά τσεκάρουμε ότι μπορούμε να δούμε τη λίστα ενεργειών του μηχανήματος.
Για να το κάνουμε αυτό, χρησιμοποιήσαμε το strings.exe, εργαλείο της SysInternals, με το οποίο γράψαμε τα raw strings σε ένα αρχείο κειμένου 🙂
Για να το κάνουμε αυτό, ανεβάσαμε το ram_strings.txt στο Volatility.
Decompiling Python…
Συνεχίσαμε προσπαθώντας να κάνουμε decompile το hc7.exe.
Για το σκοπό αυτό, χρησιμοποιήσαμε το pyinstxtractor για να εξάγουμε τα περιεχόμενα του εκτελέσιμου αλλά τα βρήκαμε σκούρα στην εξαγωγή του κυρίως hc9 script. Ζητήσαμε τη βοήθεια του Michael Gillespie ο οποίος είχε με επιτυχία αντιμετωπίσει στο παρελθόν κάτι παρόμοιο και όντως μας έδωσε λύση, η οποία είχε να κάνει με την εισαγωγή του Python 2.7 magic header στο εκτελέσιμο.
Αποκρυπτογράφηση!
Χρησιμοποιήσαμε το σχετικό blog post του 0xec σχετικά με τον hc6 και ήμασταν σε θέση να επαναλάβουμε τα βήματά τους.
Την εκμεταλλευτήκαμε, εισάγαμε το password που βρήκαμε μέσα στη RAM προηγουμένως, και αποκρυπτογραφήσαμε με επιτυχία ένα αρχείο!
from Crypto.Hash import SHA256
from Crypto.Cipher import AES
import os
import random
import sys
import base64
FILE_EXTENSION = '.GOTYA'
def getDigest(password):
hasher = SHA256.new(password)
return hasher.digest()
def decrypt(key, FileName):
OutputFile = os.path.join(os.path.dirname(FileName), os.path.basename(FileName.replace(FILE_EXTENSION, '')))
chunkS = 65536
with open(FileName, 'rb') as infile:
fileS = infile.read(16)
IniVect = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, IniVect)
with open(OutputFile, 'wb') as outfile:
while True:
chunk = infile.read(chunkS)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(int(fileS))
def run_decrypt():
if len(sys.argv) < 3:
print('Error')
sys.exit(0)
password = sys.argv[1]
filename = sys.argv[2]
decrypt(getDigest(password), filename)
if __name__ == "__main__":
run_decrypt()
(c) 2017 Michael Young, Ryan Zisk, Dimitris Anderson




