Android奇淫run-as命令,调用系统受UID限制的API

原创 橙留香Park 2022-10-01 00:32

也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大

少走了弯路,也就错过了风景,无论如何,感谢经历


本篇文章遇到排版混乱的地方,可点击文末阅读原文或前往该地址:https://orangey.blog.csdn.net/article/details/126219844

更多关于Android安全的知识,可前往:https://blog.csdn.net/ananasorangey/category11955914.html



0x01 前言

run-as是Android系统中的一个小应用,可以辅助我们进行Android程序的开发。

功能:run-as命令,以root身份运行命令,可以在未root的情况下查看某个(debug模式的)应用的内部信息(沙盒文件夹),前提条件是应用需为debug模式,即AndroidManifest.xml文件中,android:debugable需要为true

在开发Android应用的时候,有的时候希望能获取到保存到手机盘应用私有目录/data/data/com.mwr.dz下的数据来验证开发的应用是否达到预期结果,或者获取写到私有目录的log日志文件来进行debug工作。

在没有root过的手机中,我们是无法直接使用adb shell来获取到/data/data/com.mwr.dz下的数据,此时的用户权限是无法查看很多信息的,包括各个应用的沙盒,而run-as就向开发者提供了未root情况下访问沙盒信息的权限,执行run-as + 包名,就可以直接以root权限进入该应用的沙盒中查看包括数据库、xml、各种信息文件

  • 为什么命令可以查看到Android应用私有数据?

run-as程序就是通过s权限使得普通用户可以在满足条件(应用为debug模式时、操作目录仅在应用沙盒下)时具备root权限

除了提权以外,s权限还可以用来降权,root用户可更改文件的拥有者,以及通过s权限任意更改程序执行时的权限,在Linux中所有进程都是由zygote进程fork出来的,如果不降权的话则所有进程都与父进程相同、具备了root权限,这显然是不安全的,因此zygote通过forkAndSpecializeCommon函数来进行降权处理,使得子进程具备可控的权限

  • 注:

    • 1.使用run-as后,是无法使用cp命令将应用数据拷贝到sd卡的,没有权限

    • 2.apk已签名,并且设置了android:debuggable="false",将无法使用run-as命令

    • 3.无法使用run-as来直接获取应用数据的话,需在自己的应用里实现读取应用数据到sd卡的功能,应用本身对自己的数据是有访问权限的

    • 4./data/data/com.packagename/lib目录不需要执行run-as就拥有访问权限,为apk间共享so提供了便利

Java中的调试系统jdb,其实Android中的调试系统是gdb,通过gdb和gdbserver来调试App。具体来说,就是gdbserver通过ptrace附加到目标App进程去,然后gdb再通过socket或者pipe来链接gdbserver,并且向它发出命令来对App进程进行调试。需要注意以下关键点:

  • 每一个需要调试的apk在打包的时候都会带上一个gdbserver,因为手机上面不带有gdbserver工具。gdbserver用来通过ptrace附加到要调度的App进程去。

  • ptrace的调用。一般来说,只有root权限的进程可以调用。例如,如果想通过ptrace向目标进程注入一个so,需要在root过的手机上向su申请root权限。但是,这不是绝对的。如果一个进程与目标进程的uid是相同的,那么该进程就具有调用ptrace的权限。gdbserver在调试一个App之前,先通过ptrace_attach来附加到该App进程去,ptrace_attach在执行实际操作之后,会调用__ptrace_may_access来检查调用进程的权限,如果调用进程与目标进程具有相同的uid和gid,那么权限检查通过。否则的话,就要求调用者进程具有执行ptrace的能力,这是通过另外一个函数ptrace_has_cap来检查的。如果调用进程的uid是root,那么ptrace_has_cap一定会检查通过。当然,通过了上述两个权限检查之后,还要接受内核安全模块的检查,这就不是通过uid或者capability这一套机制来控制的了

  • 如何让gdbserver进程的uid与要调试的App进程的uid一样?

在没有root过的手机上要想获得root权限是不可能的,因此只能选择以目标进程相同的uid运行这个方法,可使用run-as工具

0x02 调用系统受uid限制的API

众所周知,Android P 引入了针对非 SDK 接口(俗称为隐藏API)的使用限制,这是继 Android N上针对 NDK 中私有库的链接限制之后的又一次重大调整。从今以后,不论是native层的NDK还是 Java层的SDK,我们只能使用Google提供的、公开的标准接口。

