首页
社区
课程
招聘
[原创]SVC的TraceHook沙箱的实现&无痕Hook实现思路
2022-6-4 16:39 56009

[原创]SVC的TraceHook沙箱的实现&无痕Hook实现思路

2022-6-4 16:39
56009
收藏
点赞71
打赏
分享
打赏 + 165.00雪花
打赏次数 4 雪花 + 165.00
 
赞赏  ch1   +5.00 2022/09/25 拨云见雾,受到启发,楼主继续努力!
赞赏  Editor   +150.00 2022/07/04 恭喜您获得“雪花”奖励,安全圈有你而精彩!
赞赏  Imyang   +5.00 2022/06/04
赞赏  菱志漪   +5.00 2022/06/04 大佬牛鼻
最新回复 (103)
雪    币: 248
活跃值: (291)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
渣渣辉 2022-10-10 23:14
51
0
针对”免root环境下进行attch“有点疑问,android的selinux本身限制了应用进程的ptrace,如果要attach自己,那首先得关闭selinux,这里说的免root应该是指系统已经root(关闭selinux),但是注入操作是在自己进程里面进行attach吧?
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-10 23:37
52
0
二次打包注入的
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-10 23:37
53
0
渣渣辉 针对”免root环境下进行attch“有点疑问,android的selinux本身限制了应用进程的ptrace,如果要attach自己,那首先得关闭selinux,这里说的免root应该是指系统已经r ...
二次打包注入的
雪    币: 1205
活跃值: (309)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
我是一只马鹿 2022-10-12 16:25
54
0
在楼主的教程,自己尝试了一下,基于proot的svc io hook可以拦截路径,但是最后会有个很奇怪的signal:
SIGTRAP | PTRACE_EVENT_CLONE
signal -185022416 received from process -185022208
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-12 17:25
55
0
可能你什么地方写的不对,我用的还没有发现。不过看样子你这个错误好像是拦截了系统的某些东西导致的信号异常。
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-12 17:25
56
0
我是一只马鹿 在楼主的教程,自己尝试了一下,基于proot的svc io hook可以拦截路径,但是最后会有个很奇怪的signal: SIGTRAP | PTRACE_EVENT_CLONE signal -1 ...
可能你什么地方写的不对,我用的还没有发现。不过看样子你这个错误好像是拦截了系统的某些东西导致的信号异常。
雪    币: 1205
活跃值: (309)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
我是一只马鹿 2022-10-13 17:17
57
0
珍惜Any 可能你什么地方写的不对,我用的还没有发现。不过看样子你这个错误好像是拦截了系统的某些东西导致的信号异常。
多谢楼主的思路,问题都解决了,execve的子进程也可以拦截。
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-13 17:59
58
0
我是一只马鹿 多谢楼主的思路,问题都解决了,execve的子进程也可以拦截。
嗯呢 ,ptrace attch以后还是很方便的。
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2022-10-24 20:46
59
0
你先ptrace attch后,别的进程要附加自己怎么办? 再用sccomp处理ptrace?
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2022-10-24 23:24
60
0
可以seccomp里面吧ptrace也处理了 判断事件类型,模拟即可,可以看看proot呢
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2022-10-31 10:28
61
0
珍惜Any 可以seccomp里面吧ptrace也处理了 判断事件类型,模拟即可,可以看看proot呢

大佬,为什么使用了seccomp,execl执行命令被拒绝呢?

    #define LOGD(format, ...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", "[%s]: " format, __FUNCTION__, ##__VA_ARGS__);
    pid_t pid = fork();
    if (pid == 0) {  //子进程
        struct sock_filter filter[] = {
                BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_execve, 0, 1),
                BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRACE),
