
CVE-2020-0022 BlueFrag Android RCE 취약점의 완전 공개 익스플로잇 (Pixel 3 XL에서 테스트됨)
Insinuator의 훌륭한 블로그 글과 코드에 큰 감사를 드립니다!
insinuator 글에서 언급된 모든 단계와 그 이상을 완료했습니다. 이러한 단계들을 README.md 파일에 모두 담기에는 많으므로, 위에서 언급한 Insinuator의 글을 확인해 보시기 바랍니다.
이 익스플로잇은 다음 지점까지 완전히 완성되었습니다:
이 익스플로잇은 다음과 같은 방식에서 Insinuator의 구현과 다릅니다:
libicuuc.so 대신 libandroid_runtime.so에서 주소를 유출합니다. 이 전화기/타깃에서 더 잘 작동했기 때문입니다execv를 직접 호출하는 체인 하나와 fork 후 execv를 호출하는 체인 하나, 두 개의 예제 JOP 체인이 구현되어 있습니다libandroid_runtime.so 파일을 처리하고 함수와 가젯의 오프셋을 추출하는 사용자 지정 Ghidra 스크립트가 포함되어 있습니다 (다른 타깃으로 익스플로잇을 포팅하기 쉽게 하기 위함)PC를 사용자 지정 주소를 가리키도록 수정하는 익스플로잇을 보여주는 비디오 데모입니다:

체인의 첫 번째 반복은 jop_experiment에서 볼 수 있는 것입니다. 이 체인은 fork를 호출하지 않고 execv를 직접 호출합니다. 커밋 ca28fdf에서 찾을 수 있습니다. 이 체인을 사용할 때 발생하는 일은 다음과 같습니다:

체인의 두 번째 반복은 fork를 호출한 다음 execv를 호출하는 것입니다. 이 체인의 전체 세부 사항은 여기에서 확인할 수 있습니다. 이 체인을 사용할 때 발생하는 일은 다음과 같습니다:

다행히 Pixel 3 XL에는 블루투스 프로세스가 fork 및/또는 execv를 호출하지 못하도록 하는 보호 기능이 있습니다. 지식 공유나 자랑하기 측면에서는 제 작업은 여기까지입니다. 더 발전된 내용을 작성하고 공유한다면 블랙햇들에게 너무 도움이 될 수 있습니다.
저는 이 익스플로잇이 완성된 것으로 간주합니다. 향후 개선 사항은 다음과 같습니다:
dlsym을 호출한 다음 mprotect를 호출하는 JOP 체인 작성이 모든 것들은 이 프로젝트를 재미있는 지식 공유 프로젝트에서 무기화할 수 있는 블랙햇 익스플로잇으로 바꿔 놓습니다. 그래서 제 여정은 지금으로서는 여기서 끝입니다.... 질문이 있으시면 언제든지 연락 주세요.
익스플로잇을 실행하려면 다음을 실행하기만 하면 됩니다:
make build run ARGS="00:00:00:00:00:00"
여기서 00:00:00:00:00:00은 타깃/피해자 기기의 MAC 주소입니다. make clean을 제외한 나머지 빌드 타깃들은 익스플로잇을 수정, 개선 또는 재구현하려는 경우에만 유용하므로 자세히 언급할 필요가 없습니다.
gdbserver 바이너리는 NDK 폴더에서 찾을 수 있습니다# On target
/data/local/tmp/gdbserver 0.0.0.0:1234 --attach $(ps -A | grep -i "com.android.bluetooth" | awk '{print $2}')
# On host
adb forward tcp:1234 tcp:1234
gdb-multiarch -q -x ./gdbinit
# On host
adb push ./gdbinit /data/local/tmp/gdbinit
# On target
su
/data/data/com.termux/files/usr/bin/gdb -q -x /data/local/tmp/gdbinit -p $(ps -A | grep -i "com.android.bluetooth" | awk '{print $2}')
# OR
/data/data/com.termux/files/usr/bin/gdb -q -p $(ps -A | grep -i "com.android.bluetooth" | awk '{print $2}')
작동이 중지된 경우 공격자 머신에서 블루투스 서비스를 다시 시작할 수 있습니다:
sudo systemctl restart bluetooth.service
이 섹션에서는 이 익스플로잇 개발 중 관찰된 몇 가지 현상을 설명합니다:

get_message_loop을 통해 사용되는 base::MessageLoop 객체의 vtable을 수정하는 의도하지 않은 오버플로우로 인해 타깃이 충돌할 가능성을 줄이기 위해 힙 클리너 패킷을 스프레이하고 있습니다:
partial_packets unordered_map의 각 항목에 대해 연결 리스트 항목 하나를 포함하는 32바이트 malloc 청크를 대상으로 하여 패킷의 주소를 유출하고 있습니다. 이는 map_experiment를 통해 알아냈습니다

