美文网首页
[KnowledgePoint]_[PendingIntent]

[KnowledgePoint]_[PendingIntent]

作者: 勤学奋进小郎君 | 来源:发表于2018-08-31 21:17 被阅读0次

[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

相关文章

网友评论

      本文标题:[KnowledgePoint]_[PendingIntent]

      本文链接:https://www.haomeiwen.com/subject/zonswftx.html