//                BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
                BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
        };
        struct sock_fprog prog = {
                .filter = filter,
                .len = (unsigned short) (sizeof(filter)/sizeof(filter[0])),
        };
        ptrace(PTRACE_TRACEME, 0, 0, 0);
        /* To avoid the need for CAP_SYS_ADMIN */
        if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
            perror("prctl(PR_SET_NO_NEW_PRIVS)");
            return 1;
        }
        if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) {
            perror("when setting seccomp filter");
            return 1;
        }
        ptrace(PTRACE_TRACEME, 0, 0, 0);
        kill(getpid(), SIGSTOP);
//        int rs = execl("/sbin/su", "su", "-c", "ls", (char *)0);//返回-1 errno=13
        int rs = execl("/system/bin/sh", "sh", "-c", "ls", (char *)0);//未返回任何信息
        LOGD("execl result=%d,   errno=%d", rs, errno)
        _exit(127);
    }else if(pid > 0){//主进程
        int status;
        int signal;
        struct user_regs regs;
        while(1){
            LOGD("等等挂起....");
            waitpid(pid, &status, 0);
            LOGD("进程已挂起");
            if (WIFEXITED(status)) {
                LOGD("正常退出!");
                break;
            }else if (WIFSIGNALED(status)) {
                LOGD("异常退出!%d", WTERMSIG(status));
                break;
            }else if (WIFSTOPPED(status)) {    //表明进程处于暂停状态
                signal = (status & 0xfff00) >> 8;
                switch (signal) {
                    case SIGSTOP: {//19 //因附加成功触的信号 //ptrace(PTRACE_ATTACH, ...)
                        ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESECCOMP);
                        LOGD("附加成功!");
                        break;
                    }
                    case SIGTRAP | (PTRACE_EVENT_SECCOMP << 8):
                    case SIGSYS:
                        status = ptrace(PTRACE_GETREGS, pid, 0, &regs);
                        LOGD("signal 31:%d----svc:%d----r0:%d----ip:%d----%x", signal, regs.ARM_r7, regs.ARM_r0, regs.ARM_ip, regs.ARM_sp)
                        break;
                    default:
                        LOGD("======其它信号:%d", signal)
                        break;
                }
                LOGD("继续运行");
                ptrace(PTRACE_CONT, pid, NULL, NULL);
            }
        }
    }


雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2022-10-31 10:33
62
0
系统 android 9, emui 9.1.0 honor10
雪    币: 1148
活跃值: (3384)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
王麻子本人 2022-12-5 19:00
63
0
樊辉 系统 android 9, emui 9.1.0 honor10
修改Seccomp的过滤规则,允许execl执行命令
雪    币: 1148
活跃值: (3384)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
王麻子本人 2022-12-5 19:01
64
0
樊辉 系统 android 9, emui 9.1.0 honor10
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execl), 0);
雪    币: 5
活跃值: (985)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
恋一世的爱 2022-12-14 13:32
65
0

比如我要将1.txt重定向为2.txt

雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2023-1-4 10:54
66
0
大佬们,文中说的
poke_reg(tracee, STACK_POINTER, peek_reg(tracee, ORIGINAL, STACK_POINTER));
修改SP寄存器,让这个方法二次进入,一次修改参数,一次修改返回结果即可。
为什么修改SP能让其二次进入?不应该是PC吗?这一句没懂,有大佬能解释一下吗
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2023-1-4 11:32
67
0
樊辉 大佬们,文中说的 poke_reg(tracee, STACK_POINTER, peek_reg(tracee, ORIGINAL, STACK_POINTER)); 修改SP寄存器,让这个方法 ...
sp就是栈指针,如果只修改pc还有压栈操作,直接修改sp,就免去了这些过程。可以理解成让方法二次进入
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2023-1-4 11:50
68
0
珍惜Any sp就是栈指针,如果只修改pc还有压栈操作,直接修改sp,就免去了这些过程。可以理解成让方法二次进入

Seccomp+ptrace:

我下面这段代是在proot里面改的。为什么不能实现二次进入呢?

