首页
社区
课程
招聘
[原创]go样本加载过程分析
发表于: 2021-6-23 17:13 7665

[原创]go样本加载过程分析

2021-6-23 17:13
7665

在某一次投稿时候,审核的大佬发现我分析的偏了(其实就是菜),分析了很多的库函数,还犯了些很有意思的错误,既然分析偏了,那就把go的加载过程好好研究一番,弄明白了,本篇文章只是站在样本分析的角度去看go的加载,更加的详细的直接看底部的引用链接。

当我们将样本投入exeinfo或者die查壳发现是go的样本,然后在投入ida分析的时候,我们发现ida没有识别函数符号,都是sub_xxxxxx这样的函数,此时我们是没有办法分析的,我们需要加载go的符号表

fbaK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6K9h3u0W2j5i4u0K6i4K6u0r3d9f1c8m8c8$3!0D9j5h3&6Y4d9r3g2D9M7r3g2J5

git clone之后,将GO_Utilsgo_entry.py移动到idapython
然后重启idaFile——>Script Command,载入插件

然后点击run

看以上图片 ,第一步第二步是检测样本go版本,检测结果会输出到OUTPUT Windows


基本就识别出来了,function names对应的函数名也会相应的显示出来
类似的项目还有

当我们开始之前,我们先看一个图

因为golang最关键的就是runtime,有点类似java的虚拟机,不过runtime不是虚拟机,把它理解成标准库更贴切,这张图目的就是让我们更好的了解,当样本被执行的时候,究竟都发生了什么,有一个整体分析的思路
我们这里通过一个小的样本来说明,当我们直接把样本投入到IDA进行调试

直接停在了_rt0_amd64_windows,那为什么会停在这个函数?
这里就不得不提一下程序的执行过程中的编译过程链接过程

编译过程是把预处理完的文件进行一系列词法分析,语法分析,语义分析,优化后生成相应的汇编代码文件。

链接过程是把源代码模块独立的编译,然后按照需要将他们“组装”起来,这其中包括地址和空间分配,符号,重定位等等

go也不例外,go需要使用链接器将单个的文件进行链接组装,我们来简单看一下代码

47dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6@1K9i4m8Q4x3X3g2Y4L8$3I4S2L8X3N6Q4x3X3g2G2M7X3N6Q4x3V1k6K6M7X3y4Q4x3V1k6U0L8h3c8Q4x3V1k6D9K9h3&6C8i4K6u0r3K9h3&6@1k6i4u0F1j5h3I4Q4x3V1k6D9k6q4)9J5c8X3I4A6j5W2)9J5k6h3N6G2

我们综合代码分析出,如果用户没有指定用户地址,那么在x84_64下生成的exe程序默认入口地址就是_rt0_amd64_windows,这时候你分析样本时候,样本在ida一打开,如果是PE的就会自动跳转到_rt0_amd64_windows,如果是ELF就会自动跳转到_rt0_amd64_linux

然后我们F8继续调试,程序进行一系列的调用

go bootstarp的流程就是首先,检查cpu是否符合,配置好样本运行相关的参数,然后,进行tls初始化(具体看第三个链接),然后调用runtime.argsruntime.osinitruntime.schedinit配置好样本加载时候的各种变量以及调度器,总结如下

然后执行到main这,这块基本就执行攻击者自己实现的恶意代码了,就是以main_xxxx开头的基本都是攻击者自己实现的,我们分析的时候主要分析这块就可以

那么,我们了解完以上,如果攻击者自己实现了一个包或者模块时候,会在main_main之前启动,比如说init_xxx(),xxxx_init,xxx_initx等等,常用来运行前的注册,比如说decoder,parser的注册,运行时只需计算一次的模块,比如sync.once或者全局数据库连接句柄的初始化等等
我们怎么判断是不是,init()函数具有以下特点

