SELinux और Chroot सिस्टम कॉल


21

टी एल; DR: यह एक पोर्टेबल, डेवलपर-उन्मुख रूटिंग प्रक्रिया में अंतिम चरण के बारे में एक प्रश्न है, जो सभी एंड्रॉइड मशीनों पर काम करता है। यह किसी भी शोषण पर आधारित नहीं है - यह कुछ ऐसा है जिसे हम कानूनी रूप से और नैतिक रूप से डेवलपर्स के रूप में, अपनी मशीनों के लिए अनुमति देते हैं। यदि मुझे उत्तर मिलता है और अपने डेबियन के अंदर चेरोट करने का प्रबंधन करता है, तो मैं एक संक्षिप्त ब्लॉग पोस्ट बनाऊंगा, जो इस प्रक्रिया के सभी चरणों का विस्तार उन सभी साथी डेवलपर्स के लिए करेगा, जो अपने टेबलेट पर रूट एक्सेस चाहते हैं - और संदिग्ध-मूल पर भरोसा नहीं करना चाहते हैं "वन-क्लिक-रूट्स" जो ईश्वर को जानता है-उनकी मशीनों (बॉटनेट मेंबर्स?) को क्या करना है ... एकमात्र निर्भरता मशीन के कर्नेल स्रोत होंगे (जो निर्माता कानूनी रूप से प्रदान करने के लिए बाध्य हैं) और बूट पार्टीशन इमेज (boot.img), जो निर्माता द्वारा प्रदान किए गए ओवर-द-एयर अपडेट्स के अंदर 99% है, या स्टैंडअलोन फ्लैश-सक्षम छवि के रूप में व्यक्तिगत रूप से डाउनलोड करने योग्य है।

इसलिए, एक सप्ताह बीत गया जहाँ मैंने अपना सारा खाली समय अपने नए एंड्रॉइड टैबलेट पर बिताया।

और मैं अपने एंड्रॉइड 5.0.2 टैबलेट में रूट प्राप्त करने के लिए एक पोर्टेबल, डेवलपर-उन्मुख प्रक्रिया बनाने में लगभग पूरी तरह से सफल रहा हूं।

लेकिन अभी तक एक बात याद आ रही है - मैं चेरोट नहीं कर सकता (जो मुझे अपने-अपने 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=0औरro.debuggable=1

  2. जब से मेरे निर्माता initrd.imgइसे याद कर रहे थे, मैंने भी https://android.googlesource.com/platform/system/extras/+/master/su/su.c से संकलित किया और परिणामी बाइनरी के तहत रखा , जिससे यह सुनिश्चित हो गया कि यह SUID रूट ( ) पर सेट है ।/sbin/suchmod 04755 /sbin/su

उसके बाद, मैंने नई कर्नेल और नई initrd को पैक किया, जैसा कि मैंने अपनी पिछली पोस्ट के एपिसोड 2 में समझाया था - और अपनी खुद की छवि से बूट किया गया था:

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 वास्तव में "डाउन, डॉग" मोड में है:

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

यही है, मैं अपने 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: shell: h0 "

क्या मैं उस संदर्भ को बदल सकता हूं? जड़ और सब होने के नाते, क्या मैं इससे दूर जा सकता हूं 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

कौन बिल्ली मुझे काट रही है?

यह SELinux नहीं था - यह एक जंगली हंस पीछा था ( getenforce"अनुमति" लौटने का मतलब है कि SELinux वास्तव में अब तस्वीर में नहीं है)।

अपराधी - printkकर्नेल के स्रोत में काफी संख्या में जोड़ने के बाद दोनों की विफलताओं का पता लगाने के लिए chrootऔर mount- क्षमताएँ निकला । अधिक विशेष रूप से, एंड्रॉइड की "क्षमता बाउंडिंग सेट" - आप अपने man( man 7 capabilities) के माध्यम से उन सभी के बारे में पढ़ सकते हैं ( और मुझे लगता है कि मैंने उन्हें देखने से पहले कभी परेशान नहीं किया है - मेरे रोजमर्रा के यूनिक्स कार्य उन पर निर्भर थे और मुझे पता नहीं था ... इस में कोशिश करें अपने आप को देखने के लिए अपने बॉक्स बॉक्स:

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

देख? पिंग अब 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, और सभी को और उनकी दादी को :-) में जाने न दें


क्या इस रूट विधि में अपने स्वयं के गिरी को चमकाने की क्षमता की आवश्यकता नहीं है? और ऐसा करने के लिए एक अनलॉक किए गए बूटलोडर की आवश्यकता होती है। जिस बिंदु पर आप बस एक कस्टम रिकवरी फ्लैश कर सकते हैं और उस तरह से रूट प्राप्त कर सकते हैं।
1110101001

@ 1110101001 बूटलोडर के लिए: जाहिर है, हाँ। कस्टम पुनर्प्राप्ति के लिए: मेरे टेबलेट के लिए ऐसी कोई चीज (अभी तक) नहीं है - मैं अभी एक स्थिति में हूं, हालांकि ;-)
ttsiodras

1
@ 1110101001: और एक और बात - तुमने कहा "फ्लैश करने की क्षमता" - मैं गोली करने के लिए अपने बूट छवि फ्लैश नहीं है, मैं सिर्फ यह से बूट कर रहा हूँ: fastboot boot my.img। मेरा मानना ​​है कि रूटिंग समुदाय इसे एक टेथर्ड रूटिंग कहता है :-) और निश्चित रूप से मैं इसे फ्लैश कर सकता था - अगर मैं चाहता था।
ttsiodras
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.