闲聊ROOT权限——ROOT权限的前世今生
近期工作一直非常忙。居然慢慢地疏远了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权限的前世今生的更多相关文章
- Atitit godaddy 文件权限 root权限设置
Atitit godaddy 文件权限 root权限设置 1. ubuntu需要先登录,再su切换到root1 2. sudo 授权许可使用的su,也是受限制的su1 3. ubuntu默认吗roo ...
- 恢复 root 本地无权限 Access denied for user 'root'@'localhost' (using password: NO)
调试远程的时候,覆盖了本地的权限.导致 本地无法登陆系统表. 远程连接上mysql 执行以下命令恢复. 恢复root 本地管理权限 使用空密码 grant all on *.* to roo ...
- Linux运维人员共用root帐户权限审计
Linux运维人员共用root帐户权限审计 2016-11-02 运维部落 一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还 ...
- Linux运维人员共用root帐户权限审计(转至马哥Linux运维)
一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还好, 出了问题,就很难找出源头.这里介绍下,如何利用编译bash 使不同的客 ...
- 用户身份切换之初窥企业远程用户没root还有root权限
一直很困扰我,既然企业不让用root不能登录,那怎么操作文件呢? 原来...... su - 用来切换初始变量 $PATH $HOME等 sudo 用的时候会su到root需要root的密码,这 ...
- mysql 开启root外部链接权限
mysql给root开启远程访问权限,修改root密码 1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server ...
- 开通mysql root 用户远程访问权限(转)
基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root的远程访问权限.下面是基本的步骤:1.登录到mysql中,为root进行远程访问的授权,执行下面的命令: mysql> ...
- 【转】mysql给root开启远程访问权限,修改root密码
好记性不如烂笔头,偶然用一直忘.... mysql给root开启远程访问权限,修改root密码 1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1) ...
- 无root或sudo权限,安装mysql
这其实才是真正的linux,恰当使用权限. 网上找到的中文博客,基本上就那么几篇原创,都要编译源码.但89服务器性能太差编译一次大约半小时无法忍受,在本机上创建了standard用户去尝试几篇博客所言 ...
随机推荐
- 重新学习Java——Java基本的程序设计结构(二)
上一节简单回顾了Java基本的一些程序设计的知识,这一节将继续根据<Java核心技术>这本书,进行这方面知识的复习与探索. 1. 字符串 Java字符串实际上就是Unicode字符序列.例 ...
- 继承static的注意点
继承static的注意点 singleton模式会使用 <?php class Auth { protected static $_instance = null; /** * 单用例入口 * ...
- FCC 基础JavaScript 练习1
1.JavaScript中的注释方式有以下两种 // This is an in-line comment. /* This is a multi-line comment */ 2.avaScrip ...
- TypeError: slice indices must be integers or None or have an __index__ method
由于除法/自动产生的类型是浮点型,因此出现上述错误,修正方法为,将/更改为// roi_gray_lwpCV = gray_lwpCV[y:y + h // 2, x:x + w] # 检出人脸区域后 ...
- [转] Redis在windows下安装过程
转载自(http://www.cnblogs.com/M-LittleBird/p/5902850.html) 一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的win ...
- CentOS7上安装稻壳CMS
CentOS7上安装稻壳CMS 1, 安装用途 为了给某公司建设一个小型网站,租用了一个阿里云ECS服务器,最基础的硬件配置,因此选择了CentOS7操作系统. 稻壳CMS(docCMS)源于深喉咙C ...
- 3星|林毅夫《战胜命运》:事实证明华盛顿共识是错误的,GIFF是穷国发展正道。
本书是林毅夫与喀麦隆一位经济学家合著.基本的观点是:事实证明华盛顿共识是错误的,GIFF是穷国发展正道.GIFF的主要思想是政府找到对标国家,强力推行产业政策. 作为一个经济学外行,读后感觉关于华盛顿 ...
- Spring scheduled cron 表达式
一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素. 按顺序依次为 秒(0~59) 分钟(0~59) 小时(0~23) 天(月)(0~31,但是你需要考虑你月的天数) 月(0~11) 天( ...
- HDU_1203_01背包
I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...