android 服务端 漏洞,安卓漏洞 CVE 2017-13287 复现详解-
2018年4月,Android安全公告公布了CVE-2017-13287漏洞。
與同期披露的其他漏洞一起,同屬于框架中Parcelable對象的寫入(序列化)與讀出(反序列化)的不一致所造成的漏洞。
在剛看到谷歌對于漏洞給出的補丁時一頭霧水,
在這里要感謝heeeeen@MS509Team在這個問題上的成果,啟發了我的進一步研究。
原理
谷歌在Android中提供了Parcelable作為高效的序列化實現,用來支持IPC調用中多樣的對象傳遞需求。
但是序列化和反序列化的過程依舊依靠程序員編寫的代碼進行同步。
那么當不同步的時候,漏洞就產生了。
Bundle
傳輸的時候Parcelable對象按照鍵值對的形式存儲在Bundle內,Bundle內部有一個ArrayMap用hash表進行管理。
反序列化過程如下:
/* package */ void unparcel() { synchronized (this) { final Parcel parcelledData = https://www.solves.com.cn/it/cxkf/ydd/Android/2020-02-16/mParcelledData; int N = parcelledData.readInt(); if (N < 0) { return; } ArrayMapmap = mMap; try { parcelledData.readArrayMapInternal(map, N, mClassLoader); } catch (BadParcelableException e) { } finally { mMap = map; parcelledData.recycle(); mParcelledData = null; } } }
首先讀取一個int指示里面有多少對鍵值對。
/* package */ void readArrayMapInternal(ArrayMap outVal, int N, ClassLoader loader) { if (DEBUG_ARRAY_MAP) { RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Log.d(TAG, "Reading " + N + " ArrayMap entries", here); } int startPos; while (N > 0) { if (DEBUG_ARRAY_MAP) startPos = dataPosition(); String key = readString(); Object value = https://www.solves.com.cn/it/cxkf/ydd/Android/2020-02-16/readValue(loader); outVal.Append(key, value); N--; } outVal.validate(); }
之后的每一對先是Key的字符串,然后是對應的Value。
public final Object readValue(ClassLoader loader) { int type = readInt(); switch (type) { case VAL_NULL: return null; case VAL_STRING: return readString(); case VAL_INTEGER: return readInt(); case VAL_MAP: return readHashMap(loader); case VAL_PARCELABLE: return readParcelable(loader); case VAL_SHORT: return (short) readInt(); case VAL_LONG: return readLong();
值內部先是一個int指示值的類型,再存儲實際值。
當Bundle被寫入Parcel時:
void writeToParcelInner(Parcel parcel, int flags) { final ArrayMap map; synchronized (this) { if (mParcelledData != null) { if (mParcelledData =https://www.solves.com.cn/it/cxkf/ydd/Android/2020-02-16/= NoImagePreloadHolder.EMPTY_PARCEL) { parcel.writeInt(0); } else { int length = mParcelledData.dataSize(); parcel.writeInt(length); parcel.writeInt(BUNDLE_MAGIC); parcel.appendFrom(mParcelledData, 0, length); } return; } map = mMap; } }
先寫入Bundle總共的字節數,再寫入魔數,之后是指示鍵值對數的N,還有相應的鍵值對。
LaunchAnyWhere
弄明白Bundle的內部結構后,先來看看漏洞觸發的地方:
這個流程是AppA在請求添加一個帳號:
AppA請求添加一個帳號
System_server接受到請求,找到可以提供帳號服務的AppB,并發起請求
AppB返回了一個Bundle給系統,系統把Bundle轉發給AppA
AccountManagerResponse在AppA的進程空間中調用startActivity(intent)調起一個Activity。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的android 服务端 漏洞,安卓漏洞 CVE 2017-13287 复现详解-的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腰部ct多少钱啊?
- 下一篇: 百度android广告sdk下载,IS_