近期工作一直非常忙。居然慢慢地疏远了CSDN的博客,然而在工作中遇到问题,又会被多次的引导至CSDN,故笔者抽出时间也将自己学习的成果与大家分享在这里,希望能帮助到须要帮助的人。

本文将从几个方面,由浅至深地讲述ROOT究竟是什么东西?

一. ROOT权限简介

二.为什么须要ROOT

三. ADBD的ROOT权限

四.深入源码

ROOT权限简单介绍:

ROOT权限是Linux内核中的最高权限,假设你的身份是ROOT。那么你就具有了ROOT权限。

有了最高权限。你就能够为所欲为,换句话说,假设恶意程序获取到了ROOT权限,那么就能够肆意地破坏你的手机。获取的隐私...所以厂商一般在生产手机的时候,不会提供给用户ROOT权限。官方宣称是为了保护用户手机的安全。然后装了一堆开机自己主动启动。而用户这辈子也用不到也卸载不了垃圾软件(相信使用安卓的同学们都懂我的意思),而苹果所说的越狱,也就是获取ROOT权限。

为什么须要获取ROOT权限?

苹果用户获取ROOT权限。是为了能够免费安装各种软件。以及为了获取更加灵活的操作体验,苹果不会安装一堆恶心的软件;而安卓普通用户获取ROOT权限,最大的目的就是为了卸载这些恶心的自带软件,安卓极客用户则是为了各种折腾安卓手机,安卓开发者是为了得到日志文件,分析BUG。

ADBD的ROOT权限:

ADBD是什么?相信大家都看过。IT男把手机连上电脑,然后不知怎么的弹出一个黑乎乎的窗体,上面有一排排白色的英文字母,然后帅气的敲击着键盘(一般敲击 adb shell,然后进入手机),啪啪几下,能够帮你解决一些手机的问题。这个能够和手机交互的进程就是ADBD。

这就好比,你去朋友家玩,然后你朋友家比較高端,进大门之前有个可视对讲机。那么你首先通过对讲机呼叫朋友(敲击adb
shell),看看在不在家(手机是否对应adb shell这个命令)。假设朋友在家。那么就会通过对讲机为你开门(成功进入手机中)。提供这个服务的可视对讲机就相当于ADBD。

说白了,ADBD就是能够为你提供一种进入手机内部的服务通道。

那么为什么须要ADBD具有ROOT权限?这就涉及到还有一个与ROOT息息相关的东西——su。

我们开机之后,使用手机的身份就是一个普通用户(user),假设运行su,那么就能够直接切换到ROOT身份。就像仙剑奇侠传三里面的景天,是个凡人,法力有限,可是大家都知道。他的前世是飞蓬将军,法力高强。天界无人能敌,仅仅有魔界至尊重楼能够与他一较高下。当他们来到天庭的时候,玉帝施法,让景天直接切换成飞蓬将军,于是他就有了飞蓬将军的记忆和法力,与重楼重新大战。su就是这样一个奇妙的命令。

高通平台上,su的相关代码位于: LINUX/android/system/extras/su/su.c中

事实上我们所说的越狱或者ROOT。就是把su安装到手机里面 /system/bin文件夹下,并把它的权限设置为4755,那么某些程序须要ROOT权限的时候,就能够通过su切换到ROOT身份,然后去运行。因此一般被ROOT的手机都会安装一个“超级用户”这种应用,就是用于管理哪些软件能够切换到ROOT身份,哪些不能够。保证用户安全。这个想法是非常好非常天真。对于正规的软件,人家依照你的路子来,不正规的软件。你一个小小的超级用户的应用,岂能挡我获取ROOT,虐不死你。

那么为什么须要ADBD获取ROOT权限呢?经过上面的解说大家应该能猜到,假设ADBD有ROOT权限。就能够通过adb 工具。为所欲为。而又不留下痕迹(不安装su),能够删除自带垃圾软件,获取随意文件夹的文件。安全性较高。笔者就是通过这样的方式获取一些系统级别文件。

深入代码:

看了上面的文字,或许非常多人会有这种想法,原来ROOT一个手机这么简单?错!

一点也不简单。

首先:/system分区是仅仅读的文件系统,即你无法往system分区中写入不论什么东西,其次就算你侥幸把su安装到/system/bin下,你也没法改动它的权限为4755,再者,即使你侥幸把su的权限设为4755,你也逃只是有些手机的反root机制(即检測到有文件的权限为4755。就删除)。

首先我们来看看su的部分代码:

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