Android P 和 Android Q:https://blog.csdn.net/github_34402358/article/details/94399343

用一个例子来详细介绍Android中如何降权,这个例子是模拟一个系统的API,但是这个API只允许system用户调用,代码如下:

在Android平台执行Java程序需要依赖dalvik虚拟机,因此需要将jar包转换为对应的字节码文件,操作步骤如下:1、生成java jar包 同Pc执行

java -jar E:\test.jar

2、java jar包转dex包,执行如下命令

dx --dex --output=test.dex E:\test.jar

3、连接Android手机,并将dex执行程序推入Android设备路径下:

adb push E:\test.dex /data/local/tmp/

  • 打开 IDEA 软件,点击界面上的 Create New Project

  • 出现以下界面,选中 Java,然后选择 JDK,最后点击 Next,进行下一步(我的是 jdk1.8)

  • 这里是选择生成项目时是否创建 Java 文件,勾选上 Java Hello World 后会生成一个默认的 Hello world 文件,点击 Next 进行下一步

  • 给项目命名,默认是 untiled,自己填个名字吧,最后点击 finish

  • 项目创建完成,创建 Java 文件:点击 src——>new——>package,创建一个文件包,并给包命名,与 Eclipse 的包类似

在包下面创建 Java 类文件,点击包名——>New——>Java Class;
给类文件命名

  • 进入手机shell

adb shell

  • 进入sdcard目录

cd sdcard

  • 设置将要执行的jar包的classpass,不设置将无法执行

export CLASSPATH=/sdcard/hello.jar

  • 执行jar包

app_process hello.jar com.lyh.hello.Hello aaa bbb ccc

创建一个IDA 来编写Android 中的程序

0x03 案例1

run-as 命令可以获取debug应用的私有数据,在调试debug包的时候,可以使用该命令将用户切换到系统分配给debug应用的用户上,之后就可以访问其私有数据

  • adb shell

  • whoami

  • run-as /data/data/com.mwr.dz

  • whoami

:在默认的shell环境下,用户身份是root(假设当前是普通用户,无法查看应用的私有数据),运行 run-as 后,身份切换了 u0_a40, 这个用户其实是测试应用的uid,也可以自由的访问其私有目录

  • Android中每一个应用都有一个uid,可以通过以下方式获取:

PS命令:

ps | grep com.mwr.dz

每个Android应用程序的u0_axx都是不一样的,同时uid是从10000开始,u0_a后面的数字加上10000所得的值,既是uid,这个和测试应用的输出也非常的吻合,即u0_a40 和 10040。

:0_a后面的数字就是该应用的UID值减去FIRST_APPLICATION_UID所得的值,40 + FIRST_APPLICATION_UID = 10040

android2.3.3_r1中run-as.c中主要代码:

/* 没有传入包名则退出 */
if (argc < 2)

usage();

/* 非'shell'用户或'root'用户则退出 */
myuid = getuid();

if (myuid != AID_SHELL && myuid != AID_ROOT) {

panic("only 'shell' or 'root' users can run this program\n");

}

/* 根据传入包名获取应用信息,失败则退出 */
pkgname = argv[1];

if (get_package_info(pkgname, &info) < 0) {

panic("Package '%s' is unknown\n", pkgname);

return 1;

}

/* reject system packages */
if (info.uid < AID_APP) {

panic("Package '%s' is not an application\n", pkgname);

return 1;

}

/* 如果设置了android:debuggable="false",则退出 */
if (!info.isDebuggable) {

panic("Package '%s' is not debuggable\n", pkgname);

return 1;

}

/* 检查/data/data/com.packagename目录是否可用 */
if (check_data_path(info.dataDir, info.uid) < 0) {

panic("Package '%s' has corrupt installation\n", pkgname);

return 1;

}

/* 切换当前工作目录为/data/data/com.packagename,失败则退出 */
{

int ret;

do {

ret = chdir(info.dataDir);

} while (ret < 0 && errno == EINTR);
if (ret < 0) {

panic("Could not cd to package's data directory: %s\n", strerror(errno));

return 1;

}

}

/* Ensure that we change all real/effective/saved IDs at the
* same time to avoid nasty surprises.
*/


/* 切换真实/有效/saved 用户ID和组ID*/
uid = gid = info.uid;

if(setresgid(gid,gid,gid) || setresuid(uid,uid,uid)) {

panic("Permission denied\n");

return 1;

}

