2015-05-15 3 views
4

Я пытаюсь выполнить shellcode в программе Go, аналогично тому, как вы можете сделать это с другими языками.Выполнение байтового массива в Go

Пример 1 - Shellcode in C program

Пример 2 - http://www.debasish.in/2012/04/execute-shellcode-using-python.html

Все методы имеют в целом аналогичные методы - назначить шеллкода к исполняемому памяти с помощью конкретного распределения OS (ттар, VirtualAlloc, и т.д.), а затем выполнить код путем создания указателя функции, указывающего на это место перед выполнением.

Вот мой ужасный хакерский пример при выполнении той же вещи в Go. Шестнадцатеричный код имеет манипуляции, выполняемые над ним перед передачей функции, поэтому он является форматом, когда байт [] исправлен. Говоря, что 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, но было высказано предположение, что это может быть невозможно.

Любая помощь очень ценится.

Cheers.

+0

Если вы пишете в файл вы можете также позвонить syscall.Exec на нем – ReyCharles

+0

@ReyCharles, что означало бы писать правильно отформатированный файл (например, ELF на Linux, PE на Windows, и т.д.). Не уверен, что 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 memory is executable. Если вам не нужно mmap, вы можете использовать анонимную память и воздерживаются файл TEMP:

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, который затем может быть вызван как обычная функция.

Если шеллкод специально не создан для Go, и вам нужно вызвать его из стека C, было бы проще сделать это непосредственно в C, используя cgo.

/* 
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: благодарю вас за короткий ответ. Но как делать такие вещи без '' 'пакета? Я имею в виду, что cgo отключен? – user2284570

+0

@ user2284570: Я не уверен, что это возможно. Все программы Go являются многопоточными и могут потребовать, чтобы квоты runtime, используемые cgo, безопасно вводили код без кода. – JimB

Смежные вопросы