美文网首页
越狱设备代码注入原理及防护

越狱设备代码注入原理及防护

作者: lmfei | 来源:发表于2020-03-15 11:11 被阅读0次

越狱的设备上,在应用运行的时候插入动态库
划重点----DYLD_INSERT_LIBRARIES

DYLD源码分析

dyld.cpp-插入任意的libraries

_main(const macho_header* mainExecutableMH, uintptr_t mainExecutableSlide, 
        int argc, const char* argv[], const char* envp[], const char* apple[], 
        uintptr_t* startGlue){
  ...
#if __MAC_OS_X_VERSION_MIN_REQUIRED
    //当allowEnvVarsPrint、allowEnvVarsPath、allowEnvVarsSharedCache全为false时
    if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) {
                //移除插入的环境变量,执行这个方法后面的插入就会失败
        pruneEnvironmentVariables(envp, &apple);
        // set again because envp and apple may have changed or moved
        setContext(mainExecutableMH, argc, argv, envp, apple);
    }
    else
#endif
  ...
    // load any inserted libraries
    if  ( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {
        for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) 
            loadInsertedDylib(*lib);
    }
  ...
  return result;  
}

如何才能让allowEnvVarsPrint、allowEnvVarsPath、allowEnvVarsSharedCache全为false呢
dyld.cpp

static void configureProcessRestrictions(const macho_header* mainExecutableMH)
{
  ...
        bool isRestricted = false;
        bool libraryValidation = false;
        // any processes with setuid or setgid bit set or with __RESTRICT segment is restricted
                //issetugid无法改变,所以只有看hasRestrictedSegment什么时候为true
        if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) {
            isRestricted = true;
        }
        bool usingSIP = (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0);
        uint32_t flags;
        if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) {
            // On OS X CS_RESTRICT means the program was signed with entitlements
            if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) {
                isRestricted = true;
            }
            // Library Validation loosens searching but requires everything to be code signed
            if ( flags & CS_REQUIRE_LV ) {
                isRestricted = false;
                libraryValidation = true;
            }
        }
        //当isRestricted为true时
    gLinkContext.allowAtPaths                = !isRestricted;
    gLinkContext.allowEnvVarsPrint           = !isRestricted;
    gLinkContext.allowEnvVarsPath            = !isRestricted;
  ...
}
//
// Look for a special segment in the mach header. 
// Its presences means that the binary wants to have DYLD ignore
// DYLD_ environment variables.
//
#if __MAC_OS_X_VERSION_MIN_REQUIRED
//mh为MachO文件的头
static bool hasRestrictedSegment(const macho_header* mh)
{
    const uint32_t cmd_count = mh->ncmds;
         //cmds为commands
    const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));
    const struct load_command* cmd = cmds;
    for (uint32_t i = 0; i < cmd_count; ++i) {
        switch (cmd->cmd) {
            case LC_SEGMENT_COMMAND:
            {
                                //取出SEGMENT
                const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;
                
                //dyld::log("seg name: %s\n", seg->segname);
                                //是否存在segment的那么为__RESTRICT
                if (strcmp(seg->segname, "__RESTRICT") == 0) {
                    const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));
                    const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];
                    for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                                                //是否存在segment的value为__restrict
                        if (strcmp(sect->sectname, "__restrict") == 0) 
                            return true;
                    }
                }
            }
            break;
        }
        cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
    }
        
    return false;
}
#endif

总结
通过在Mach-O文件中,增加segname为__RESTRICT,value为__restrict的值,可以使isRestricted返回YES,然后后gLinkContext.allowAtPaths、gLinkContext.allowEnvVarsPrint、gLinkContext.allowEnvVarsPath值就为false,进而执行pruneEnvironmentVariables方法,移除插入的环境变量,最终是的插入失败

越狱防护

Build Setting -> Other Linker Flags 中新增内容

-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null

这个设置可以在Mach-O文件中增加segname为__RESTRICT,value为__restrict的段,以达到防护的效果!!!

生活如此美好,今天就点到为止。。。

相关文章

  • 越狱设备代码注入原理及防护

    越狱的设备上,在应用运行的时候插入动态库划重点----DYLD_INSERT_LIBRARIES DYLD源码分析...

  • 十三、iOS逆向之《越狱防护》

    概叙 越狱防护是指防止别人修改自己的APP作出的防护手段。 1.了解代码注入方式 了解防护之前需要了解代码注入的方...

  • iOS应用代码注入防护

    iOS应用代码注入防护 iOS应用代码注入防护

  • Cycript的使用

    这里使用了越狱手机, 在手机上通过Cydia安装了Cycript. 还可以通过注入的方式注入到非越狱设备, Mon...

  • web 安全

    常见web安全及防护原理 sql注入原理就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,...

  • 浏览器的安全问题

    web安全防护及原理 sql注入原理 通过sql命令插入到web表单递交或输入域名或页面请求的查询字符串,最终欺骗...

  • MonkeyDev-Logos Tweak初识

    LogosTweak,可以帮我们在不用重签名的情况下进行代码的动态注入,它的使用前提是在越狱设备上,下面记录下新建...

  • 应用防护代码注入

    在应用开发过程中,我们不仅仅需要完成正常的业务逻辑,考虑应用性能、代码健壮相关的问题,我们有时还需要考虑到应用安全...

  • 小迪16期-20170403

    第七天:二次注入原理及演示(代码审计意义很大) 二次注入代码审计解析 盲注攻击 sleep if sql语句 1....

  • 零基础使用Django2.0.1打造在线教育网站(二十五):常见

    写在前面 本篇笔记我们将介绍常见的网络攻击与防护,具体包括SQL注入攻击及防护,XSS攻击及防护以及CSRF攻击及...

网友评论

      本文标题:越狱设备代码注入原理及防护

      本文链接:https://www.haomeiwen.com/subject/buuxehtx.html