4f3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7K9h3q4&6N6e0m8^5i4K6u0W2j5$3!0E0i4K6u0r3x3U0l9J5x3q4)9J5c8U0l9&6i4K6u0r3x3U0S2Q4x3V1k6Y4L8#2)9J5k6r3u0A6L8X3q4J5P5g2)9J5k6s2u0W2N6X3g2J5M7$3g2Q4x3X3c8W2L8X3N6A6L8X3g2W2M7X3W2F1k6#2)9J5k6s2c8A6M7s2y4Q4x3X3c8S2L8X3c8Q4x3X3c8W2P5r3q4E0M7r3I4W2i4K6u0r3
24cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3M7h3y4J5j5h3!0Q4x3X3b7J5x3o6p5^5i4K6u0r3M7q4)9J5c8U0p5I4x3e0t1@1x3K6j5H3i4K6u0W2K9s2c8E0L8l9`.`.
44dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3k6X3I4Z5M7#2)9J5c8Y4m8Q4x3V1j5I4x3U0j5#2y4K6x3@1z5q4)9J5k6h3S2@1L8h3H3`.
5a8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7K9h3q4&6N6e0m8^5i4K6u0W2j5$3!0E0i4K6u0r3x3U0l9J5x3q4)9J5c8U0l9&6i4K6u0r3x3U0S2Q4x3V1k6Y4L8#2)9J5k6r3u0A6L8X3q4J5P5g2)9J5k6s2u0W2N6X3g2J5M7$3g2Q4x3X3c8W2L8X3N6A6L8X3g2W2M7X3W2F1k6#2)9J5k6s2c8A6M7s2y4Q4x3X3c8S2L8X3c8Q4x3X3c8W2P5r3q4E0M7r3I4W2i4K6u0r3
237K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2K9h3y4W2K9h3&6@1L8#2)9J5k6h3y4G2L8g2)9J5c8Y4m8G2M7%4c8K6i4K6u0r3k6$3!0Q4x3V1k6K6N6r3q4J5N6q4)9J5c8R3`.`.
700K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6*7K9s2g2S2L8X3I4S2L8W2)9J5k6i4A6Z5K9h3S2#2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8U0p5I4x3e0x3%4x3o6M7&6x3R3`.`.

 
 
 
 
https://github.com/strazzere/golang_loader_assist
 
https://github.com/0xjiayu/go_parser
https://github.com/strazzere/golang_loader_assist
 
https://github.com/0xjiayu/go_parser
.text:0000000000465CC0 ; [00000005 BYTES: COLLAPSED FUNCTION _rt0_amd64_windows. PRESS CTRL-NUMPAD+ TO EXPAN
.text:0000000000465CC0 ; [00000005 BYTES: COLLAPSED FUNCTION _rt0_amd64_windows. PRESS CTRL-NUMPAD+ TO EXPAN
 
 
 
//linux build
if *flagEntrySymbol == "" {
  switch ctxt.BuildMode {
  case BuildModeCShared, BuildModeCArchive:
    *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", buildcfg.GOARCH, buildcfg.GOOS)
  case BuildModeExe, BuildModePIE:
    *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", buildcfg.GOARCH, buildcfg.GOOS)
  case BuildModeShared, BuildModePlugin:
    // No *flagEntrySymbol for -buildmode=shared and plugin
  default:
    Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
  }
}
//linux build
if *flagEntrySymbol == "" {
  switch ctxt.BuildMode {
  case BuildModeCShared, BuildModeCArchive:
    *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", buildcfg.GOARCH, buildcfg.GOOS)
  case BuildModeExe, BuildModePIE:
    *flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", buildcfg.GOARCH, buildcfg.GOOS)
  case BuildModeShared, BuildModePlugin:
    // No *flagEntrySymbol for -buildmode=shared and plugin
  default:
    Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
  }
}
//windows build
if(INITENTRY == nil) {
        INITENTRY = mal(strlen(goarch)+strlen(goos)+20);
        if(!flag_shared) {
            sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
        } else {
            sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
        }
    }
    lookup(INITENTRY, 0)->type = SXREF;
//windows build
if(INITENTRY == nil) {
        INITENTRY = mal(strlen(goarch)+strlen(goos)+20);
        if(!flag_shared) {
            sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
        } else {
            sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
        }

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2021-6-25 10:34 被HexChristmas编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 58782
活跃值: (21900)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
图片没显示出来,麻烦补充一下图片。
2021-6-24 18:02
0
雪    币: 734
活跃值: (483)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
收到,已补充
2021-6-25 10:35
0
游客
登录 | 注册 方可回帖
返回