poseidon icon indicating copy to clipboard operation
poseidon copied to clipboard

Windows compatability

Open scottctaylor12 opened this issue 2 years ago • 3 comments

There were lots of small changes that needed to happen to make poseidon work with Windows. Here's the summary:

Major Changes:

  • Dockerfile downloads gcc-mingw-w64 to enable cross compiling within the Linux docker container to windows exe RUN apt update; apt-get -y install gcc-mingw-w64
  • agent_functions/builder.py now includes a Windows build command the uses the typical go build method rather than xgo. (I couldn't get xgo to work for windows...)
elif target_os == "windows":
                command += "mkdir /build;"
                command += (
                    "GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -ldflags=\"{}\" -tags {} -o /build/poseidon-windows-amd64".format(
                        ldflags,
                        profile,
                    )
                )
  • pkg/utils/functions_windows.go Used golang.org/x/sys/windows to call RtlGetVersion() win32 API for getOS() function. This is required for the checkin process to collect necessary information.

Minor changes:

For the most part, I had to go in various command packages and add a _windows.go file with the //+build windows header and include a return error of "Not Implemented/Compatible". These cases are found in:

  • drives_windows.go
  • dyld_inject_windows.go
  • execute_memory_windows.go
  • jxa_windows.go
  • keylog/keystate/keystate_windows.go
  • keys_windows.go
  • libinject_windows.go
  • list_entitlements_windows.go
  • listtasks_windows.go
  • persist_loginitem_windows.go
  • ps_windows.go
  • ls_windows.go
  • screencapture_windows.go
  • xpc_windows.go

Some commands build, but do not work for windows. For these situations, I went into the agent_function/.py file and disabled them for windows by adding:

attributes = CommandAttributes(
    supported_os=[SupportedOS.MacOS, SupportedOS.Linux]
)

This change can be found in:

  • setenv.py
  • unsetenv.py
  • shell.py
  • ps.py

Notable Testing Success:

  • Windows default executable builds successfully and works with all profiles: websocket, http, and poseidon_tcp
  • Windows egress agent can successfully perform the link_tcp and unlink_tcp command for P2P comms (to windows and linux poseidon_tcp agents)

scottctaylor12 avatar Jun 24 '22 15:06 scottctaylor12

Also, socks proxying worked while testing from a windows agent :fire:

scottctaylor12 avatar Jun 24 '22 15:06 scottctaylor12

@its-a-feature PR is up-to-date with latest MythicAgents:dev branch changes and ready for review!

I noticed one thing about your upstream change. The way you handle the compiler flags might cause a bug within the poseidon container. The compiler flags are set using export to environment variables which is fine. However, those environment variables will still be set when the next payload is being built.

Problem scenario: darwin payload exports CC=o64-clang; and CXX=o64-clang++ when being built. When the Linux payload gets built, those environment variables might still be set and mess up the build.

https://github.com/MythicAgents/poseidon/blob/f5e9c0a74d0bc528495a47c91f362ddf01cb48d1/Payload_Type/poseidon/mythic/agent_functions/builder.py#L97-L100

Solution: Instead of exporting the compiler flags, add them before the garble/go command like: CC=mingw go build ..... rather than export CC=mingw; go build ...

scottctaylor12 avatar Jun 27 '22 17:06 scottctaylor12

How's this effort going? Is it to the point where you want me to review it or are you still looking to add major command functionality?

its-a-feature avatar Aug 25 '22 22:08 its-a-feature

Apologies for the long delay @its-a-feature! I fixed up my execute-assembly command to use direct syscalls and run in-process rather than fork & run. Whenever you have the time, could you review my PR please?

scottctaylor12 avatar Jan 05 '23 22:01 scottctaylor12

With the v3.0.0 release, how would you like me to handle this PR? I see there's a v3.0.0 branch, off of master, but I'm trying to merge into the dev branch.

scottctaylor12 avatar Mar 16 '23 18:03 scottctaylor12

Great question! If possible, it'd be nice to target the v3.0.0 release. If it's a big lift though, we can always keep going with the other branch for now (easier testing for you) and then once v3.0.0 goes live, we can port it over - the biggest change is that the v3.0.0 version is golang instead of python.

its-a-feature avatar Mar 16 '23 18:03 its-a-feature

Not a problem! I'll close this out and start a new PR with the v3.0.0😀 I like the idea of starting a fresh PR since this has been sitting a bit

scottctaylor12 avatar Mar 16 '23 18:03 scottctaylor12

You closed this one, does that mean the new one updated for v3.0.0 is coming soon? :)

its-a-feature avatar Apr 05 '23 17:04 its-a-feature

Actually I was just about to message you in Slack about it! Should I contribute to dev, v3.0.0, or yolo to main haha

scottctaylor12 avatar Apr 05 '23 17:04 scottctaylor12

Right now only v3.0.0 is actually updated for V3, so open PRs against that one for now so i can test with all the updates

its-a-feature avatar Apr 05 '23 17:04 its-a-feature

Sounds good to me 😁

scottctaylor12 avatar Apr 05 '23 17:04 scottctaylor12