送给最好的TA.apk分析

今天这份上古恶意软件突然又流传于各大校园,于是我来尝试分析一下这个apk

分析

对于apk,先尝试jadx反编译工具一把梭

01

大致看一下几个类,猜测可能封装了lua的解释执行器或是虚拟机,那么我们的目标就是找到lua代码。

最后在com.androlua.Main类里找到了疑似的代码:

02

同时在Resource里也能看到0.mp3和main.lua等文件:

03

众所周知,apk是个zip包:

1
2
$ file 送给最好的TA.apk
送给最好的TA.apk: Zip archive data, at least v1.0 to extract

于是直接7z打开提取出lua文件。

010等工具打开看看,发现不像是lua的字节码,至少熵特别低,倒是像加密过的代码:

04

查找相关资料,得知luac文件开头的“魔数”(magic number)是.LuaS,即1B 4C 75 61 53,这里显然不是。然而横向对比几个Lua文件,发现他们的第一个字节都是0x1B。

这里猜测他可能被加密了,于是一直在apk里找可能的解密部分,找了半天除了找到个RSA和AES,可是都找不到密钥。。。

思考一下,如果是RSA或者AES,显然不会不加密第一个字节,所以这里的加密可能比较简单,或者不在java层面。最后考虑会在.so文件中直接加载并解密,于是看看libluajava.so

ida打开,找找可疑函数,发现有个叫luaL_loadbufferx的函数,仔细一看有点类似解密的代码

05

这里看到,他先对比了第一个字节是不是0x1B,然后后面对应了一个十分ez的异或解密。

可能有些同学好奇,这里的0xFFFFFFFF80808081是啥,其实这是编译器的编译优化,对于整数除法或取模,会被优化成乘法和右移的形式,感兴趣的同学可以自行查找资料。

然而我并没有看出它的除法运算是啥。。。不过ez,直接抄代码解密:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
filename = "main.lua"

with open(filename, "rb") as f:
    buf = f.read()
length = len(buf)

def decrypt(buf, length):
    assert buf[0] == 0x1B and buf[1]!=0x4C
    res = [0 for i in range(length)]
    res[0] = 0x1B
    v10 = 0

    for i in range(1, length):
        v10 += length
        tmp = (0x10000000080808081 * v10)>>32
        xor = v10 + (tmp >> 7)
        if tmp >> 31 == 1:
            xor +=1
        xor &= 0xFF
        res[i] = buf[i] ^ xor
    return bytes(res)
de_buf = decrypt(buf,length)

with open(filename + "c","wb") as f:
    f.write(de_buf)

好了,我们拿到了解密过的luac文件:

06

再搜一波资料,发现有个叫unluac的工具可以反编译luac,一把梭:

1
java -jar unluac_2015_06_13.jar main.luac > main_de.lua

到了这里,我们就拿到了lua的源码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require("import")
import("android.app.*")
import("android.os.*")
import("android.widget.*")
import("android.view.*")
import("android.view.View")
import("android.content.Context")
import("android.media.MediaPlayer")
import("android.media.AudioManager")
import("com.androlua.Ticker")
activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)
m = MediaPlayer()
m.reset()
m.setDataSource(activity.getLuaDir() .. "/0.mp3")
m.prepare()
m.start()
m.setLooping(true)
ti = Ticker()
ti.Period = 10
function ti.onTick()
  activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
  activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)
end
ti.start()
function onKeyDown(A0_0, A1_1)
  if string.find(tostring(A1_1), "KEYCODE_BACK") ~= nil then
    activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
  end
  return true
end

可以看到,这里调用了MediaPlayer函数,播放了0.mp3

同时把你的音量锁定到了15

又同时改了按下音量键的一些效果。

对于所说的截屏,确实能看到截取屏幕图像的方法,但是暂时没找到如何调用的

07

并没有找到上传的点,也没有上传到哪个服务器。

解决办法

直接关机重启卸载就可以解决。听说某位同学把手机直接掰两半了,心疼。

如果遇到十分紧急的情况,不要慌张,第一时间插上耳机然后关机就没事了。

危害

整个app只是把lua封装进了apk,执行lua代码。

整个apk应该只是一个恶作剧程序,完全是为了恶搞。

现在的思路是Run起来后抓包,看看有没有往外的数据。

使用Virtotal分析并没有报很大的危害,只有360报了流氓软件:

08

至于网传的危害多么多么大,会泄露个人隐私等等,并没有直接证据,等待后续继续逆向分析。

总结

提醒各位同学,千万不要点击来路不明的apk,文件等。

希望大家多多学习网络安全知识,不要被这种十分低级的套路恶心到了。

评论