这句话告诉我们。假设运行su的不是ROOT或者SHELL用户,那就直接退出。说明切换身份时候,你必须是这两个用户。还好我们用adb shell进入。是SHELL用户,好险啊。

if(argc < 2) {
uid = gid = 0;
} else {
int gids_count = sizeof(gids)/sizeof(gids[0]);
extract_uidgids(argv[1], &uid, &gid, gids, &gids_count);
if(gids_count) {
if(setgroups(gids_count, gids)) {
fprintf(stderr, "su: failed to set groups\n");
return 1;
}
}
}

推断运行su的时候,有没有其他參数,我们仅仅是运行su,即argc < 2成立。su也能够切换成其他用户(argc > 2,具体看su命令的使用),这时候。uid 和 gid 都被设置为0 。即ROOT用户的ID号和组号

if(setgid(gid) || setuid(uid)) {
fprintf(stderr,"su: permission denied\n");
return 1;
}

来了来了。就是它,这就是我们终于的目的,把我变身成飞蓬将军,假设一切顺利。你就能够变身成功了(切换ROOT成功)

/* Default exec shell. */
execlp("/system/bin/sh", "sh", NULL);

每次su之后,就会变成root#,然后就能够通过控制台继续敲命令,可是不同的是,你已经是ROOT了,权限已经非常大了。

Android系统启动的时候,ADBD是ROOT权限,仅仅是后来被降级了,推断是否降级的函数是should_drop_privileges()这个函数:

static int should_drop_privileges() {
#ifndef ALLOW_ADBD_ROOT
return 1;
#else /* ALLOW_ADBD_ROOT */

首先推断是否定义了ALLOW_ADBD_ROOT,假设系统都不同意你ROOT。就直接返回1,以下什么都不看了,就像找工作的时候,无论你多么厉害,假设你第一条要求都不符合,就直接把你pass了,说什么都没用,够狠的。

    int secure = 0;
char value[PROPERTY_VALUE_MAX]; /* run adbd in secure mode if ro.secure is set and
** we are not in the emulator
*/
property_get("ro.kernel.qemu", value, "");
if (strcmp(value, "1") != 0) {
property_get("ro.secure", value, "1");
if (strcmp(value, "1") == 0) {
// don't run as root if ro.secure is set...
secure = 1;

以下就是获取系统的属性。推断是否打开ROOT权限,能够看到假设ro.kernel.qumu 这个属性被置为了。没关系再给你一次机会,推断ro.secure是否也是1。假设是。对不起你无法获得root权限。我要把secure置为1了(secure为1意味着要降级,后面会解说)。接着:

           // ... except we allow running as root in userdebug builds if the
// service.adb.root property has been set by the "adb root" command
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") == 0) {
property_get("service.adb.root", value, "");
if (strcmp(value, "1") == 0) {
secure = 0;
}
}
}
}

哈哈,又给了你一次机会,我再来推断ro.debuggable是不是1,假设不是。对不起,我必需要降级,否则再给你一次机会。推断service.adb.root这个属性的值,假设也是1,那么就不降级,一般在编译ROM版本号的时候,会同事编译两个版本号。一个是project版本号,是具有ROOT权限的ADBD。这样方便开发人员调试系统,还有一个就是我们用户用的版本号,叫user版本号,这个是没有ROOT权限的,能够看到,就是通过property_get一系列属性来推断是否降级。

    return secure;
#endif /* ALLOW_ADBD_ROOT */
}

最后,返回secure就可以。能够看到最后决定是否降级的变量就是secure,全部假设有源码的话。仅仅有最后将secure赋值为0。无论什么版本号。最后都是ROOT权限。

