Cuộc gọi hệ thống SELinux và chroot


21

TL; DR: Đây là câu hỏi về bước cuối cùng, trong quy trình root di động, hướng đến nhà phát triển, hoạt động trên tất cả các máy Android. Nó không dựa trên bất kỳ khai thác nào - đó là điều mà chúng tôi được phép hợp pháp và đạo đức để làm, với tư cách là nhà phát triển, cho các máy móc của chính chúng tôi. Nếu tôi nhận được câu trả lời và quản lý để kiểm tra bên trong Debian của mình, tôi sẽ tạo một bài đăng blog ngắn gọn chi tiết tất cả các bước của quy trình này cho tất cả các nhà phát triển đồng nghiệp muốn truy cập root vào máy tính bảng của họ - và không muốn tin vào nguồn gốc đáng ngờ "một lần bấm rễ" mà Chúa biết những gì với máy của họ (thành viên botnet?) ... Sự phụ thuộc duy nhất sẽ là nguồn hạt nhân của máy (mà nhà sản xuất bắt buộc phải cung cấp về mặt pháp lý) và hình ảnh phân vùng khởi động (boot.img), chiếm 99% số lần trong các bản cập nhật qua không trung do nhà sản xuất cung cấp hoặc có thể tải xuống riêng lẻ dưới dạng hình ảnh có thể flash độc lập.

Vì vậy, một tuần trôi qua nơi tôi dành toàn bộ thời gian rảnh cho máy tính bảng Android mới của mình.

Và tôi đã gần như hoàn toàn thành công - trong việc tạo ra một quy trình di động, hướng đến nhà phát triển, để đạt được root trong máy tính bảng Android 5.0.2 của tôi.

Nhưng vẫn còn một điều còn thiếu - tôi không thể thực hiện một chroot (mà tôi cần để chạy debootstrapDebian -ed của tôi !)

Những gì tôi đã làm cho đến nay

  1. Đầu tiên, tôi đã thực hiện một bản vá nhỏ trong các nguồn nhân của máy tính bảng (do nhà sản xuất cung cấp) và sau đó biên dịch kernel của riêng tôi - nơi tôi đã vô hiệu hóa các kiểm tra để thay đổi chế độ thực thi SELINUX . Đặc biệt...

Trong 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. Sau đó tôi đã thay đổi hình ảnh initrd của /default.propmình để chứa: ro.secure=0ro.debuggable=1

  2. Vì nhà sản xuất của tôi initrd.imgđã thiếu nó, tôi cũng đã biên dịch su.ctừ https://android.googlesource.com/pl/sbin/su platform / system / textras / + / master / su / và đặt nhị phân kết quả bên dưới , đảm bảo rằng nó được đặt thành root SUID ( chmod 04755 /sbin/su) .

Sau đó, tôi đã đóng gói kernel mới và initrd mới, như tôi đã giải thích trong Tập 2 của bài viết trước - và khởi động từ hình ảnh của chính tôi:

adb reboot boot-loader ; fastboot boot myboot.img

Vì vậy, bạn là root?

Vâng, ban đầu nó có vẻ thành công:

$ 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

Và tôi đã đạt được root:

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

Tôi chắc chắn 100% tôi là root - không chỉ bởi vì idnói như vậy, mà bởi vì tôi cũng có thể làm những việc mà các quy trình thông thường chắc chắn không thể:

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 và kìa - Cuối cùng tôi cũng có thể đọc các phân vùng thô từ máy tính bảng của mình!

Và SELinux thực sự ở chế độ "xuống, chó":

root@K01E_2:/ # getenforce                                                     
Permissive

Nhưng ... vẫn còn những điều tôi không thể làm:

root@K01E_2:/ # mkdir /my_mnt

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

Đó là, tôi không thể gắn phân vùng EXT4-fs được định dạng thứ 2 của thẻ SD bên ngoài.

Tôi cũng không thể chroot với debootstrapDebian đáng yêu của mình :

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

Có phải vì Selinux?

Tôi không biết - Tôi là người mới (rất mới - một tuần tuổi) với SELinux. Tôi nghĩ rằng khi bạn đặt nó vào chế độ ngủ ( getenforcebáo cáo "Cho phép") thì nó không còn can thiệp ...

