SELinux 및 chroot 시스템 호출

SELinux 및 chroot 시스템 호출

핵심요약: 이것은 모든 Android 기기에서 작동하는 이식 가능한 개발자 중심 루팅 프로세스의 마지막 단계에 대한 질문입니다. 이는 착취에 기반한 것이 아닙니다. 이는 개발자로서 우리가 자신의 컴퓨터에 대해 법적, 윤리적으로 허용된 작업입니다. 답변을 얻고 데비안에서 chroot를 관리하면 태블릿에 대한 루트 액세스를 원하고 의심스러운 소스 "One"을 신뢰하고 싶지 않은 모든 개발자를 위해 이 프로세스의 모든 단계를 자세히 설명하는 간결한 블로그 게시물을 게시할 것입니다. keyroot"가 자신의 컴퓨터(봇넷 구성원?)에 어떤 영향을 미치는지, 신은 아시겠지만... 유일한 종속성은 해당 컴퓨터의 커널 소스(제조업체가 법적으로 제공할 의무가 있음)와 부팅 파티션 이미지( boot.img)입니다. 99%의 경우 상황 제조업체에서 제공하는 무선 업데이트에 포함되어 있거나 독립 실행형 플래시 가능 이미지로 별도로 다운로드할 수 있습니다.

일주일이 지났고 나는 새 Android 태블릿 작업에 모든 자유 시간을 보냈습니다.

나는 거의 완전히 성공했습니다. Android 5.0.2 태블릿을 루팅하기 위한 이식 가능한 개발자 중심 프로세스를 만드는 것입니다.

하지만 한 가지 빠졌습니다. chroot를 할 수 없습니다. (저는 debootstrap-ed Debian을 실행해야 합니다!)

내가 지금까지 무엇을 했는지

  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. 그런 다음 다음을 /default.prop포함하도록 initrd 이미지를 변경했습니다 .ro.secure=0ro.debuggable=1

  2. 제조업체 initrd.img에 누락되었으므로 su.c컴파일 도 했습니다.https://android.googlesource.com/platform/system/extras/+/master/su/생성된 바이너리를 아래에 배치합니다 /sbin. SUID 루트( )로 설정되어 있는지 확인하세요 chmod 04755 /sbin/su.

그 후 설명대로 새 커널과 새 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)

그런데 드디어 태블릿에서 원시 파티션을 읽을 수 있게 되었습니다!

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(root) gid=0(root)...컨텍스트=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?

어떤 제안이라도 환영합니다...

답변1

내가 chrooting하는 것을 누가 막고 있습니까?

이것은 SELinux가 아닙니다. 이것은 소름끼치는 추격전입니다( getenforce"Permissive"로 돌아가는 것은 SELinux가 실제로 더 이상 그림에 없다는 것을 의미합니다).

범인은 - 실패를 printk추적하기 위해 커널 소스 코드에 상당한 양을 추가한 후 - 다음과 같은 것으로 밝혀졌습니다.chrootmount능력. 좀 더 구체적으로 말하자면 Android의 "능력 경계 세트"입니다. 이에 대한 모든 내용은 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 루트가 아닙니다. 정보를 사용합니다.파일 시스템의 확장 속성에 저장됨원시 소켓 계층에 대한 액세스 권한이 있음을 알아야 합니다(따라서 ICMP 작업, 즉 IP 수준에서 수행할 수 있음).

어쨌든, 나는 "내 능력을 포기하는 것"을 중단한 내 핵심의 외과적 지점인 - 틀림없이 불쾌한 "모두 행진하도록 놔두는" 방식으로 - 다음과 같이 빗나갔습니다( 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;
  //}

이제 작동했으므로 제대로 작동하도록 해야 합니다. 즉, 모든 사람과 할머니는 포함되지 않고 termux나와 Terminal Emulator사용자만 전화할 수 있도록 su허용 해야 합니다. :-)chroot

관련 정보