2015-05-15 54 views
4

我試圖在Go程序中執行shellcode,類似於您如何使用其他語言來執行。在Go中執行字節數組

實施例1 - Shellcode in C program

實施例2 - http://www.debasish.in/2012/04/execute-shellcode-using-python.html

所有方法都具有大致類似的技術 - 經由所述OS專用分配(MMAP,的VirtualAlloc等)分配的shellcode到可執行存儲器中,然後執行該代碼通過在執行之前創建指向該位置的函數指針。

這是我在Go中執行同樣的事情的可怕的黑客例子。 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) 
} 

在我已經有了一個指針(?片)在我的推測代碼的代碼到底是可執行的記憶 - 但我還是不知道怎麼到這個地址澆鑄成一個函數指針執行。我詢問了一些IRC頻道,但有人建議它可能不可能。

任何幫助,非常感謝。

乾杯。

+0

如果你把它寫進你不妨稱之爲syscall.Exec它 – ReyCharles

+0

@ReyCharles一個文件,這將意味着寫入(在Windows等像ELF在Linux上,PE)格式正確的文件。不確定Windows是否仍然允許運行MS-DOS COM格式的文​​件(這是非常簡單的)。 – kostix

+0

是的,對不起,我沒在想:) – ReyCharles

回答

4

有多種方式可以做到這一點,雖然我沒有自己測試過。

您可能想看看https://github.com/nelhage/gojit/blob/master/jit.go 它實現了一個基於cgo(這是更安全,但速度更慢)的解決方案和基於直接調用的解決方案。看看所有與構建相關的功能。

+0

謝謝 - 這是一個非常棒的圖書館,工作完美。 – Peleus

+0

@Peleus:如果cgo被禁用? – user2284570

5

首先,您根本不需要(當前)使用mmap,因爲go內存是可執行的。如果你確實需要mmap,您可以使用匿名內存並放棄臨時文件:

b, e := syscall.Mmap(0, 0, len(shellcode), syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC, syscall.MAP_ANON) 
copy(b, shellcode) 

否則,你可以嘗試直接使用shellcode,因爲它已經被連續的陣列支持。

至於在shellcode轉換字節於函數時,從C模擬將如下所示:

f := *(*func() int)(unsafe.Pointer(&d[0])) 

其中創建名爲f的函數值然後可以被稱爲像一個正常的功能。

如果shellcode不是專門爲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]))) 
+0

謝謝你的回答。我將上面的標記標記爲正確,因爲它允許稍微簡單一些的解決方案 - 但是我很欣賞你寫的內容也教會了我對其中某些我感興趣的技術。 Upvoted。 – Peleus

+0

@JimB:謝謝你的簡短回答。但是如果沒有'C'package怎麼做那種事?我的意思是cgo禁用? – user2284570

+0

@ user2284570:我不確定這是否可能。所有Go程序都是多線程的,並且可能需要cgo使用的運行時鉤子安全地輸入非去程序代碼。 – JimB

相關問題