首页
社区
课程
招聘
[求助]想问下android setgid(0)失败的原因
发表于: 2014-3-17 11:53 30227

[求助]想问下android setgid(0)失败的原因

2014-3-17 11:53
30227
最近在修改su.c文件,我的目的是让所有三方应用在user版本上都可以使用root权限,我现在不想要apk来管理,也就是对申请root权限的应用没有限制,只要申请都可以获得,于是我去掉了su.c中的下面这段限制
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
        return 1;
    }
我把上面这段话去掉之后,发现在setgid(gid) || setuid(uid) 这地方报错,gid和uid的值都为0,也就是root的用户组,但是不知道为什么会报:Operation not permitted 这样的错误呢?我研究了下setgid函数,被运行的文件有setgid的权限,那么运行该文件时就拥有该文件所有者同样的权限,而我的su文件的权限是这样的:
-rwsr-sr-x root     root        83776 2008-08-01 20:00 su
setgid和setuid的权限都有啊,而且我通过shell指令运行su文件,也能成功获取到root权限,为什么我用第三方的应用去获取,在setgid的时候就会失败呢???

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (25)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你的JAVA代码怎么调用 的。
完整的贴一下。
2014-3-17 13:00
0
雪    币: 0
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
                                try{
                                        Process p = Runtime.getRuntime().exec("su");

                                        BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                                       
                                       
                                        String s = br.readLine();
                                       
                                        if(s == null){
                                                Log.i("xxx", "error s == null");
                                        }
                                       
                                        while(s != null){
                                                Log.i("xxx", "error" + s);
                                                s = br.readLine();
                                        }
                                       
                                }catch(Exception e){
                                        Log.e("xxx", "error: " + e.getMessage());
                                }
应该不是这个原因吧
2014-3-17 13:25
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
然后你试着将这段去掉的代码重新加回去。 再调用试试。 感觉 跟代码没关系 。
2014-3-17 15:26
0
雪    币: 0
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
如果我把这段代码
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
        return 1;
    }
再加回去的话,在java层运行su的时候,就会在这段代码的时候退出了,因为我写的java应用uid不是AID_ROOT或AID_SHELL,根本就不会执行之后的代码。
我刚才也试了下setgid函数,第三方应用不能通过该函数设置成非本应用的gid号,但是shell进程可以成功设置,不知道为什么~~~root的原理不就是通过setgid和setuid来获取root组的权限吗?
2014-3-17 15:42
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
所以。 这是他原来的代码么? 如果是原来的话。 那在JAVA中应该也是不能用的。

但实际上su是可以用的。 所以你用的不是原始的su的代码?
2014-3-17 21:05
0
雪    币: 0
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
是android系统默认的代码,我用的就是原始的代码,只是把   
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
        return 1;
    }
这段限制去掉了,我对比了一个root包的su.c的源码,里面也只是多了一个数据库的查询,如果调用su的应用不在限制列表内,那么也是直接调用 setgid(0)和setuid(0)来直接获取root的权限。
2014-3-18 09:06
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我也同样困惑这个问题。
有人能够解答下吗?
2014-3-18 09:19
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
所以你看是这样的结果:

一、原始代码A,成功使用

二、代码B,在A的基础上去掉了这几行,不能使用。

三、代码C,在B的基础上加回来,结果应该也是A,但却不能使用了~ 。。

2014-3-18 09:19
0
雪    币: 0
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
。。。不是这个 哥们你理解错了。。无论我去没去那段代码,都只能在shell下使用su能成功获取root权限,但是通过第三方应用软件调用su获取不到root权限,会卡在setgid这里,setgid会失败。
2014-3-18 11:01
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
但实际上。 真实使用的su 的代码。 第三方应用是可以取到root权限的。 所以你这份代码原生就不能正常使用啊!
2014-3-18 12:58
0
雪    币: 53
活跃值: (280)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
Android什么版本下测试的?4.4 or <4.4
4.4有些厂商增加了drop capbnd,甚至有些kernel还增加了no_new_privs,普通应用不能提权的

你看看应用的pid,观察一下CapBnd:是否是全F,不是的话就没set*id 这个能力。
cat /proc/pid/status
2014-3-18 15:07
0
雪    币: 0
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
我是在4.3上试验的,我看了下我的目标进程的CapBnd为
CapBnd: fffffff000000000
按照你的意思是没有setgid的权限?那么我想问一下,我也试过用刷机精灵类的软件一键root功能,确实能成功root,它是怎么做的呢?修改了这个CapBnd的值?有研究过可以一起讨论讨论。
2014-3-18 17:00
0
雪    币: 138
活跃值: (475)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
开机启动时开启一个 su --daemon 的服务,由它来控制新的进程启动权限;
详细细节见 daemon.c
2014-3-18 19:01
0
雪    币: 53
活跃值: (280)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
楼上已解释
通过修改/system/etc/install_recovery.sh,嵌入要启动的native daemon程序,监听socket,然后/system/bin/su只是一个socket客户端,与监听的socket进行通信,传递需要root权限才能操作的命令。
su只是个代理,所以不需要suid权限都可以。
2014-3-19 21:58
0
雪    币: 138
活跃值: (475)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16
路径是 /system/etc/install-recovery.sh ,这个路径 /install_recovery.sh 是无法自启动滴

/system/etc/install-recovery.sh 内容:

#!/system/bin/sh
/system/xbin/su --daemon &


楼主需要删掉 判断 superuser是否存在
if (stat(ctx.user.base_path, &st) < 0)

干脆把deny 替换成 allow 得了
2014-3-20 16:32
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
有没可以通过/proc/sys/kernel/cap-bound修改的方式
2014-8-5 11:21
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
我也遇到这个问题了,不知道咋解决。
2014-9-16 20:03
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
能在具体点吗,我也备受苦恼啊!
2014-9-16 20:48
0
雪    币: 138
活跃值: (475)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
20
首先需要确认你的android版本是否已经开启 SELinux, 如果有 SELinux禁止了非init进程的授权操作;你需要在 /etc/install-recovery.sh 或者替换其他由init启动的进程

如果是跟LZ一样, 修改源码,这个得具体看哪里被拒绝了; 具体情况打LOG来确认吧;
2014-9-17 08:50
0
雪    币: 24
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
学习了,su --daemon又为什么能获取到root权限呢?我也去看看代码
2014-9-17 09:30
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
需要修改源码吗 ?
还是通过修改源码找到根源在做打算 。
2014-9-17 11:22
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
Android4.3及4.4都无法在su.c进行修改就可以提权的;
以下是哥们在Android4.4植入的一个Root通道,供参考:
      可以在init.rc加一个一个服务Root_service,然后自己写一个Root_su.c(类似于su) ,apk/其他系统api要执行Root命令,可以直接跟Root_su交互就行了,而Root_su则通过Socket与Root_service通信,要知道Root_service本身就具有Root权限;这样就间接让APK具有执行Root命令权限的目的;最后Root_su.c可以设置自己的密码;
2014-9-29 15:47
0
雪    币: 5
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
这个是要求在root的shell下进行启动的
2015-3-16 15:59
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
现在也卡在这儿,可以请教下思路吗
2015-3-26 09:46
0
游客
登录 | 注册 方可回帖
返回
//