case SIGTRAP | PTRACE_EVENT_SECCOMP << 8: {//1797		通过seccomp的SECCOMP_RET_TRACE产生的消息,而不执行系统调用(系统调用前触发)
                //PTRACE_EVENT_SECCOMP在PTRACE_SYSCALL(syscall-entry-stop和syscall-exit-stop)中间
                LOGI("信号%d来自vpid %d(%d)的 seccomp(SECCOMP_RET_TRACE)\n", signal, tracee->vpid, tracee->pid);
//				translate_syscall(tracee);
				status = fetch_regs(tracee);	//提取寄存器
                Sysnum syscall_index = get_sysnum(tracee, CURRENT);
                word_t syscall = detranslate_sysnum(get_abi(tracee), syscall_index);
                LOGD("vpid %" PRIu64 "(%d): list[%d]=%d: %s(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx) = 0x%lx [sp:0x%lx, abi:%d]",
                     tracee->vpid, tracee->pid,
                     syscall_index,
                     syscall,
                     stringify_sysnum(syscall_index),
                     peek_reg(tracee, CURRENT, SYSARG_1), peek_reg(tracee, CURRENT, SYSARG_2),
                     peek_reg(tracee, CURRENT, SYSARG_3), peek_reg(tracee, CURRENT, SYSARG_4),
                     peek_reg(tracee, CURRENT, SYSARG_5), peek_reg(tracee, CURRENT, SYSARG_6),
                     peek_reg(tracee, CURRENT, SYSARG_RESULT),
                     peek_reg(tracee, CURRENT, STACK_POINTER),
                     get_abi(tracee));

				save_current_regs(tracee, ORIGINAL);	//保存current寄存器到original
				poke_reg(tracee, STACK_POINTER, peek_reg(tracee, ORIGINAL, STACK_POINTER));	//修改sp
				push_specific_regs(tracee,  false);
				tracee->restart_how = PTRACE_CONT;


雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2023-1-4 12:03
69
0
樊辉 Seccomp+ptrace:我下面这段代是在proot里面改的。为什么不能实现二次进入呢?case&nbsp;SIGTRAP&nbsp;|&nbsp;PTRACE_EVENT ...
,,, 你看看我课程吧 ,你这写法不对 。帖子里面的demo需要的话可以私聊我 。
雪    币: 6088
活跃值: (2267)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
breaklink 2023-1-4 15:24
70
0
ptrace下断点是指修改指令brk #0吗?那还是过不了crc检测啊
雪    币: 6088
活跃值: (2267)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
breaklink 2023-1-4 16:00
71
0
breaklink ptrace下断点是指修改指令brk #0吗?那还是过不了crc检测啊
行吧,自己用gdb试了一下,下硬件断点就能断下来也不会触发crc
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2023-1-5 19:06
72
0
珍惜Any ,,, 你看看我课程吧 ,你这写法不对 。帖子里面的demo需要的话可以私聊我 。
好像也不用修改sp寄存器,seccomp拦截到后直接PTRACE_SYSCALL后就进入到syscall-exit-stop里面了
雪    币: 1941
活跃值: (12815)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
珍惜Any 2 2023-1-7 09:43
73
0
樊辉 好像也不用修改sp寄存器,seccomp拦截到后直接PTRACE_SYSCALL后就进入到syscall-exit-stop里面了
主要还是为了解决svc二次进入,修改svc的返回值。
雪    币: 224
活跃值: (962)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
樊辉 2023-1-16 17:24
74
0
珍惜Any 主要还是为了解决svc二次进入,修改svc的返回值。
大佬,有没有什么办法获取调用堆栈的模块,比如: openat拦截后,知道它是系统库调用的还是app的so调用的,用来过滤一下
雪    币: 52
活跃值: (506)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
万里星河 2023-1-16 21:06
75
0
珍惜Any 主要还是为了解决svc二次进入,修改svc的返回值。

感觉大佬提供的arm64位的用于系统调用的内联汇编有点问题

游客
登录 | 注册 方可回帖
返回