SELinux 및 chroot 시스템 호출


21

TL; DR : 이것은 모든 Android 시스템에서 작동하는 이식 가능한 개발자 중심의 루팅 프로세스의 마지막 단계에 대한 질문입니다. 그것은 어떤 익스플로잇을 기반으로하지 않습니다. 개발자로서 우리 자신의 머신에 대해 합법적이고 도덕적으로 허용되는 것입니다. 답변을 얻고 데비안 내부에서 chroot를 관리한다면, 태블릿에 대한 루트 액세스를 원하고 모호한 출처를 신뢰하고 싶지 않은 모든 동료 개발자를 위해이 프로세스의 모든 단계를 자세히 설명하는 간결한 블로그 게시물을 작성합니다. 머신에 대해 신을 알고있는 "원 클릭 루트"(봇넷 구성원?) ... 유일한 의존성은 머신의 커널 소스 (제조자가 법적으로 제공해야하는)와 부트 파티션 이미지 (boot.img)는 제조업체에서 제공 한 OTA (Over-the-Air) 업데이트 내부 시간의 99 %이거나 독립형 플래시 가능 이미지로 개별적으로 다운로드 할 수 있습니다.

그래서 일주일이지나 새로운 자유 시간을 새로운 안드로이드 태블릿에서 보냈습니다.

그리고 나는 안드로이드 5.0.2 태블릿에서 루트를 달성하기 위해 휴대용 개발자 중심 프로세스를 만드는 데 거의 성공했습니다.

그러나 아직 한 가지 빠진 것이 있습니다-나는 chroot를 할 수 없습니다 (내 debootstrap데비안 을 실행해야합니다 !)

내가 지금까지 한 일

  1. 먼저 태블릿의 (제조업체에서 제공 한) 커널 소스에 마이너 패치를 적용한 다음 자체 커널을 컴파일했습니다. 여기서 SELINUX 시행 모드 변경 검사를 비활성화했습니다 . 구체적으로 ...

에서 security/selinux/selinuxfs.c:

...
if (new_value != selinux_enforcing) {
    /* Commented out by ttsiodras.
    length = task_has_security(current, SECURITY__SETENFORCE);
    if (length)
        goto out;
    */
    audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
        "enforcing=%d old_enforcing=%d auid=%u ses=%u",
        new_value, selinux_enforcing,
  1. 그때 나는 내 initrd를 이미지의 변경 /default.prop포함 : ro.secure=0ro.debuggable=1

  2. 제조업체에서 initrd.img누락되었으므로 https://android.googlesource.com/platform/system/extras/+/master/su/su.c 에서 컴파일 하여 결과 바이너리를에 배치 했습니다. SUID 루트 ( )로 설정되어 있는지 확인하십시오. ./sbin/suchmod 04755 /sbin/su

그 후, 나는 이전 포스트의 에피소드 2에서 설명했듯이 새로운 커널과 새로운 initrd를 패키지하고 내 이미지로 부팅했습니다.

adb reboot boot-loader ; fastboot boot myboot.img

그래서 당신은 뿌리입니까?

예, 처음에는 성공한 것으로 보입니다.

$ adb shell

shell@K01E_2:/ $ id

uid=2000(shell) gid=2000(shell) groups=1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),
3003(inet),3006(net_bw_stats) 
context=u:r:shell:s0

shell@K01E_2:/ $ ls -l /sbin/su /sbin/_su
-rwxr-xr-x root     root          131 2015-10-03 10:44 su
-rwsr-xr-x root     root         9420 2015-10-03 01:31 _su

(the _su is the binary I compiled, set to SUID root, and "su" is
 a script I wrote to tell "su" to add me to all these groups...)

shell@K01E_2:/ $ cat /sbin/su

#!/system/bin/sh
export PATH=/system/bin:$PATH
exec /sbin/_su 0,0,1000,1028,2000,2001,1004,1007,1011,1015,\
   1028,3001,3002,3003,3006

그리고 나는 이제 루트를 달성했습니다 :

