Pel*_*eus 5 function-pointers go shellcode
我正在尝试在Go程序中执行shellcode,类似于如何使用其他语言.
例1 - C程序中的Shellcode
示例2 - http://www.debasish.in/2012/04/execute-shellcode-using-python.html
所有方法都有大致相似的技术 - 通过OS特定的分配(mmap,virtualalloc等)将shellcode分配给可执行内存,然后通过在执行之前创建指向该位置的函数指针来执行代码.
这是我在Go中执行相同操作的可怕hacky示例.shellcode在传递给函数之前对它执行了操作,所以它的格式为[]字节是固定的.说mmap期望传递文件描述符,这就是存在可怕的"写入tmp文件"部分的原因.
func osxExec(shellcode []byte) {
f, err := os.Create("data/shellcode.tmp")
if err != nil {
fmt.Println(err)
}
defer f.Close()
_,_ = f.Write(shellcode)
f.Sync()
b, err := syscall.Mmap(int(f.Fd()), 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_SHARED)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%p", b)
}
Run Code Online (Sandbox Code Playgroud)
在代码的最后,我有一个指针(切片?)代码,我认为是可执行内存 - 但我不知道如何将此地址转换为函数指针执行.我询问了一些IRC频道,但有人认为这可能是不可能的.
任何帮助是极大的赞赏.
干杯.
首先,您根本不需要(当前)使用mmap,因为内存是可执行的.如果确实需要mmap,可以使用匿名内存并放弃临时文件:
b, e := syscall.Mmap(0, 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_ANON)
copy(b, shellcode)
Run Code Online (Sandbox Code Playgroud)
否则,您可以尝试shellcode直接使用,因为它已经由连续数组支持.
至于将字节转换shellcode为函数,来自C的模拟看起来像:
f := *(*func() int)(unsafe.Pointer(&d[0]))
Run Code Online (Sandbox Code Playgroud)
它创建一个名为的函数值f,然后可以像普通函数一样调用它.
如果shell代码不是专门为Go制作的,并且您需要从C堆栈中调用它,那么使用cgo直接在C中执行它会更容易.
/*
call(char *code) {
int (*ret)() = (int(*)())code;
ret();
}
*/
import "C"
func main() {
...
// at your call site, you can send the shellcode directly to the C
// function by converting it to a pointer of the correct type.
C.call((*C.char)(unsafe.Pointer(&shellcode[0])))
Run Code Online (Sandbox Code Playgroud)
有多种方法可以做到这一点,尽管我自己没有测试过。
您可能想看看https://github.com/nelhage/gojit/blob/master/jit.go 它实现了基于 cgo 的解决方案(更安全,但速度较慢),以及基于直接的解决方案称呼。查看所有与构建相关的函数。