if (should_drop_privileges()) {
drop_capabilities_bounding_set_if_needed(); gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET,
AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
AID_NET_BW_STATS };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
exit(1); /* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {<span style="white-space:pre"> </span>//以前的漏洞。被封住了
exit(1);
}
if (setuid(AID_SHELL) != 0) {<span style="white-space:pre"> </span>//以前的漏洞
exit(1);
} D("Local port disabled\n");
}

从这段代码能够看到。假设should_drop_privileges返回1,那么就能够降级了。降级函数为setgid(AID_SHELL)和setuid(AID_SHELL)。以前有黑客利用一些方法。使得setgid和setuid运行失败,即降级失败,以前的代码中是没有exit的,那么当setuid和setgid运行失败之后。就不会降级。

ROOT不是那么轻易的。如今有非常多已知的漏洞,可是都被封锁了,全部不是每一个root工具都能root成功的。要看它採用的是什么方法来ROOT。

闲聊ROOT权限——ROOT权限的前世今生的更多相关文章

  1. Atitit  godaddy 文件权限 root权限设置

    Atitit  godaddy 文件权限 root权限设置 1. ubuntu需要先登录,再su切换到root1 2. sudo 授权许可使用的su,也是受限制的su1 3. ubuntu默认吗roo ...

  2. 恢复 root 本地无权限 Access denied for user 'root'@'localhost' (using password: NO)

    调试远程的时候,覆盖了本地的权限.导致  本地无法登陆系统表.  远程连接上mysql  执行以下命令恢复. 恢复root  本地管理权限  使用空密码 grant all on *.* to roo ...

  3. Linux运维人员共用root帐户权限审计

    Linux运维人员共用root帐户权限审计 2016-11-02 运维部落 一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还 ...

  4. Linux运维人员共用root帐户权限审计(转至马哥Linux运维)

    一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还好, 出了问题,就很难找出源头.这里介绍下,如何利用编译bash 使不同的客 ...

  5. 用户身份切换之初窥企业远程用户没root还有root权限

    一直很困扰我,既然企业不让用root不能登录,那怎么操作文件呢? 原来...... su -    用来切换初始变量 $PATH $HOME等 sudo 用的时候会su到root需要root的密码,这 ...

  6. mysql 开启root外部链接权限

    mysql给root开启远程访问权限,修改root密码 1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server ...

  7. 开通mysql root 用户远程访问权限(转)

    基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root的远程访问权限.下面是基本的步骤:1.登录到mysql中,为root进行远程访问的授权,执行下面的命令: mysql> ...

  8. 【转】mysql给root开启远程访问权限,修改root密码

    好记性不如烂笔头,偶然用一直忘.... mysql给root开启远程访问权限,修改root密码   1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1) ...

  9. 无root或sudo权限,安装mysql

    这其实才是真正的linux,恰当使用权限. 网上找到的中文博客,基本上就那么几篇原创,都要编译源码.但89服务器性能太差编译一次大约半小时无法忍受,在本机上创建了standard用户去尝试几篇博客所言 ...

随机推荐

  1. PHP开发心得一

    1,php获得服务器时间 $time= date('Y-m-d H:i'); echo $time; 一般写法如上,但发现打印出来的时间小时数总数不对,和机器的时间差几个小时.查资料发现,要设定时区. ...

  2. Vue.js——router-link阻止click事件

    router-link 只能单纯做路由跳转 https://segmentfault.com/q/1010000007896386

  3. JDBC配置MSSQL

    使用JDBC连接SQL SERVER 这可能是个很老套的话题,但不管怎么说还是有用的.姑且把配置方法贴出来吧.1. 确认Sql Server的的运行状态打开Sql Server配置管理器,确认Sql ...

  4. block相关归纳

    经过今天的Block的学习.上网查询相关文章归纳了一下 一.一个使用Block的好处有: Block可以用在许多不同的环境中,这样可以让代码更加简单,以及减少函数声明的数量,不用实现代理协议. 简单性 ...

  5. JQuery 的toggle() 方法如何使用?

    JQuery中的toggle()方法,相当于点一个元素时,重复循环两个函数,而这两个函数可以作为toggle()函数的两个参数传进去,当第一次点击的时候会执行前面的参数,而第二次点击时执行的是后面的参 ...

  6. (2) GoJS Node简介

    node GoJS提供了非常简单的创建Node节点的方法,可将文本内容.结点形状.背景颜色.边距等属性通过数据绑定[go.Binding]直接绑定到对应的Node数据中. 本文简单介绍Node的创建过 ...

  7. <MySQL>入门五 视图

    -- 视图 /* 含义:虚拟表,和普通的表一样使用 mysql5.1版本的新特性,是通过表动态生成的数据,只保存了sql的逻辑,不保存查询的结果 应用场景: - 多个地方用到同样的查询结果 - 该查询 ...

  8. 微信小程序支付全问题解决

    这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发. * 注作者使用的PHP,不过支付流程都是这样 开发前必读 主要流程 小程序前端发送求参请求 接受请求封装 "统一下单 ...

  9. airfoil polar data during post stall stages (high AOA)

    airfoil polar data during post stall stages (high AOA) Table of Contents 1. airfoil polar during pos ...

  10. 【Codeforces 977F】Consecutive Subsequence

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 设f[i]表示i作为序列的最后一个数字,最长的连续序列的长度. 用f[i]和f[i-1]+1来转移即可 [代码] import java.io ...