shell@K01E_2:/ $ su

root@K01E_2:/ # id

uid=0(root) gid=0(root) 
groups=1000(system),1004(input),1007(log),1011(adb),
1015(sdcard_rw),1028(sdcard_r),1028(sdcard_r),2000(shell),2001(cache),
3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) 
context=u:r:shell:s0

나는 100 % 확신합니다. 왜냐하면 id그렇게 말할뿐만 아니라 정상적인 프로세스로는 확실히 할 수없는 일을 할 수 있기 때문입니다.

root@K01E_2:/ # ls -l /dev/block/platform/msm_sdcc.1/by-name/boot
lrwxrwxrwx root root 2015-10-03 10:47 boot -> /dev/block/mmcblk0p16

root@K01E_2:/ # dd if=/dev/block/mmcblk0p16 of=/dev/null bs=1M
16+0 records in
16+0 records out
16777216 bytes transferred in 0.569 secs (29485441 bytes/sec)

Lo와 보라-나는 마침내 타블렛에서 원시 파티션을 읽을 수 있습니다!

그리고 SELinux는 실제로 "down, dog"모드에 있습니다 :

root@K01E_2:/ # getenforce                                                     
Permissive

그러나 ... 여전히 할 수없는 일이 있습니다.

root@K01E_2:/ # mkdir /my_mnt

root@K01E_2:/ # mount -t ext4 /dev/block/mmcblk1p2 /my_mnt
mount: Operation not permitted

즉, 외부 SD 카드의 EXT4-fs 형식의 두 번째 파티션을 마운트 할 수 없습니다.

나는 또한 내 사랑스러운 debootstrap데비안에 뿌리를 내릴 수 없습니다 .

root@K01E_2:/ # chroot /data/debian/ /bin/bash                             
chroot() fail
Operation not permitted

SELinux 때문입니까?

모르겠다-나는 SELinux를 처음 접했다. 나는 당신이 그것을 잠들게 할 때 ( getenforce"허용"보고) 더 이상 방해하지 않는다고 생각했습니다 ...

분명히, 나는 틀렸다. 토끼 구멍 아래로 다시갑니다 ...

내 프로세스 컨텍스트 때문일 수 있습니까?

그 기억 id반환 ... "UID = 0 (루트) GID = 0 (루트) ... 컨텍스트 = U : R : 쉘 : S0 "

그 상황을 바꿀 수 있습니까? 근본이기 때문에 멀리 갈 수 shell있습니까? 그렇다면 무엇으로 이동합니까?

첫 번째 질문에 대한 답은 runcon다음과 같습니다.

shell@K01E_2:/ $ runcon u:r:debuggerd:s0 /sbin/su

root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:debuggerd:s0

좋은. 그러나 상황은 나에게 수 mount와에게 chroot?

SELinux에 대한 자세한 내용을 메인 컴퓨터에서 다시 읽으면 /sepolicy파일의 루트를 파싱 합니다 initrd.img.

