作者:Kevin
链接:https://www.zhihu.com/question/21074979/answer/18176410
来源:知乎
著作权归作者所有,转载请联系作者获得授权。

Android的内核就是Linux,所以Android获取root其实和Linux获取root权限是一回事儿。
你想在Linux下获取root权限的时候就是执行sudo或者su,接下来系统会提示你输入root用户的密码,密码正确就获得root权限了。Android本身就不想让你获得Root权限,大部分手机出厂的时候根本就没有su这个程序。所以你想获得Android的root权限,第一步就是要把编译好的su文件拷贝到Android手机的/system/bin或者/system/xbin/目录下。我们先假设你可以把su放在xbin下,接下来你可以在Android手机的adb shell或者串口下输入su了。
Linux下su以后输入密码就可以root了,但Android里的su和Linux里的su是不一样的,Android里的su不是靠验证密码的,而是看你原来的权限是什么。意思就是如果你是root,那你可以通过su切换到别的用户,比如说shell,wifi,audio什么的。但如果你是root之外的其他用户,就不能切换回root了,会提示你permission denied。(具体su是怎么做到这一点的,我准备过几天有时间的时候写在下面,单独说明
也就说用root运行su才有用,但我这个时候还没有root怎么办呢?这就涉及到另外个问题。
一般我们在Linux的console下输入 ls -l 会列出所有文件的权限。
比如:-rwxr-xr-x,用过Linux的人都知道r代表该文件可读,w代表可写,x代表可执行,-就代表没有该权限。第一个rwx代表文件所有者的权限,第二个rwx代表和所有者同组人的权限,第三个rwx代表其他用户对该文件的权限。但下面这个文件就比较特殊。
rws,它的执行权限标志位是一个s,s代表当任何一个用户执行该文件的时候都拥有文件所有者的权限,这文件的所有者是root,简单点说就是不管谁执行这个文件,他执行的时候都是以root身份执行的。rws,它的执行权限标志位是一个s,s代表当任何一个用户执行该文件的时候都拥有文件所有者的权限,这文件的所有者是root,简单点说就是不管谁执行这个文件,他执行的时候都是以root身份执行的。
也就说即使我不是root也有可能以root身份来执行程序,那么我就把一个所有者是root的su程序权限标志位置成-rwsr-xr-x,那么不管谁执行它,都是root身份执行,su就可以顺利执行成功了,执行成功之后我就是root身份了。

问题都清楚了,就是你需要把一个所有者是root的su拷贝到Android手机上,并且把su的权限标志位置成-rwsr-xr-x。能把这个事情搞定你就成功root了一个手机。
大概意思就是两行代码
cp /data/tmp/su /system/bin/ #copy su 到/system/分区
chown root:root su #su的所有者置成root
chmod 4775 /system/bin/su #把su置成-rwsr-xr-x
熟悉Android的同学都知道,执行上面的每一行代码都需要root权限才能成功。
意思就是说,你只有有root权限的情况下才能执行上面两行代码,而这两行代码就是为了让你获得root权限的,这是一个逻辑闭环,那么如何打破这个逻辑闭环呢?
一个办法就是找一个本身已经有root权限的进程来启动我上面的两行代码,那我这两行代码一启动就是root权限,就可以顺利执行了。但是已经有root权限的进程都是出厂时候就装到手机上的,代码写死了,你没法控制它执行你自己的代码啊。这个时候就需要你找漏洞了,比如用来破解Android2.3 root权限的zergRush漏洞就是利用一个拥有root权限的进程栈溢出漏洞。
/*
* 栈溢出说白了就是这个进程读到了自有内存之外的地址空间,这段内存空间没分配给它,谁都能写
* 这段内存,那我就可以把自己的两行代码预先写到这里,运行zergRush代码,然后等那个倒霉的进
* 程执行我就行了。
*/
栈溢出这段也解释错了,关于栈溢出的解释大家可以看答案下面@张炬 的评论。上面有下划线的部分可以忽略。

如果各位有一定基础,能看懂我上面讲的,就基本知道原理其实并不难,难点在于找到漏洞。
zergRush的代码在这儿:
revolutionary/zergRush · GitHub
有兴趣的可以看看,网上也有很多分析文章。

另外iphone的越狱其实和Android的root是一回事儿,都是越权操作。所以越狱的方式也都差不多,也是找IOS自带程序的漏洞,只不过IOS安全性强一点,所以也比较难找。如果你发现你的iphone的某个自带程序经过一些特定操作会出现系统崩溃重启的现象,并且是可以复现的,那就很有可能可以用来越狱了。
好像是IOS6出来的时候,由于比较难搞,某个越狱团队就号召大家来找茬,发现的漏洞可以报告给他们用来越狱。说明IOS越狱越来越难。直接体现就是现在越狱需要的时间越来越长。
不过如果你发现漏洞也可以报告给苹果,苹果会根据漏洞严重程度给予一定奖励。我记得看新闻说南非一个家伙靠给苹果找漏洞赚25万美元。发家致富的好路子啊,哈哈。

================================================
谢谢各位支持
关于为什么su一定要放到/system/bin/或者/system/xbin/
一个同事告诉我,这个问题我的解释是错的,su不能放在data分区原因是因为data分区在mount时就指定了不能给可执行程序加s位。你在adb shell里执行mount就可以看到,或者看我下面的截图。
下面有下划线的部分是我自己的解释,各位可以忽略。下面有下划线的部分是我自己的解释,各位可以忽略。
/*
* 首先,你当然可以把su这个程序copy到/data/分区,但你adb push进去的时候,su有这个程序的所
* 有者肯定不是root,一般是shell什么的(记不清了,应该是和adbd这个进程的所有者一样),这个时
* 候即使你把它权限置为-rwsr-xr-x,哪你运行它的时候也是shell身份运行的,su会提示你输入密码
* 的。
* 第二我们root手机的目的是为了运行需要root权限的APP,比如goagent或者什么的。这些APP里代
* 码需要获得root的时候是这么写的:
* Process p = Runtime.getRuntime().exec("su");
* 也就是它们在代码里调用了一下su这个程序,哪可以写成下面这个样子吗?
* Process p = Runtime.getRuntime().exec("./data/tmp/su");
* 我没写过APP,不太清楚,估计是不行的。换句话说你必须把su放到环境变量PATH所有的目录
* 里,APP才能调用到它。如果你不想放到bin或者xbin下,你就必须给PATH增加一个目录。PATH是
* root权限才能修改的,你如果能修改PATH,说明你已经有root权限了,修改PATH就没必要了,还
* 不如直接放到bin下面。
*/

关于sudo
android的工程里没有sudo这个东西。sudo是为了给普通用户临时分配root权限的,Android里建立了很多用户,比如wifi,shell等等,这些用户可以访问那个文件,不可以访问那个文件,代码里已经写死了,权限也分配的很分明。它们在运行的过程中不需要临时获得root权限。所以Android不需要sudo这个程序。

回复@吴利文
1. Android的su确实是不验证密码的,是我想当然了。答案已经修改了。
2. chmod 1755也是我错了,应该是4755,答案已经改了。
3. 你的答案我看了,你没发觉你跟我说的是一回事吗?我觉得你应该是没仔细看我的答案吧。
4. 你叙述的 so call"一般的root流程",只是一种方法,而这个问题是问原理。实际上不管你用什么漏洞获得了root,下面需要做的一样的,都是copy su到xbin, chown最后chmod。你的“一般的root流程”和别人不管用什么方法的二般流程有什么区别吗?不都是为了刚上面这些事吗?

/* ChangeLog
* 08/13/2013
* 修改栈溢出的解释错误
* 修改为什么su一定要放到/system/bin/或者/system/xbin/的解释错误
* 08/16/2013
* 修改chmod错误
* 修改运行su需要密码的错误
* 回复somebody

Android 的提权 (Root) 原理是什么?的更多相关文章

  1. Android 的提权(root)原理【转】

    Android的内核就是Linux,所以Android获取root其实和Linux获取root权限是一回事儿. su还需要所有者(Owner)是root才能正确的给其他程序赋予root权限.linux ...

  2. android ioctl fuzz,android 本地提权漏洞 android root

    目前正在研究android 三方设备驱动 fuzzer , 也就是下图所说的 ioctl fuzzing, 下图是由keen team nforest 大神发布: 欢迎正在研究此方面的人联系我共同交流 ...

  3. Android中典型的ROOT原理(5)

    ROOT的作用 Customization 用户的个人定制,如删除一些预安装,定制开机动画等. 特权操作 所有需要特权操作的基本都是要通过ROOT,这也是ROOT的初衷. ROOT的第一步:寻找漏洞并 ...

  4. mof提权原理及实现

    关于 mof 提权的原理其实很简单,就是利用了c:/windows/system32/wbem/mof/目录下的 nullevt.mof 文件,每分钟都会在一个特定的时间去执行一次的特性,来写入我们的 ...

  5. mof提权原理及其过程

    mof提权的原理: mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做"托管对象格式"其作用是每隔五秒就 ...

  6. Meterpreter提权详解

      0x01 Meterpreter自动提权 1.生成后门程序 我们在kali的命令行下直接执行以下命令获得一个针对windows的反弹型木马: msfvenom -p windows/meterpr ...

  7. mysql提权常用方法。 hack某某

    一般是root权限,知道mysql root权限,root账号密码 启动项提权:原理:利用高权限的root写入一个vbs脚本到启动项,再通过一些方法如ddos,社工管理员之类的方法来让服务器重启,运行 ...

  8. Day 10 用户的提权,用户组的创建删除

    1.如何为用户设定密码,又如何修改密码? 2.用户的创建流程? [扩展了解] 3.用户组如何管理? 4.普通用户无权限怎么办? 切换身份 or 提权? su 切换用户 sudo 提权   5.为用户添 ...

  9. 靶机DC-2 rbash绕过+git提权

    这个靶机和DC-1一样,一共5个flag.全部拿到通关. root@kali:/home/kali# nmap -sP 192.168.1.* 先扫一下靶机的IP地址,拿到靶机的地址为192.168. ...

随机推荐

  1. MetricGraphics.js – 时间序列数据的可视化

    MetricsGraphics.js 是建立在D3的基础上,被用于可视化和布局的时间序列数据进行了优化.它提供以产生一个原则性的,一致的和响应式的方式的图形常见类型的简单方法.该库目前支持折线图,散点 ...

  2. 【初探Underscore】再说模版引擎

    前言 Underscore 是一个JavaScript实用库,提供了类似Prototype.js (或 Ruby)的一些功能,但是没有扩展任何JavaScript内置对象. 它弥补了部分jQuery没 ...

  3. 使用gulp来构建一个前端项目

    什么是gulp? gulp是一个前端项目构建工具,是自动化项目的构建利器,它不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成.你可以使用gulp及其插件对你的项目代码 ...

  4. [SharePoint] SharePoint 错误集 1

    1. Delete a site collection · Run command : Remove-SPSite –Identity http://ent132.sharepoint.hp.com/ ...

  5. Day Tips:Remote 服务器黑屏

    如果是台式机:CTRL+ALT+End 笔记本一般情况下End建和其他的键混合使用,所以是Fn+CTRL+ALT+End

  6. 用Dart写的黑白棋游戏

    2013年11月,Dart语言1.0稳定版SDK发布,普天同庆.从此,网页编程不再纠结了. 在我看来,Dart语法简直就是C#的升级版,太像了.之所以喜欢Ruby的一个重要理由是支持mixin功能,而 ...

  7. 【CoreData】 简单地使用

    先介绍一下什么是CoreData —— 它是在iOS5之后出现的一个框架,提供了对象-关系映射(ORM)的功能,既能够将OC对象转化成数据,保存在SQLite数据库文件中,也能将保存在数据库中的数据还 ...

  8. iOS代码加密常用加密方式

    iOS代码加密常用加密方式 iOS代码加密常用加密方式,常见的iOS代码加密常用加密方式算法包括MD5加密.AES加密.BASE64加密,三大算法iOS代码加密是如何进行加密的,且看下文 MD5 iO ...

  9. 【代码笔记】iOS-首页3张图片变化

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  10. HTML5 结构性标签 行内语义性标签

    结构性标签: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UT ...