commit 30ce22f496a09bebd68bf32dbc1630322cfe0a70 Author: secur30nly Date: Tue Jun 6 05:14:45 2023 -0400 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f3a72d3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 @secur30nly + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d7c3bc --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# go-self-delete +Go implementation of the self-deletion of an running executable from disk. + +> **DISCLAIMER.** All information contained in this repository is provided for educational and research purposes only. The owner is not responsible for any illegal use of included code snippets. + +## Usage + +```go +package main + +import "github.com/secur30nly/go-self-delete" + +func main() { + // some code ... + + selfdelete.SelfDeleteExe() + + // some code ... +} + +``` + +## References + +- https://github.com/LloydLabs/delete-self-poc +- https://twitter.com/jonasLyk/status/1350401461985955840 diff --git a/go-self-delete.go b/go-self-delete.go new file mode 100644 index 0000000..2868888 --- /dev/null +++ b/go-self-delete.go @@ -0,0 +1,145 @@ +/* + License: MIT Licence + + References: + - https://github.com/LloydLabs/delete-self-poc + - https://twitter.com/jonasLyk/status/1350401461985955840 +*/ + + +package selfdelete + +import ( + "fmt" + "unsafe" + "golang.org/x/sys/windows" +) + + +type FILE_RENAME_INFO struct { + Union struct { + ReplaceIfExists bool + Flags uint32 + } + RootDirectory windows.Handle + FileNameLength uint32 + FileName [1]uint16 +} + + +type FILE_DISPOSITION_INFO struct { + DeleteFile bool +} + + +func dsOpenHandle(pwPath *uint16) (windows.Handle, error) { + handle, err := windows.CreateFile( + pwPath, + windows.DELETE, + 0, + nil, + windows.OPEN_EXISTING, + windows.FILE_ATTRIBUTE_NORMAL, + 0, + ) + + if err != nil { + return 0, err + } + + return handle, nil +} + + +func dsRenameHandle(hHandle windows.Handle) error { + var fRename FILE_RENAME_INFO + DS_STREAM_RENAME, err := windows.UTF16FromString(":deadbeef") + + if err != nil { + return err + } + + lpwStream := &DS_STREAM_RENAME[0] + fRename.FileNameLength = uint32(unsafe.Sizeof(lpwStream)) + + windows.NewLazyDLL("kernel32.dll").NewProc("RtlCopyMemory").Call( + uintptr(unsafe.Pointer(&fRename.FileName[0])), + uintptr(unsafe.Pointer(lpwStream)), + unsafe.Sizeof(lpwStream), + ) + + err = windows.SetFileInformationByHandle( + hHandle, + windows.FileRenameInfo, + (*byte)(unsafe.Pointer(&fRename)), + uint32(unsafe.Sizeof(fRename) + unsafe.Sizeof(lpwStream)), + ) + + if err != nil { + return err + } + + return nil +} + + +func dsDepositeHandle(hHandle windows.Handle) error { + var fDelete FILE_DISPOSITION_INFO + fDelete.DeleteFile = true + + err := windows.SetFileInformationByHandle( + hHandle, + windows.FileDispositionInfo, + (*byte)(unsafe.Pointer(&fDelete)), + uint32(unsafe.Sizeof(fDelete)), + ) + + if err != nil { + return err + } + + return nil +} + + +func SelfDeleteExe() error { + var wcPath [windows.MAX_PATH + 1]uint16 + var hCurrent windows.Handle + + _, err := windows.GetModuleFileName(0, &wcPath[0], windows.MAX_PATH) + if err != nil { + return err + } + + hCurrent, err = dsOpenHandle(&wcPath[0]) + if err != nil || hCurrent == windows.InvalidHandle { + return err + } + + err = dsRenameHandle(hCurrent) + if err != nil { + windows.CloseHandle(hCurrent) + return err + } + + windows.CloseHandle(hCurrent) + + hCurrent, err = dsOpenHandle(&wcPath[0]) + if err != nil || hCurrent == windows.InvalidHandle { + return err + } + + err = dsDepositeHandle(hCurrent) + if err != nil { + windows.CloseHandle(hCurrent) + return err + } + + windows.CloseHandle(hCurrent) + + fmt.Println("Self deletion is successful. Program still running, hit key to continue") + str := "" + fmt.Scanln(&str) + + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..901c6d3 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/secur30nly/go-self-delete + +go 1.19 + +require golang.org/x/sys v0.8.0