linuxbox$ $ sesearch -A sepolicy | grep chroot
allow init_shell init_shell : capability { chown sys_chroot ...
allow init init : capability { chown dac_read_search sys_chroot ...
allow kernel kernel : capability { chown dac_override sys_chroot ... 
allow asus-dbug-d asus-dbug-d : capability { chown sys_chroot ...
...

여러 가지 가능성이 있습니다! 특히 그 kernel중 하나는 유망한 것 같습니다.

shell@K01E_2:/ $ runcon u:r:kernel:s0 /sbin/su

root@K01E_2:/ # id
uid=0(root) gid=0(root)... context=u:r:kernel:s0

root@K01E_2:/ # chroot /data/debian/ /bin/bash                             
chroot() fail
Operation not permitted

꿰매다.

도대체 누가 나를 노래하지 못하게 chroot합니까?

모든 조언을 가장 환영합니다 ...

답변:


12

도대체 누가 나를 chrooting에서 차단하고 있습니까?

그것은 SELinux가 아니 었습니다-그것은 거위 추적이었습니다 ( getenforce"Permissive"를 반환하면 SELinux가 더 이상 그림에 없다는 것을 의미합니다).

범인 -의 꽤 번호를 추가 한 후 printk커널의 소스는 모두의 실패를 추적하는 chroot과를 mount-로 밝혀졌다 기능 . 더 구체적으로 말하면, 안드로이드의 "기능 범위 설정"- man( man 7 capabilities)을 통해 그들에 관한 모든 것을 읽을 수 있고 나는 결코 그들을 귀찮게 한 적이 없다고 고백합니다-일상적인 UNIX 작업은 그들에 달려 있었고 전혀 몰랐습니다 ... 리눅스 박스는 당신을 위해 볼 수 있습니다 :

$ getfattr -d -m - /sbin/ping
getfattr: Removing leading '/' from absolute path names
# file: sbin/ping
security.capability=0s......

만나다? Ping은 더 이상 SUID 루트가 아닙니다 . 파일 시스템의 확장 된 속성저장된 정보를 사용 하여 원시 소켓 계층에 액세스 할 수 있음을 알 수 있습니다 (따라서 IPMP 수준에서 ICMP 작업을 수행 할 수 있음).

어쨌든, 나는 "내 능력 세트를 떨어 뜨린"커널의 수술 지점을 틀어 놓았다. 논란의 여지가 있지만, "모두 행진하게한다"는 방식은 다음과 security/commoncap.c같다.

static long cap_prctl_drop(struct cred *new, unsigned long cap)
{
    if (!capable(CAP_SETPCAP))
        return -EPERM;
    if (!cap_valid(cap))
        return -EINVAL;

    // ttsiodras: come in, everyone, the water's fine!
    //cap_lower(new->cap_bset, cap);
    return 0;
}

이것은 기능이 절대로 삭제되지 않음을 의미합니다-실제로 매우 안전한 구성 :-)

$ adb shell

shell@K01E_2:/ $ su

root@K01E_2:/ # chroot /data/debian/ /bin/bash

root@localhost:/# export PATH=/bin:/sbin:/usr/bin:/usr/sbin:\
     /usr/local/bin:$PATH

root@localhost:/# cat /etc/issue
Debian GNU/Linux 8 \n \l

안녕 내 달콤한 데비안 :-)

아, 그리고 "루트 검사기"도 작동합니다. "su.c"를 빼면 태블릿의 모든 사람이 루트가 될 수 있습니다.

int main(int argc, char **argv)
{
  struct passwd *pw;
  uid_t uid, myuid;
  gid_t gid, gids[50];

  /* Until we have something better, only root and shell can use su. */
  myuid = getuid();
  //
  // ttsiodras - Oh no, you don't :-)
  //
  //if (myuid != AID_ROOT && myuid != AID_SHELL) {
  //    fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
  //    return 1;
  //}

이제 작동하는지, 나는 그것이 제대로 작동해야합니다 - 즉, 단지 내 수 termuxTerminal Emulator사용자가 호출 su하고 chroot있는 모든 사람과 그들의 할머니를 보자, 그리고 :-)


이 루트 메소드에는 커널을 플래시하는 기능이 필요하지 않습니까? 이를 위해서는 잠금 해제 된 부트 로더가 필요합니다. 어느 시점에서 사용자 지정 복구를 플래시하고 그런 식으로 루트를 얻을 수 있습니다.
1110101001

@ 1110101001 부트 로더의 경우 : 예. 맞춤 복구의 경우 : 태블릿에는 아직 그런 것이 없습니다.하지만 지금은 태블릿을 만들 수있는 위치에 있습니다. ;-)
ttsiodras

1
@ 1110101001 : 그리고 한가지 더 – 당신은 "플래시 능력"이라고-부팅 이미지를 태블릿에 플래시하지 않았습니다, 나는 단지 그것으로 부팅하고 있습니다 : fastboot boot my.img. 나는 루팅 커뮤니티가 이것을 테 더링 루팅 이라고 믿습니다 .
ttsiodras
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.