Rõ ràng, tôi đã sai. Xuống hố thỏ chúng ta lại đi ...

Có thể là do bối cảnh quá trình của tôi?

Hãy nhớ rằng đã idtrả về ... "uid = 0 (root) gid = 0 (root) ... bối cảnh = u: r: shell: s0 "

Tôi có thể thay đổi bối cảnh đó không? Là gốc và tất cả, tôi có thể di chuyển khỏi shell? Và nếu vậy, di chuyển đến những gì?

Câu trả lời cho câu hỏi đầu tiên là 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

Tốt Nhưng bối cảnh nào sẽ cho phép tôi mountchroot?

Đọc thêm một số thông tin về SELinux, trở lại trong máy chính của tôi, tôi phân tích /sepolicytệp trên thư mục gốc của 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 ...
...

OK, một số khả năng! Đặc biệt là kernelmột điều có vẻ đầy hứa hẹn:

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

Chết tiệt.

Ai là kẻ đang chặn tôi khỏi chrooting?

Mọi lời khuyên đều được chào đón ...

Câu trả lời:


12

Ai là kẻ đang ngăn cản tôi chroot?

Đó không phải là SELinux - đó là một cuộc rượt đuổi ngông cuồng ( getenforcetrả lại "Permissive" có nghĩa là Selinux thực sự không còn trong ảnh nữa).

Thủ phạm - sau khi thêm khá nhiều nguồn printktrong kernel để theo dõi những thất bại của cả hai chrootmount- hóa ra là khả năng . Cụ thể hơn, "bộ giới hạn khả năng" của Android - bạn có thể đọc tất cả về chúng thông qua man( man 7 capabilities) và tôi thú nhận rằng tôi chưa bao giờ bận tâm tìm hiểu về chúng - các tác vụ UNIX hàng ngày của tôi phụ thuộc vào chúng và tôi không biết ... hãy thử điều này trong hộp linux của bạn để xem cho chính mình:

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

Xem? Ping không còn là gốc SUID - nó sử dụng thông tin được lưu trữ trong các thuộc tính mở rộng của hệ thống tệp để biết rằng nó có quyền truy cập vào lớp ổ cắm thô (vì vậy nó có thể thực hiện điều ICMP - ở cấp độ IP).

Dù sao, tôi lạc đề - điểm phẫu thuật trong nhân của tôi, nơi tôi đã dừng "thả khả năng của mình" - theo cách kinh tởm, "hãy để tất cả diễu hành" theo cách này - là: ( 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;
}

Điều này có nghĩa là các khả năng KHÔNG BAO GIỜ bị bỏ - một cấu hình rất an toàn, thực sự :-)

$ 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

Xin chào, Debian ngọt ngào của tôi :-)

Ồ, và "Trình kiểm tra gốc" cũng hoạt động - Tôi đã cắt "su.c", vì vậy mọi người trong máy tính bảng của tôi đều có thể trở thành root:

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;
  //}

Bây giờ nó hoạt động, tôi phải làm cho nó hoạt động đúng - tức là cho phép duy nhất của tôi termuxTerminal Emulatorngười dùng để gọi suchroot, và không để cho tất cả mọi người và bà ngoại của họ trong :-)


Không phải phương thức root này yêu cầu khả năng flash kernel của riêng bạn sao? Và để làm điều đó đòi hỏi một bộ tải khởi động đã mở khóa. Tại thời điểm đó, bạn cũng có thể chỉ cần flash một phục hồi tùy chỉnh và đạt được root theo cách đó.
1110101001

@ 1110101001 Đối với bộ tải khởi động: rõ ràng là có. Đối với phục hồi tùy chỉnh: không có thứ gì như vậy (chưa) cho máy tính bảng của tôi - tôi hiện đang ở vị trí để tạo một cái, mặc dù ;-)
ttsiodras

1
@ 1110101001: Và một điều nữa - bạn nói "khả năng flash" - Tôi chưa flash hình ảnh khởi động của mình vào máy tính bảng, tôi chỉ khởi động từ nó : fastboot boot my.img. Tôi tin rằng cộng đồng rễ gọi đây là một tethered rễ :-) Và dĩ nhiên tôi có thể flash nó - nếu tôi muốn.
ttsiodras
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.