/* 用户在包名参数后指定了要执行的命令,就执行这个命令 */
if (argc >= 3 ) {

if (execvp(argv[2], argv+2) < 0) {

panic("exec failed for %s Error:%s\n", argv[2], strerror(errno));

return -errno;

}

}

/* 用户没有传入要执行的命令,执行默认的shell命令子进程,此时可以执行exit命令退出 */
execlp("/system/bin/sh", "sh", NULL);

panic("exec failed\n");

return 1;

9 8 7 6 5 4 3 2 1 0
- r w x r - x r - x

  • 第9位表示文件类型,可以为p、d、l、s、c、b和-:

    • p表示命名管道文件

    • d表示目录文件

    • l表示符号连接文件

    • s表示socket文件

    • c表示字符设备文件

    • b表示块设备文件

    • -表示普通文件

  • 第8~6位、5~3位、2~0位分别表示文件所有者的权限、同组用户的权限、其他用户的权限,其形式为rwx:

    • r表示可读,可以读出文件的内容,对应的数字是4

    • w表示可写,可以修改文件的内容,对应的数字是2

    • x表示可执行,可运行这个程序,对应的数字是1

  • 执行的话,分别表现在所有者或同组用户权限的可执行位上,例如:

    • 1)-rwsr-xr-x 表示SUID和所有者权限中可执行位被设置

    • 2)-rwsr--r-- 表示SUID被设置,但所有者权限中可执行位没有被设置

    • 3)-rwxr-sr-x 表示SGID和同组用户权限中可执行位被设置

    • 4)-rw-r-sr-- 表示SGID被设置,但同组用户权限中可执行位没有被设置

0x04 Android中setuid和setgid

Android系统进程Zygote启动过程的源代码分析:http://blog.csdn.net/luoshengyang/article/details/6768304

Android的APK都是运行在独立的应用程序进程里面的,Android中的所有的应用进程和SystemServer进程都是Zygote进程fork出来的。Zygote进程又是由init进程fork出来的,并且它被init进程fork出来后,没有被setuid降权,也就是它的uid仍然是root。

应用程序进程被Zygote进程fork出来的时候,它的UID也应当是root。但是,它们的UID会被setuid修改为所加载的APK被分配的UID。

Android 2.2 以及之前版本的Zygote没有对降权时setuid调用的返回值进行检查。同样,在耗尽目标程序uid的最大进程数之后,Zygote就无法降低它的权限,然后就以root权限启动应用了

虽然Zygote进程相当于Android系统的根进程,但它也是由Linux系统的init进程启动的。各个进程的先后顺序为:

init进程 –-> Zygote进程 -–> SystemServer进程 -–>应用进程

所有Android应用进程都是zygote fork出来的,新fork出来的应用进程还保持着root权限,这显然是不被允许的,所以这个fork出来的子进程的权限需要被降级,本文说的就是Android源码在什么地方执行了权限降级的操作

  • zygote降权处理

Zygote启动流程:

1)初始化DDMS

2)注册Zygote进程的Socket

3)加载class、resource、OpenGL、WebView等各种资源

4)fork出SystemServer进程

5)启动SystemServer进程

6)调用runSelectLoop()一直监听Socket信息

7)收到创建应用程序Socket消息,调用ZygoteConnection#runOnce()。在runOnce()中调用Zygote#forkAndSpecialize()创建应用进程

8)启动应用进程

  • su工具原理

Android手机的root原理:一个普通的进程通过执行su,从而获得一个具有root权限的进程

su所做的事情其实很简单,它再fork另外一个子进程来做真正的事情,也就是在执行su的时候后面所跟的那些参数。由于运行su的进程的uid是root,因此由它fork出来的子进程的uid也是root,于是子进程也可以达到跟root一样的权限操作稳健。不过,用来root手机的su还会配合另外一个称为superuser的App来使用。su在fork子进程来做真正的事情之前,会先启动superuser,询问用户是否允许fork一个uid是root的子进程,对root权限进行控制,避免被恶意应用偷偷地使用

  • chmod修改setuid和setgid場景:run-as命令

在Android中也有类似的场景,例如run-as命令本生的uid是root,gid是shell,输入 run-as 命令的用户就会立马升级到root用户,root用户可以进入到任何应用的data/data/目录下面

chmod 6755 run-as

ll /system/bin/run-as

