p*******m 发帖数: 20761 | 1 几天前,Bluebox Security刚曝出了Android存在安全漏洞。小分队立刻就掌握了其技
术细节。最近几天经过对Android的研究,小分队又发现了一个类似的漏洞。攻击者可
以对原apk进行修改,但不修改其原apk的签名。只是原理跟Bluebox Security曝的漏洞
不太一样,但效果是一样的。
这次我们讲讲技术细节:
1. 在讲这个漏洞之前,首先需要搞明白java里short类型转int类型的问题。要
理解这个漏洞,必须明白这个技术点。
public class JavaTest {
public static void main(String[] args) {
short a = (short)0xFFFF;
int b;
b = a;
System.out.println(b);
b = a & 0xFFFF;
System.out.println(b);
}
}
如果你能很清楚的了解上述代码中两次打印变量b的值有何不同,以及为何不同的话,
这部分就可以先跳过了。否则还是要先弄清楚再往下看。
2. Zip文件格式
在每个Zip文件中都有一个Central directory,Central directory中的每一项是一个
File header。这个File header的结构对应到Android代码的类就是ZipEntry。File
header结构中有一个偏移量指向local file header,local file header后面就紧跟着
file data。接下来我们详细看一下local file header的结构。
local file header signature 4 bytes (0x04034b50)
version needed to extract 2 bytes
general purpose bit flag 2 bytes
compression method 2 bytes
last mod file time 2 bytes
last mod file date 2 bytes
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
file name length 2 bytes
extra field length 2 bytes
file name (variable size)
extra field (variable size)
可以看到,除最后2个域以外,local file header的其他域都是定长的。而这两个变长
域的长度是由file name length和extra field length所确定。再次说明,紧跟在
extra field后面的就是文件的数据file data了。
3. Android如何进行apk校验
Android在进行apk文件校验时,会调到ZipFile的public InputStream getInputStream
(ZipEntry entry)函数。这函数中,有这么一段:
RAFStream rafstrm = new RAFStream(raf, entry.
mLocalHeaderRelOffset + 28);
DataInputStream is = new DataInputStream(rafstrm);
int localExtraLenOrWhatever = Short.reverseBytes(is.readShort());
is.close();
// Skip the name and this "extra" data or whatever it is:
rafstrm.skip(entry.nameLength + localExtraLenOrWhatever);
rafstrm.mLength = rafstrm.mOffset + entry.compressedSize;
if (entry.compressionMethod == ZipEntry.DEFLATED) {
int bufSize = Math.max(1024, (int)Math.min(entry.getSize(),
65535L));
return new ZipInflaterInputStream(rafstrm, new Inflater(true
), bufSize, entry);
} else {
return rafstrm;
}
注意:上述代码中红色部分。localExtraLenOrWhatever就是local file header结构中
的extra field length。回想一下我们第一部分将的技术点,如果这里的extra filed
length的大小是大于2^15,会怎么样?
没错,localExtraLenOrWhatever将会是负值。因此接下来,rafstrm.skip(entry.
nameLength + localExtraLenOrWhatever); 这句将无法真正跳过变长域file name (
variable size) 和extra field (variable size)。反而有可能呢会跳到file name (
variable size)中,甚至file name (variable size)之前。当然为了攻击方便,我们
还是期望它跳到file name (variable size)中。
4. 如何实施攻击
要改变一个apk的行为,显然攻击的目标就是apk里的classes.dex文件。对于classes.
dex文件在apk文件中的local file header结构,其file name (variable size)域的内
容肯定就是“classes.dex”了。注意,这里的后缀名dex,正好和dex文件开头的三个
字节完全相同(不理解的,参见dex文件格式)。
a) 利用这一点,从file name (variable size)域“classex.dex”的“.”之后
开始我们可以写入一个完整的dex文件。这个dex文件必须是原apk里的classes.dex文件
。只有这样才能绕过签名验证
b) 修改extra field length,使之为0xFFFD。因为这个值刚好为-3。根据漏洞
,rafstrm.skip(entry.nameLength + localExtraLenOrWhatever); 这句就会跳到file
name (variable size)域中的“.”之后。也就是一个dex文件的开始,这里必须是原
dex文件内容。
c) 修改local file header之后的file data数据。在这里写入带有攻击代码的
classes.dex内容。
d) 以上的修改会带来apk文件一些结构上的调整,比如扩充extra field域,调
整file data大小等。
具体攻击模型,如下图。
安卓安全小分队发现Android新漏洞
5. 总结
总的来说该攻击手段,首先利用了Android在签名验证过程中,对Zip文件相应16位域的
读取时,没有考虑到大于2^15的情况。(因为java的int , short, long都是有符号数
,而不像C/C++里有无符号数)。
其次利用了Zip文件中的local file header结构的extra field域来存放原classes.dex
。但这个域的大小最多只能是2^16-1,因此被攻击的Apk里的classes.dex大小必须在
64K以内。否则,就无法对其进行攻击。这算是这种攻击方式的一个限制。
最后还有一个问题补充说明:之所以这种攻击方式能成功,还在于在运行时,系统抽取
的是hacked classes.dex,而在签名校验时,验证的是extra域里的classes.dex。前者
是在libdex.so中实现,后者在Java层实现。是由Java层跟Native层不一致导致。 |
l*********s 发帖数: 5409 | |
d*****0 发帖数: 68029 | |
p*******m 发帖数: 20761 | |
l**b 发帖数: 457 | |
a****a 发帖数: 3905 | 6 android的问题是google的补丁很难到device,而不是google不patch。
【在 p*******m 的大作中提到】 : http://www.talkandroid.com/168062-new-major-security-threat-for : 补丁已经出来了
|
G*****n 发帖数: 3863 | 7 哈哈。网上老美都在笑安卓小分队的英文名。Android Security Squad, 简称ASS。
这个名字是恶搞取得吧。 |
p*******m 发帖数: 20761 | |
l***k 发帖数: 1153 | |
g*******t 发帖数: 7704 | 10 ms是最喜欢这样的消息,
但不要忘了,windows根本不要什么签名, 一个程序可以直接dll注入windows的系统进
程,
【在 l***k 的大作中提到】 : 现在怎么到处是漏洞啊监听啥的,闹的人心惶惶啊
|
f*****e 发帖数: 5177 | 11 我就奇怪了。DO NO EVIL的狗狗整天跟SB的软软比。
狗狗是不是也要SB了才满意呀?
【在 g*******t 的大作中提到】 : ms是最喜欢这样的消息, : 但不要忘了,windows根本不要什么签名, 一个程序可以直接dll注入windows的系统进 : 程,
|
g*******t 发帖数: 7704 | 12 是白痴用户都习惯windows那么多年不穿衣服, android出个小洞,就叫个不停,是不
是太矫情了,
【在 f*****e 的大作中提到】 : 我就奇怪了。DO NO EVIL的狗狗整天跟SB的软软比。 : 狗狗是不是也要SB了才满意呀?
|
g****r 发帖数: 1589 | 13 windows出个漏洞还不是一样被人骂
【在 g*******t 的大作中提到】 : 是白痴用户都习惯windows那么多年不穿衣服, android出个小洞,就叫个不停,是不 : 是太矫情了,
|