[KnowledgePoint]_[PendingIntent]_[broadcastAnywhere]

[1]PendingIntent核心:异步激发intent
PendingIntent的理解:延迟执行intent

官方文档:PendingIntent By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the PendingIntent: almost always, for example, the base Intent you supply should have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.
大意:应用A将PendingIntent发送给应用B让应用B以应用A自己的权限和身份执行指定的操作(Intent),即B此时有了越权操作,是A赋予的

  • 根据官方文档的介绍可以想到,当我们拿到PendingIntent,修改了其中的Intent(PendingIntent本质上只是延迟激发intent),就可以用他的权限来开那些未导出的活动、服务、广播

官方文档:intent.fillIn Copy the contents of other in to this object, but only where fields are not defined by this object. For purposes of a field being defined, the following pieces of data in the Intent are considered to be separate fields:
大意:将other的内复制到这个对象中,但是要求这个对象内的字段为空。

  • intent.fillIn方法:
    大部分属性字段 只有原始intent的mAction为空或者设置的flags不为0才可以覆盖,有两个比较特殊mComponent 、mSelector 必须设置标志flags才可以修改,但是一般开发人员不会主动设置。所以出现几种情况:
  1. 双空(mAction、mComponent为空),可以给intent赋值,启动特定组件
  2. 更改可以更改的属性,故意造成数据异常,可以实现拒绝服务等其他行为
    @FillInFlags
    public int fillIn(@NonNull Intent other, @FillInFlags int flags) {
        int changes = 0;
        boolean mayHaveCopiedUris = false;
        if (other.mAction != null                 
                && (mAction == null || (flags&FILL_IN_ACTION) != 0)) {        //只有原始intent的mAction为空或者设置的flags不为0才可以覆盖
            mAction = other.mAction;                                           //other是用来改变原始intent内容的
            changes |= FILL_IN_ACTION;
        }
        if ((other.mData != null || other.mType != null)
                && ((mData == null && mType == null)
                        || (flags&FILL_IN_DATA) != 0)) {
            mData = other.mData;
            mType = other.mType;
            changes |= FILL_IN_DATA;
            mayHaveCopiedUris = true;
        }
        if (other.mCategories != null
                && (mCategories == null || (flags&FILL_IN_CATEGORIES) != 0)) {
            if (other.mCategories != null) {
                mCategories = new ArraySet<String>(other.mCategories);
            }
            changes |= FILL_IN_CATEGORIES;
        }
      .........
        // Selector is special: it can only be set if explicitly allowed, 
        // for the same reason as the component name.
        if (other.mSelector != null && (flags&FILL_IN_SELECTOR) != 0) {
            if (mPackage == null) {
                mSelector = new Intent(other.mSelector);
                mPackage = null;
                changes |= FILL_IN_SELECTOR;
            }
        }
      .........
        // Component is special: it can -only- be set if explicitly allowed,
        // since otherwise the sender could force the intent somewhere the
        // originator didn't intend.
        if (other.mComponent != null && (flags&FILL_IN_COMPONENT) != 0) {
            mComponent = other.mComponent;
            changes |= FILL_IN_COMPONENT;
        }
        return changes;
    }

实例1:android 4.4.2中系统settings->addAccount()存在"双空"PendingIntent的漏洞

我们应该知道的:除了人工点击settings->添加账户来触发addAccount()方法


1.png

settings已经提供了接口让我们,在代码里就可以触发申请添加账户

源码位置:/packages/apps/Settings/src/com/android/settings/accounts/AddAccountSettings.java

178    @Override
179    protected void onSaveInstanceState(Bundle outState) {
180        super.onSaveInstanceState(outState);
181        outState.putBoolean(KEY_ADD_CALLED, mAddAccountCalled);
182        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "saved");
183    }
184
185    private void addAccount(String accountType) {
186        Bundle addAccountOptions = new Bundle();
187        mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(), 0);        //双空PendingIntent出现的地方
188        addAccountOptions.putParcelable(KEY_CALLER_IDENTITY, mPendingIntent);
189        addAccountOptions.putBoolean(EXTRA_HAS_MULTIPLE_USERS, Utils.hasMultipleUsers(this));
190        AccountManager.get(this).addAccount(
191                accountType,
192                null, /* authTokenType */
193                null, /* requiredFeatures */
194                addAccountOptions,
195                null,
196                mCallback,
197                null /* handler */);
198        mAddAccountCalled  = true;
199    }
200}

Questions:

  • 怎么由PendingIntent对象修改intent对象
    [Anwser] intent.fillIn
  • 没有找到AddAccountSettings.java类在哪里定义导出?
    [Anwser] 源码位置:/packages/apps/Settings/AndroidManifest.xml
        <activity android:name="com.android.settings.accounts.AddAccountSettings"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/header_add_an_account"
            android:taskAffinity="com.android.settings"
            android:parentActivityName="Settings$ManageAccountsSettingsActivity">
            <intent-filter>      //有意图过滤intent-filter但是没有android:exported="false"就是默认可以导出
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.settings.ADD_ACCOUNT_SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

[1] https://my.oschina.net/youranhongcha/blog/196933

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 12,140评论 0 10
  • The Inner Game of Tennis W Timothy Gallwey Jonathan Cape ...
    网事_79a3阅读 14,242评论 3 20
  • 想和你去流浪 一路上我俩边走边唱 我会想象 想象你看向我的模样 你也许会问我为什么想要流浪 我说只不过是对自由的向...
    张敬童阅读 2,166评论 0 1
  • 梁 乐 你的生前,是一只笼子 整个家族如一只鸟,在其中 养了五十年。 五十年,提着这鸟笼的手 捏紧又松开。 祖父,...
    梁乐阅读 3,770评论 0 3
  • V1.2017-1-16:首稿 今天初步思考设计了个人信息流管理方案,为什么要这么叫这个名字?以前之初,我把它叫做...
    悖论价投阅读 3,555评论 0 0