参考链接

https://blog.csdn.net/whklhhhh/article/details/81177455

https://blog.csdn.net/moonshine2016/article/details/53422082

https://daemon369.github.io/android/2013/09/03/use-run-as-get-android-private-data

https://www.codeboy.me/2019/09/10/android-run-as/

https://blog.csdn.net/qq_17250009/article/details/52061171

http://www.520monkey.com/archives/607


你以为你有很多路可以选择,其实你只有一条路可以走



橙留香Park 橙留香来自一位三流剑客之乡,担任威胁猎手,脑子不会转弯,属于安全特学脑。橙留香同学[小菜鸟],定期分享从零入门车联网安全(包括基础知识储备)技术。只为你呈现有价值的信息,专注于车联网安全领域之Android终端反入侵技术研究。
评论
  • 在智能家居领域中,Wi-Fi、蓝牙、Zigbee、Thread与Z-Wave等无线通信协议是构建短距物联局域网的关键手段,它们常在实际应用中交叉运用,以满足智能家居生态系统多样化的功能需求。然而,这些协议之间并未遵循统一的互通标准,缺乏直接的互操作性,在进行组网时需要引入额外的网关作为“翻译桥梁”,极大地增加了系统的复杂性。 同时,Apple HomeKit、SamSung SmartThings、Amazon Alexa、Google Home等主流智能家居平台为了提升市占率与消费者
    华普微HOPERF 2025-01-06 17:23 145浏览
  • 这篇内容主要讨论三个基本问题,硅电容是什么,为什么要使用硅电容,如何正确使用硅电容?1.  硅电容是什么首先我们需要了解电容是什么?物理学上电容的概念指的是给定电位差下自由电荷的储藏量,记为C,单位是F,指的是容纳电荷的能力,C=εS/d=ε0εrS/4πkd(真空)=Q/U。百度百科上电容器的概念指的是两个相互靠近的导体,中间夹一层不导电的绝缘介质。通过观察电容本身的定义公式中可以看到,在各个变量中比较能够改变的就是εr,S和d,也就是介质的介电常数,金属板有效相对面积以及距离。当前
    知白 2025-01-06 12:04 173浏览
  • 自动化已成为现代制造业的基石,而驱动隔离器作为关键组件,在提升效率、精度和可靠性方面起到了不可或缺的作用。随着工业技术不断革新,驱动隔离器正助力自动化生产设备适应新兴趋势,并推动行业未来的发展。本文将探讨自动化的核心趋势及驱动隔离器在其中的重要角色。自动化领域的新兴趋势智能工厂的崛起智能工厂已成为自动化生产的新标杆。通过结合物联网(IoT)、人工智能(AI)和机器学习(ML),智能工厂实现了实时监控和动态决策。驱动隔离器在其中至关重要,它确保了传感器、执行器和控制单元之间的信号完整性,同时提供高
    腾恩科技-彭工 2025-01-03 16:28 170浏览
  • PLC组态方式主要有三种,每种都有其独特的特点和适用场景。下面来简单说说: 1. 硬件组态   定义:硬件组态指的是选择适合的PLC型号、I/O模块、通信模块等硬件组件,并按照实际需求进行连接和配置。    灵活性:这种方式允许用户根据项目需求自由搭配硬件组件,具有较高的灵活性。    成本:可能需要额外的硬件购买成本,适用于对系统性能和扩展性有较高要求的场合。 2. 软件组态   定义:软件组态主要是通过PLC
    丙丁先生 2025-01-06 09:23 85浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球无人机锂电池产值达到2457百万美元,2024-2030年期间年复合增长率CAGR为9.6%。 无人机锂电池是无人机动力系统中存储并释放能量的部分。无人机使用的动力电池,大多数是锂聚合物电池,相较其他电池,锂聚合物电池具有较高的能量密度,较长寿命,同时也具有良好的放电特性和安全性。 全球无人机锂电池核心厂商有宁德新能源科技、欣旺达、鹏辉能源、深圳格瑞普和EaglePicher等,前五大厂商占有全球
    GIRtina 2025-01-07 11:02 74浏览
  • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
    知白 2025-01-07 15:02 76浏览
  • By Toradex 秦海1). 简介嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台。  2. 准备a). Verdin i.MX8MP ARM核心版配合Dahlia载板并
    hai.qin_651820742 2025-01-07 14:52 48浏览
  • 本文介绍Linux系统更换开机logo方法教程,通用RK3566、RK3568、RK3588、RK3576等开发板,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。制作图片开机logo图片制作注意事项(1)图片必须为bmp格式;(2)图片大小不能大于4MB;(3)BMP位深最大是32,建议设置为8;(4)图片名称为logo.bmp和logo_kernel.bmp;开机
    Industio_触觉智能 2025-01-06 10:43 87浏览
  • 彼得·德鲁克被誉为“现代管理学之父”,他的管理思想影响了无数企业和管理者。然而,关于他的书籍分类,一种流行的说法令人感到困惑:德鲁克一生写了39本书,其中15本是关于管理的,而其中“专门写工商企业或为企业管理者写的”只有两本——《为成果而管理》和《创新与企业家精神》。这样的表述广为流传,但深入探讨后却发现并不完全准确。让我们一起重新审视这一说法,解析其中的矛盾与根源,进而重新认识德鲁克的管理思想及其著作的真正价值。从《创新与企业家精神》看德鲁克的视角《创新与企业家精神》通常被认为是一本专为企业管
    优思学院 2025-01-06 12:03 122浏览
  • 大模型的赋能是指利用大型机器学习模型(如深度学习模型)来增强或改进各种应用和服务。这种技术在许多领域都显示出了巨大的潜力,包括但不限于以下几个方面: 1. 企业服务:大模型可以用于构建智能客服系统、知识库问答系统等,提升企业的服务质量和运营效率。 2. 教育服务:在教育领域,大模型被应用于个性化学习、智能辅导、作业批改等,帮助教师减轻工作负担,提高教学质量。 3. 工业智能化:大模型有助于解决工业领域的复杂性和不确定性问题,尽管在认知能力方面尚未完全具备专家级的复杂决策能力。 4. 消费
    丙丁先生 2025-01-07 09:25 83浏览
  • 每日可见的315MHz和433MHz遥控模块,你能分清楚吗?众所周知,一套遥控设备主要由发射部分和接收部分组成,发射器可以将控制者的控制按键经过编码,调制到射频信号上面,然后经天线发射出无线信号。而接收器是将天线接收到的无线信号进行解码,从而得到与控制按键相对应的信号,然后再去控制相应的设备工作。当前,常见的遥控设备主要分为红外遥控与无线电遥控两大类,其主要区别为所采用的载波频率及其应用场景不一致。红外遥控设备所采用的射频信号频率一般为38kHz,通常应用在电视、投影仪等设备中;而无线电遥控设备
    华普微HOPERF 2025-01-06 15:29 131浏览
  •     为控制片内设备并且查询其工作状态,MCU内部总是有一组特殊功能寄存器(SFR,Special Function Register)。    使用Eclipse环境调试MCU程序时,可以利用 Peripheral Registers Viewer来查看SFR。这个小工具是怎样知道某个型号的MCU有怎样的寄存器定义呢?它使用一种描述性的文本文件——SVD文件。这个文件存储在下面红色字体的路径下。    例:南京沁恒  &n
    电子知识打边炉 2025-01-04 20:04 100浏览
  • 根据Global Info Research项目团队最新调研,预计2030年全球封闭式电机产值达到1425百万美元,2024-2030年期间年复合增长率CAGR为3.4%。 封闭式电机是一种电动机,其外壳设计为密闭结构,通常用于要求较高的防护等级的应用场合。封闭式电机可以有效防止外部灰尘、水分和其他污染物进入内部,从而保护电机的内部组件,延长其使用寿命。 环洋市场咨询机构出版的调研分析报告【全球封闭式电机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球封闭式电机总体规
    GIRtina 2025-01-06 11:10 104浏览
  • 随着市场需求不断的变化,各行各业对CPU的要求越来越高,特别是近几年流行的 AIOT,为了有更好的用户体验,CPU的算力就要求更高了。今天为大家推荐由米尔基于瑞芯微RK3576处理器推出的MYC-LR3576核心板及开发板。关于RK3576处理器国产CPU,是这些年的骄傲,华为手机全国产化,国人一片呼声,再也不用卡脖子了。RK3576处理器,就是一款由国产是厂商瑞芯微,今年第二季推出的全新通用型的高性能SOC芯片,这款CPU到底有多么的高性能,下面看看它的几个特性:8核心6 TOPS超强算力双千
    米尔电子嵌入式 2025-01-03 17:04 55浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